diff --git a/CHANGELOG.md b/CHANGELOG.md index 63858849..62e0291c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,20 @@ 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.23](https://github.com/bipproduction/hipmi/compare/v1.2.22...v1.2.23) (2024-12-11) + +## [1.2.22](https://github.com/bipproduction/hipmi/compare/v1.2.21...v1.2.22) (2024-12-10) + +## [1.2.21](https://github.com/bipproduction/hipmi/compare/v1.2.20...v1.2.21) (2024-12-09) + +## [1.2.20](https://github.com/bipproduction/hipmi/compare/v1.2.19...v1.2.20) (2024-12-09) + +## [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) diff --git a/bun.lockb b/bun.lockb index 03d96215..88eaa6ad 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/next.config.js b/next.config.js index 5c728631..48384e99 100644 --- a/next.config.js +++ b/next.config.js @@ -1,10 +1,10 @@ /** @type {import('next').NextConfig} */ const nextConfig = { - reactStrictMode: false, - experimental: { - serverActions: true - }, - -} + reactStrictMode: false, + experimental: { + serverActions: true, + }, + output: "standalone" +}; -module.exports = nextConfig +module.exports = nextConfig; diff --git a/package.json b/package.json index 3a2f0c4d..68de6a42 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,14 @@ { "name": "hipmi", - "version": "1.2.16", + "version": "1.2.23", "private": true, "prisma": { "seed": "npx tsx prisma/seed.ts --yes" }, "scripts": { "dev": "bun --bun run next dev --experimental-https", - "build": "bun --bun run next build", + "build": "NODE_OPTIONS='--max-old-space-size=2048' bun --bun run next build", + "build:dev": "bun --bun run next build", "start": "bun --bun run next start", "lint": "bun --bun run next lint", "ver": "bunx commit-and-tag-version -- --prerelease" @@ -39,6 +40,7 @@ "@tiptap/pm": "^2.2.3", "@tiptap/react": "^2.2.3", "@tiptap/starter-kit": "^2.2.3", + "@types/bun": "^1.1.14", "@types/lodash": "^4.17.4", "@types/mapbox-gl": "^3.4.0", "@types/node": "20.4.5", @@ -47,6 +49,7 @@ "@types/uuid": "^9.0.4", "autoprefixer": "10.4.14", "bufferutil": "^4.0.8", + "bun": "^1.1.38", "dayjs": "^1.11.10", "dotenv": "^16.4.5", "echarts": "^5.4.3", diff --git a/public/aset/home/home-hipmi-new.png b/public/aset/home/home-hipmi-new.png new file mode 100644 index 00000000..968807de Binary files /dev/null and b/public/aset/home/home-hipmi-new.png differ diff --git a/src/app/api/auth/check/route.ts b/src/app/api/auth/check/route.ts index ff617b41..b51a6f31 100644 --- a/src/app/api/auth/check/route.ts +++ b/src/app/api/auth/check/route.ts @@ -1,10 +1,12 @@ import { prisma } from "@/app/lib"; import { data } from "autoprefixer"; -import { NextResponse } from "next/server"; +import { NextRequest, NextResponse } from "next/server"; +export const dynamic = "force-dynamic"; -export async function GET(request: Request) { - const { searchParams } = new URL(request.url); - const id = searchParams.get("id"); +export async function GET(request: NextRequest) { + const id = request.nextUrl.searchParams.get("id"); + // const { searchParams } = new URL(request.url); + // const id = searchParams.get("id"); try { const data = await prisma.kodeOtp.findFirst({ @@ -12,10 +14,11 @@ export async function GET(request: Request) { id: id as string, }, }); - return new Response(JSON.stringify({ data }), { status: 200 }); + + return NextResponse.json(data, { status: 200 }); } catch (error) { console.log(error); } - return new Response(JSON.stringify({ data: null }), { status: 404 }); + return NextResponse.json(null, { status: 500 }); } diff --git a/src/app/api/auth/login/route.ts b/src/app/api/auth/login/route.ts index 3aac1607..97c36643 100644 --- a/src/app/api/auth/login/route.ts +++ b/src/app/api/auth/login/route.ts @@ -18,14 +18,11 @@ export async function POST(req: Request) { const sendWa = await res.json(); if (sendWa.status !== "success") - return new Response( - JSON.stringify({ - success: false, - message: "Nomor Whatsapp Tidak Aktif", - }), + return NextResponse.json( + { success: false, message: "Nomor Whatsapp Tidak Aktif" }, { status: 400 } ); - + const createOtpId = await prisma.kodeOtp.create({ data: { nomor: nomor, @@ -34,32 +31,30 @@ export async function POST(req: Request) { }); if (!createOtpId) - return new Response( - JSON.stringify({ - success: false, - message: "Gagal Membuat Kode OTP", - }), + return NextResponse.json( + { success: false, message: "Gagal Membuat Kode OTP" }, { status: 400 } ); - return new Response( - JSON.stringify({ + return NextResponse.json( + { 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 !!", - }), + + return NextResponse.json( + { success: false, message: "Server Whatsapp Error !! " }, { status: 500 } ); } } - return NextResponse.json({ success: false }); + return NextResponse.json( + { success: false, message: "Method Not Allowed" }, + { status: 405 } + ); } diff --git a/src/app/api/auth/logout/route.ts b/src/app/api/auth/logout/route.ts index 9a5356ff..44a4a2ab 100644 --- a/src/app/api/auth/logout/route.ts +++ b/src/app/api/auth/logout/route.ts @@ -1,28 +1,20 @@ -import { prisma } from "@/app/lib"; import { cookies } from "next/headers"; -export async function GET(request: Request) { - const { searchParams } = new URL(request.url); - const id = searchParams.get("id"); +import { NextRequest, NextResponse } from "next/server"; +export const dynamic = "force-dynamic"; +export async function GET(request: NextRequest) { + const id = request.nextUrl.searchParams.get("id"); + // const { searchParams } = new URL(request.url); + // const id = searchParams.get("id"); - const delToken = await prisma.userSession.delete({ - where: { - userId: id as string, - }, - }); + // const delToken = await prisma.userSession.delete({ + // where: { + // userId: id as string, + // }, + // }); const del = cookies().delete(process.env.NEXT_PUBLIC_BASE_SESSION_KEY!); - return new Response(JSON.stringify({ success: true, message: "Logout Berhasil" }), {status: 200}); + return NextResponse.json( + { 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" }); -// } diff --git a/src/app/api/auth/register/route.ts b/src/app/api/auth/register/route.ts index 19366387..c307d724 100644 --- a/src/app/api/auth/register/route.ts +++ b/src/app/api/auth/register/route.ts @@ -1,5 +1,6 @@ import { sessionCreate } from "@/app/auth/_lib/session_create"; import prisma from "@/app/lib/prisma"; +import { NextResponse } from "next/server"; export async function POST(req: Request) { if (req.method === "POST") { @@ -11,60 +12,38 @@ export async function POST(req: Request) { }, }); - if (cekUsername) - return new Response( - JSON.stringify({ - success: false, - message: "Username sudah digunakan", - }), - { status: 400 } - ); - - const createUser = await prisma.user.create({ - data: { - username: data.username, - nomor: data.nomor, - active: true, - }, - }); - - const token = await sessionCreate({ - sessionKey: process.env.NEXT_PUBLIC_BASE_SESSION_KEY!, - encodedKey: process.env.NEXT_PUBLIC_BASE_TOKEN_KEY!, - user: createUser as any, - }); - try { - const createUserSession = await prisma.userSession.create({ + if (cekUsername) + return NextResponse.json( + { success: false, message: "Username sudah digunakan" }, + { status: 400 } + ); + + const createUser = await prisma.user.create({ data: { - token: token as string, - userId: createUser.id, + username: data.username, + nomor: data.nomor, + active: true, }, }); - if (!createUserSession) - return new Response( - JSON.stringify({ - success: false, - message: "Gagal Membuat Session", - }), - { status: 400 } - ); + const token = await sessionCreate({ + sessionKey: process.env.NEXT_PUBLIC_BASE_SESSION_KEY!, + encodedKey: process.env.NEXT_PUBLIC_BASE_TOKEN_KEY!, + user: createUser as any, + }); + + return NextResponse.json( + { success: true, message: "Berhasil Login", data: createUser }, + { status: 200 } + ); } catch (error) { console.log(error); } - - return new Response( - JSON.stringify({ - success: true, - message: "Berhasil Login", - }), - - { status: 200 } - ); } - return new Response( - JSON.stringify({ success: false, message: "Method Not Allowed" }), + + return NextResponse.json( + { success: false, message: "Method Not Allowed" }, { status: 405 } ); } diff --git a/src/app/api/auth/resend/route.ts b/src/app/api/auth/resend/route.ts index 3aac1607..3e02b0ef 100644 --- a/src/app/api/auth/resend/route.ts +++ b/src/app/api/auth/resend/route.ts @@ -18,11 +18,11 @@ export async function POST(req: Request) { const sendWa = await res.json(); if (sendWa.status !== "success") - return new Response( - JSON.stringify({ + return NextResponse.json( + { success: false, message: "Nomor Whatsapp Tidak Aktif", - }), + }, { status: 400 } ); @@ -34,32 +34,36 @@ export async function POST(req: Request) { }); if (!createOtpId) - return new Response( - JSON.stringify({ + return NextResponse.json( + { success: false, message: "Gagal Membuat Kode OTP", - }), + }, { status: 400 } ); - return new Response( - JSON.stringify({ + return NextResponse.json( + { success: true, message: "Kode Verifikasi Dikirim", kodeId: createOtpId.id, - }), + }, { status: 200 } ); } catch (error) { console.log(error); - return new Response( - JSON.stringify({ + + return NextResponse.json( + { success: false, message: "Server Whatsapp Error !!", - }), + }, { status: 500 } ); } } - return NextResponse.json({ success: false }); + return NextResponse.json( + { success: false, message: "Method Not Allowed" }, + { status: 405 } + ); } diff --git a/src/app/api/auth/validasi/route.ts b/src/app/api/auth/validasi/route.ts index f865cc07..69c64a8c 100644 --- a/src/app/api/auth/validasi/route.ts +++ b/src/app/api/auth/validasi/route.ts @@ -1,107 +1,52 @@ import { sessionCreate } from "@/app/auth/_lib/session_create"; import prisma from "@/app/lib/prisma"; -import { ServerEnv } from "@/app/lib/server_env"; -import { sealData } from "iron-session"; -import { revalidatePath } from "next/cache"; -import { cookies } from "next/headers"; import { NextResponse } from "next/server"; export async function POST(req: Request) { if (req.method === "POST") { const { nomor } = await req.json(); - const dataUser = await prisma.user.findUnique({ - where: { - nomor: nomor, - }, - select: { - id: true, - nomor: true, - username: true, - active: true, - masterUserRoleId: true, - }, - }); - - - if (dataUser === null) - return new Response( - JSON.stringify({ success: false, message: "Nomor Belum Terdaftar" }), - { status: 404 } - ); - - const token = await sessionCreate({ - sessionKey: process.env.NEXT_PUBLIC_BASE_SESSION_KEY!, - encodedKey: process.env.NEXT_PUBLIC_BASE_TOKEN_KEY!, - 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, - }, - }); - } - try { - const createUserSession = await prisma.userSession.create({ - data: { - token: token as string, - userId: dataUser.id, + const dataUser = await prisma.user.findUnique({ + where: { + nomor: nomor, + }, + select: { + id: true, + nomor: true, + username: true, + active: true, + masterUserRoleId: true, }, }); - if (!createUserSession) - return new Response( - JSON.stringify({ success: false, message: "Gagal Membuat Session" }), - { status: 400 } + if (dataUser == null) + return NextResponse.json( + { success: false, message: "Nomor Belum Terdaftar" }, + { status: 404 } ); + + const token = await sessionCreate({ + sessionKey: process.env.NEXT_PUBLIC_BASE_SESSION_KEY!, + encodedKey: process.env.NEXT_PUBLIC_BASE_TOKEN_KEY!, + user: dataUser as any, + }); + + return NextResponse.json( + { + success: true, + message: "Berhasil Login", + roleId: dataUser.masterUserRoleId, + active: dataUser.active, + }, + { status: 200 } + ); } 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 new Response( - JSON.stringify({ success: false, message: "Method Not Allowed" }), + return NextResponse.json( + { success: false, message: "Method Not Allowed" }, { status: 405 } ); } diff --git a/src/app/api/check-cookies/route.ts b/src/app/api/check-cookies/route.ts index b02fce67..ebc446be 100644 --- a/src/app/api/check-cookies/route.ts +++ b/src/app/api/check-cookies/route.ts @@ -8,7 +8,7 @@ export async function GET(req: Request) { if (!c || !c?.value || _.isEmpty(c?.value) || _.isUndefined(c?.value)) { return NextResponse.json({ success: false }); - // return new Response(JSON.stringify({ success: false })); + } return NextResponse.json({ success: true }); } diff --git a/src/app/api/event/check-kehadiran/route.ts b/src/app/api/event/check-kehadiran/route.ts new file mode 100644 index 00000000..083f6e05 --- /dev/null +++ b/src/app/api/event/check-kehadiran/route.ts @@ -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 }); +} diff --git a/src/app/api/event/check-peserta/route.ts b/src/app/api/event/check-peserta/route.ts new file mode 100644 index 00000000..49b863e2 --- /dev/null +++ b/src/app/api/event/check-peserta/route.ts @@ -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 }); +} diff --git a/src/app/api/event/get-all/route.ts b/src/app/api/event/get-all/route.ts new file mode 100644 index 00000000..33e9c89a --- /dev/null +++ b/src/app/api/event/get-all/route.ts @@ -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 }); +} diff --git a/src/app/api/event/get-one-by-id/route.ts b/src/app/api/event/get-one-by-id/route.ts new file mode 100644 index 00000000..7ab66fac --- /dev/null +++ b/src/app/api/event/get-one-by-id/route.ts @@ -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 } + ); +} diff --git a/src/app/api/event/list-peserta/route.ts b/src/app/api/event/list-peserta/route.ts new file mode 100644 index 00000000..6acbbc08 --- /dev/null +++ b/src/app/api/event/list-peserta/route.ts @@ -0,0 +1,17 @@ +import { event_newGetListPesertaById } from "@/app_modules/event/fun"; +import { Event_getListPesertaById } from "@/app_modules/event/fun/get/get_list_peserta_by_id"; +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 }); +} diff --git a/src/app/api/new/forum/route.ts b/src/app/api/new/forum/route.ts new file mode 100644 index 00000000..84d3523a --- /dev/null +++ b/src/app/api/new/forum/route.ts @@ -0,0 +1,67 @@ +import { prisma } from "@/app/lib" +import { NextResponse } from "next/server"; +export const dynamic = "force-dynamic"; + +// GET ALL DATA PORTOFOLIO BY PROFILE ID +export async function GET(request: Request) { + try { + const { searchParams } = new URL(request.url) + const page = searchParams.get("page") + const search = searchParams.get("search") + const dataSkip = Number(page) * 5 - 5; + + const data = await prisma.forum_Posting.findMany({ + take: 5, + skip: dataSkip, + orderBy: { + createdAt: "desc", + }, + where: { + isActive: true, + diskusi: { + mode: "insensitive", + contains: (search == undefined || search == "null") ? "" : search, + }, + }, + select: { + id: true, + diskusi: true, + createdAt: true, + isActive: true, + authorId: true, + Author: { + select: { + id: true, + username: true, + Profile: { + select: { + id: true, + name: true, + imageId: true, + }, + }, + }, + }, + Forum_Komentar: { + where: { + isActive: true, + }, + }, + ForumMaster_StatusPosting: { + select: { + id: true, + status: true, + }, + }, + forumMaster_StatusPostingId: true, + }, + }); + + return NextResponse.json({ success: true, message: "Berhasil mendapatkan data", data }, { 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 }); + } +} \ No newline at end of file diff --git a/src/app/api/new/home/route.ts b/src/app/api/new/home/route.ts new file mode 100644 index 00000000..bdb110d8 --- /dev/null +++ b/src/app/api/new/home/route.ts @@ -0,0 +1,69 @@ +import { prisma } from "@/app/lib"; +import { funGetUserIdByToken } from "@/app_modules/_global/fun/get"; +import { NextResponse } from "next/server"; +export const dynamic = "force-dynamic"; + + +// 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 }); + } +} \ No newline at end of file diff --git a/src/app/api/new/map/[id]/route.ts b/src/app/api/new/map/[id]/route.ts new file mode 100644 index 00000000..8047965d --- /dev/null +++ b/src/app/api/new/map/[id]/route.ts @@ -0,0 +1,76 @@ +import { prisma } from "@/app/lib"; +import { NextResponse } from "next/server"; +export const dynamic = "force-dynamic"; + +export async function GET(request: Request, context: { params: { id: string } }) { + try { + const { id } = context.params + const data = await prisma.businessMaps.findUnique({ + where: { + id: id, + }, + select: { + namePin: true, + latitude: true, + longitude: true, + pinId: true, + imageId: true, + Author: { + select: { + Profile: { + select: { + id: true, + name: true, + imageId: true, + } + } + } + }, + Portofolio: { + select: { + id: true, + alamatKantor: true, + tlpn: true, + deskripsi: true, + namaBisnis: true, + MasterBidangBisnis: { + select: { + name: true, + }, + }, + }, + }, + } + }); + + const dataLokasi = { + namePin: data?.namePin, + latitude: data?.latitude, + longitude: data?.longitude, + pinId: data?.pinId, + imageId: data?.imageId, + } + + const dataAuthor = { + id: data?.Author?.Profile?.id, + name: data?.Author?.Profile?.name, + imageId: data?.Author?.Profile?.imageId, + } + + const dataBisnis = { + id: data?.Portofolio?.id, + alamatKantor: data?.Portofolio?.alamatKantor, + tlpn: data?.Portofolio?.tlpn, + deskripsi: data?.Portofolio?.deskripsi, + namaBisnis: data?.Portofolio?.namaBisnis, + bidangBisnis: data?.Portofolio?.MasterBidangBisnis?.name, + } + + return NextResponse.json({ success: true, message: "Berhasil mendapatkan data", dataLokasi, dataAuthor, dataBisnis }, { 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 }); + } +} \ No newline at end of file diff --git a/src/app/api/new/map/route.ts b/src/app/api/new/map/route.ts new file mode 100644 index 00000000..7a07e5ec --- /dev/null +++ b/src/app/api/new/map/route.ts @@ -0,0 +1,40 @@ +import { prisma } from "@/app/lib"; +import _ from "lodash"; +import { NextResponse } from "next/server"; +export const dynamic = "force-dynamic"; + + +// GET ALL DATA MAP +export async function GET(request: Request) { + try { + const data = await prisma.businessMaps.findMany({ + where: { + isActive: true, + }, + select: { + id: true, + namePin: true, + latitude: true, + longitude: true, + pinId: true, + Portofolio: { + select: { + logoId: true, + } + } + } + }); + + const dataFix = data.map((v: any) => ({ + ..._.omit(v, ["Portofolio"]), + logoId: v.Portofolio.logoId + })) + + 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 }); + } +} \ No newline at end of file diff --git a/src/app/api/new/portofolio/[id]/route.ts b/src/app/api/new/portofolio/[id]/route.ts new file mode 100644 index 00000000..747cabd0 --- /dev/null +++ b/src/app/api/new/portofolio/[id]/route.ts @@ -0,0 +1,173 @@ +import { prisma } from "@/app/lib"; +import { NextResponse } from "next/server"; +import fs from "fs"; +export const dynamic = "force-dynamic"; + + + +// GET ONE DATA PORTOFOLIO BY ID PORTOFOLIO +export async function GET(request: Request, context: { params: { id: string } }) { + try { + let dataFix + const { id } = context.params; + const { searchParams } = new URL(request.url); + const kategori = searchParams.get('cat'); + + if (kategori == "bisnis") { + const data = await prisma.portofolio.findUnique({ + where: { + id: id, + }, + select: { + id_Portofolio: true, + namaBisnis: true, + alamatKantor: true, + tlpn: true, + deskripsi: true, + logoId: true, + MasterBidangBisnis: { + select: { + name: true + } + }, + Profile: { + select: { + userId: true + } + } + } + }); + + dataFix = { + id_Portofolio: data?.id_Portofolio, + namaBisnis: data?.namaBisnis, + alamatKantor: data?.alamatKantor, + tlpn: data?.tlpn, + deskripsi: data?.deskripsi, + logoId: data?.logoId, + bidangBisnis: data?.MasterBidangBisnis?.name, + authorId: data?.Profile?.userId + } + + } else if (kategori == "lokasi") { + const data = await prisma.portofolio.findUnique({ + where: { + id: id, + }, + select: { + logoId: true, + BusinessMaps: { + select: { + id: true, + namePin: true, + latitude: true, + longitude: true, + imageId: true, + pinId: true + } + } + } + }); + + dataFix = { + mapId: data?.BusinessMaps?.id, + logoId: data?.logoId, + namePin: data?.BusinessMaps?.namePin, + latitude: data?.BusinessMaps?.latitude, + longitude: data?.BusinessMaps?.longitude, + imageId: data?.BusinessMaps?.imageId, + pinId: data?.BusinessMaps?.pinId + } + + } else if (kategori == "sosmed") { + const data = await prisma.portofolio.findUnique({ + where: { + id: id, + }, + select: { + Portofolio_MediaSosial: { + select: { + facebook: true, + twitter: true, + instagram: true, + tiktok: true, + youtube: true + } + } + } + }); + + dataFix = { + facebook: data?.Portofolio_MediaSosial?.facebook, + twitter: data?.Portofolio_MediaSosial?.twitter, + instagram: data?.Portofolio_MediaSosial?.instagram, + tiktok: data?.Portofolio_MediaSosial?.tiktok, + youtube: data?.Portofolio_MediaSosial?.youtube + } + } + + 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 (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + +// DELETE ONE DATA PORTOFOLIO +export async function DELETE(request: Request, context: { params: { id: string } }) { + try { + const { id } = context.params + + const data = await prisma.portofolio.findUnique({ + where: { + id: id + } + }) + + const findLogo = await prisma.images.findFirst({ + where: { + id: String(data?.logoId), + }, + select: { + id: true, + url: true, + }, + }); + + if (findLogo) { + fs.unlinkSync(`./public/portofolio/logo/${findLogo.url}`) + const deleteLogo = await prisma.images.delete({ + where: { + id: String(findLogo?.id), + }, + }); + } + + + + const deletePortoMedsos = await prisma.portofolio_MediaSosial.delete({ + where: { + portofolioId: id, + }, + }); + + const deleteMap = await prisma.businessMaps.delete({ + where: { + portofolioId: id + } + }) + + const deletePortofolio = await prisma.portofolio.delete({ + where: { + id: id, + }, + }); + + return NextResponse.json({ success: true, message: "Berhasil menghapus data" }, { status: 200 }); + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal menghapus data, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} \ No newline at end of file diff --git a/src/app/api/new/portofolio/route.ts b/src/app/api/new/portofolio/route.ts new file mode 100644 index 00000000..fbf91221 --- /dev/null +++ b/src/app/api/new/portofolio/route.ts @@ -0,0 +1,60 @@ +import { prisma } from "@/app/lib"; +import { NextResponse } from "next/server"; +export const dynamic = "force-dynamic"; + + +// 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 }); + } +} \ No newline at end of file diff --git a/src/app/api/new/user/route.ts b/src/app/api/new/user/route.ts new file mode 100644 index 00000000..8f710f53 --- /dev/null +++ b/src/app/api/new/user/route.ts @@ -0,0 +1,59 @@ +import { prisma } from "@/app/lib"; +import { NextResponse } from "next/server"; +export const dynamic = "force-dynamic"; + + +// 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 }); + } +} \ No newline at end of file diff --git a/src/app/api/origin-url/route.ts b/src/app/api/origin-url/route.ts index 186624ae..4cbd28d7 100644 --- a/src/app/api/origin-url/route.ts +++ b/src/app/api/origin-url/route.ts @@ -1,6 +1,7 @@ import { headers } from "next/headers"; +import { NextResponse } from "next/server"; export async function GET(req: Request) { const origin = new URL(req.url).origin; - return new Response(JSON.stringify({ success: true, origin })); + return NextResponse.json({ success: true, origin }); } diff --git a/src/app/api/test-scroll/route.ts b/src/app/api/test-scroll/route.ts index c722ba33..f2fdc9ea 100644 --- a/src/app/api/test-scroll/route.ts +++ b/src/app/api/test-scroll/route.ts @@ -1,8 +1,11 @@ import prisma from "@/app/lib/prisma"; +import { NextResponse } from "next/server"; export async function GET(req: Request) { const page = new URL(req.url).searchParams.get("page"); - if (!page) return new Response("page require", { status: 400 }); + if (!page) + return NextResponse.json({ message: "Page not found" }, { status: 400 }); + const res = await prisma.projectCollaboration_Message.findMany({ take: 5, skip: +page * 5 - 5, diff --git a/src/app/api/upload/route.ts b/src/app/api/upload/route.ts new file mode 100644 index 00000000..00e2b69c --- /dev/null +++ b/src/app/api/upload/route.ts @@ -0,0 +1,51 @@ +import { NextResponse } from "next/server"; +export async function POST(request: Request) { + const WS_APIKEY = process.env.WS_APIKEY; + console.log(WS_APIKEY); + + try { + const formData = await request.formData(); + + const res = await fetch("https://wibu-storage.wibudev.com/api/upload", { + method: "POST", + body: formData, + headers: { + Authorization: `Bearer ${process.env.WS_APIKEY}`, + }, + }); + + // if (res.ok) { + // console.log("Berhasil"); + // const hasil = await res.json(); + // return { success: true, data: hasil.data }; + // } else { + // const errorText = await res.text(); + // return { success: false, data: {} }; + // } + } catch (error) { + console.log(error); + } + + // try { + // const res = await fetch("https://wibu-storage.wibudev.com/api/upload", { + // method: "POST", + // body: formData, + // headers: { + // Authorization: `Bearer ${process.env.WS_APIKEY}`, + // }, + // }); + + // if (res.ok) { + // const hasil = await res.json(); + // return { success: true, data: hasil.data }; + // } else { + // const errorText = await res.text(); + // return { success: false, data: {} }; + // } + // } catch (error) { + // console.error("Upload error:", error); + // return { success: false, data: {} }; + // } + + return NextResponse.json({ success: true }); +} diff --git a/src/app/api/user/route.ts b/src/app/api/user/route.ts new file mode 100644 index 00000000..33b4d093 --- /dev/null +++ b/src/app/api/user/route.ts @@ -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 | null> { + try { + const enc = new TextEncoder().encode(encodedKey); + const { payload } = await jwtVerify(token, enc, { + algorithms: ["HS256"], + }); + return (payload.user as Record) || null; + } catch (error) { + console.error("Gagal verifikasi session", error); + return null; + } +} diff --git a/src/app/api/validasi/route.ts b/src/app/api/validasi/route.ts index 65467cdb..4562aa95 100644 --- a/src/app/api/validasi/route.ts +++ b/src/app/api/validasi/route.ts @@ -1,7 +1,9 @@ +import { NextResponse } from "next/server"; + 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 })); + if (!token) return NextResponse.json({ success: false }, { status: 401 }); + return NextResponse.json({ success: true }); + } diff --git a/src/app/api/zz-makuro/route.ts b/src/app/api/zz-makuro/route.ts index df7b0d72..da2e4655 100644 --- a/src/app/api/zz-makuro/route.ts +++ b/src/app/api/zz-makuro/route.ts @@ -1,7 +1,8 @@ import { headers } from "next/headers"; +import { NextResponse } from "next/server"; export async function GET( req: Request) { const origin = new URL(req.url).origin; - return new Response(JSON.stringify({ success: true, origin })); + return NextResponse.json({ success: true, origin }); } diff --git a/src/app/auth/api/login/route.ts b/src/app/auth/api/login/route.ts index 370b5bad..eb59a9f0 100644 --- a/src/app/auth/api/login/route.ts +++ b/src/app/auth/api/login/route.ts @@ -1,5 +1,6 @@ import { prisma } from "@/app/lib"; import { sessionCreate } from "../../_lib/session_create"; +import { NextResponse } from "next/server"; export async function POST(req: Request) { const user = await prisma.user.findUnique({ @@ -12,10 +13,7 @@ export async function POST(req: Request) { }, }); - if (!user) - return new Response( - JSON.stringify({ success: false, message: "User not found" }), {status: 404} - ); + if (!user) return NextResponse.json({ success: false }, { status: 404 }); const token = await sessionCreate({ sessionKey: process.env.NEXT_PUBLIC_BASE_SESSION_KEY!, @@ -23,5 +21,5 @@ export async function POST(req: Request) { user: user as any, }); - return new Response(JSON.stringify({ success: true, token })); + return NextResponse.json({ success: true, token }); } diff --git a/src/app/auth/api/logout/route.ts b/src/app/auth/api/logout/route.ts index af733975..25aab3db 100644 --- a/src/app/auth/api/logout/route.ts +++ b/src/app/auth/api/logout/route.ts @@ -1,5 +1,8 @@ import { cookies } from "next/headers"; +import { NextResponse } from "next/server"; + export async function GET() { const del = cookies().delete(process.env.NEXT_PUBLIC_BASE_SESSION_KEY!); - return new Response(JSON.stringify({ success: true })); + + return NextResponse.json({ success: true, message: "Logout Berhasil" }); } diff --git a/src/app/dev/(user)/home/page.tsx b/src/app/dev/(user)/home/page.tsx index 86f17573..4bd78e32 100644 --- a/src/app/dev/(user)/home/page.tsx +++ b/src/app/dev/(user)/home/page.tsx @@ -1,32 +1,21 @@ -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 { 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 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.main_admin); return ( <> - + /> */} + ); } diff --git a/src/app/dev/event/create/page.tsx b/src/app/dev/event/create/page.tsx index 5363ccb1..b731e460 100644 --- a/src/app/dev/event/create/page.tsx +++ b/src/app/dev/event/create/page.tsx @@ -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_getMasterTipeAcara } from "@/app_modules/event/fun/master/get_tipe_acara"; export default async function Page() { - const userLoginId = await funGetUserIdByToken(); + const userLoginId = await newFunGetUserId(); const listTipeAcara = await Event_getMasterTipeAcara(); return ( diff --git a/src/app/dev/event/detail/kontribusi/[id]/page.tsx b/src/app/dev/event/detail/kontribusi/[id]/page.tsx index 5678dc7a..508e14ae 100644 --- a/src/app/dev/event/detail/kontribusi/[id]/page.tsx +++ b/src/app/dev/event/detail/kontribusi/[id]/page.tsx @@ -11,8 +11,7 @@ export default async function Page({ params }: { params: { id: string } }) { return ( <> diff --git a/src/app/dev/event/detail/main/[id]/page.tsx b/src/app/dev/event/detail/main/[id]/page.tsx index 9f42a181..11850c4e 100644 --- a/src/app/dev/event/detail/main/[id]/page.tsx +++ b/src/app/dev/event/detail/main/[id]/page.tsx @@ -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_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 } }) { let eventId = params.id; - const userLoginId : any= await funGetUserIdByToken(); - - const dataEvent = await event_getOneById(eventId); - const listPeserta = await Event_getListPesertaById(eventId); - const isJoin = await Event_CekUserJoinById(eventId, userLoginId); + const userLoginId = await newFunGetUserId(); const totalPeserta = await Event_countTotalPesertaById(eventId); return ( <> ); diff --git a/src/app/dev/event/detail/publish/[id]/page.tsx b/src/app/dev/event/detail/publish/[id]/page.tsx index 4388c255..1123ede9 100644 --- a/src/app/dev/event/detail/publish/[id]/page.tsx +++ b/src/app/dev/event/detail/publish/[id]/page.tsx @@ -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 } }) { let eventId = params.id; const dataEvent = await event_getOneById(eventId); - const listPeserta = await Event_getListPesertaById(eventId); const totalPeserta = await Event_countTotalPesertaById(eventId); return ( ); } diff --git a/src/app/dev/event/detail/riwayat/[id]/page.tsx b/src/app/dev/event/detail/riwayat/[id]/page.tsx index 2f506396..a6715a97 100644 --- a/src/app/dev/event/detail/riwayat/[id]/page.tsx +++ b/src/app/dev/event/detail/riwayat/[id]/page.tsx @@ -1,21 +1,15 @@ - import { Event_DetailRiwayat } from "@/app_modules/event"; 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 } }) { let eventId = params.id; - const dataEvent = await event_getOneById(eventId); - const listPeserta = await Event_getListPesertaById(eventId); const totalPeserta = await Event_countTotalPesertaById(eventId); return ( <> ); diff --git a/src/app/dev/event/konfirmasi/[id]/page.tsx b/src/app/dev/event/konfirmasi/[id]/page.tsx index a7de2574..bb2200b5 100644 --- a/src/app/dev/event/konfirmasi/[id]/page.tsx +++ b/src/app/dev/event/konfirmasi/[id]/page.tsx @@ -1,40 +1,17 @@ -import { funGetUserIdByToken } from "@/app_modules/_global/fun/get"; +import { newFunGetUserId } from "@/app/lib/new_fun_user_id"; import Ui_Konfirmasi from "@/app_modules/event/_ui/konfirmasi"; -import { - event_funCheckKehadiran, - event_funCheckPesertaByUserId, -} from "@/app_modules/event/fun"; -import { event_getOneById } from "@/app_modules/event/fun/get/get_one_by_id"; -import { redirect } from "next/navigation"; -export default async function Page({ params }: { params: { id: string } }) { - const eventId = params.id; - const userLoginId = await funGetUserIdByToken(); - const dataEvent = await event_getOneById(eventId); - - const checkPeserta = await event_funCheckPesertaByUserId({ - eventId: eventId, - userId: userLoginId as string, - }); - - - - if (dataEvent?.isArsip) - return redirect(`/dev/event/detail/riwayat/${dataEvent.id}`); - - if (checkPeserta == false) - return redirect(`/dev/event/detail/main/${eventId}`); - - // if (checkKehadiran) { - // return redirect(`/dev/event/main/beranda`); - // } +export default async function Page({ + params, +}: { + params: Promise<{ id: string }>; +}) { + const eventId = (await params).id; + const userLoginId = await newFunGetUserId(); return ( <> - + ); } diff --git a/src/app/dev/event/main/beranda/page.tsx b/src/app/dev/event/main/beranda/page.tsx index e5201847..5bde2a88 100644 --- a/src/app/dev/event/main/beranda/page.tsx +++ b/src/app/dev/event/main/beranda/page.tsx @@ -1,12 +1,10 @@ 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() { - const dataEvent = await event_getListAllPublish({ page: 1 }); return ( <> - + ); } diff --git a/src/app/dev/katalog/[id]/layout.tsx b/src/app/dev/katalog/[id]/layout.tsx index bd874c57..98b718f6 100644 --- a/src/app/dev/katalog/[id]/layout.tsx +++ b/src/app/dev/katalog/[id]/layout.tsx @@ -1,31 +1,24 @@ -import { funGetUserIdByToken } from "@/app_modules/_global/fun/get"; -import { KatalogLayout } from "@/app_modules/katalog/main"; -import { Profile_getOneProfileAndUserById } from "@/app_modules/katalog/profile/fun/get/get_one_user_profile"; +import { LayoutKatalogNew } from "@/app_modules/katalog/main"; -export default async function Layout({ - children, - params, -}: { - children: any; - params: { id: string }; -}) { - const profileId = params.id; - const dataProfile = await Profile_getOneProfileAndUserById(profileId); - const authorId = dataProfile?.userId; +export default async function Layout({ children, params, }: { children: any; params: { id: string } }) { + // const profileId = params.id; + // const dataProfile = await Profile_getOneProfileAndUserById(profileId); + // const authorId = dataProfile?.userId; - const userLoginId = await funGetUserIdByToken(); - const userRoleId = dataProfile?.User?.masterUserRoleId; + // const userLoginId = await funGetUserIdByToken(); + // const userRoleId = dataProfile?.User?.masterUserRoleId; return ( <> - {children} - + */} + {children} ); } diff --git a/src/app/dev/katalog/[id]/page.tsx b/src/app/dev/katalog/[id]/page.tsx index 24cccdab..98ab33e3 100644 --- a/src/app/dev/katalog/[id]/page.tsx +++ b/src/app/dev/katalog/[id]/page.tsx @@ -1,22 +1,21 @@ -import { funGetUserIdByToken } from "@/app_modules/_global/fun/get"; -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"; +import { ViewKatalogNew } from "@/app_modules/katalog"; export default async function Page({ params }: { params: { id: string } }) { - let profileId = params.id; - const userLoginId = await funGetUserIdByToken(); + // let profileId = params.id; + // const userLoginId = await funGetUserIdByToken(); - const listPorto = await funGetListPortofolio(profileId); - const dataProfile = await Profile_getOneProfileAndUserById(profileId); + // const listPorto = await funGetListPortofolio(profileId); + // const dataProfile = await Profile_getOneProfileAndUserById(profileId); return ( <> - + /> */} + + ); } diff --git a/src/app/dev/layout.tsx b/src/app/dev/layout.tsx index 4c91bd10..49f4a4c7 100644 --- a/src/app/dev/layout.tsx +++ b/src/app/dev/layout.tsx @@ -1,42 +1,21 @@ -import { funGetUserIdByToken } from "@/app_modules/_global/fun/get"; -import { funGlobal_getUserById } from "@/app_modules/_global/fun/get/fun_get_user_by_id"; -import { redirect } from "next/navigation"; import { RealtimeProvider } from "../lib"; +import { newFunGetUserId } from "../lib/new_fun_user_id"; import { ServerEnv } from "../lib/server_env"; -import { RouterAdminDashboard } from "../lib/router_hipmi/router_admin"; -import { funGlobal_checkActivationUseById } from "@/app_modules/_global/fun/get/fun_check_activation_use_by_id"; export default async function Layout({ children, }: { children: React.ReactNode; }) { - const userLoginId = await funGetUserIdByToken(); - // const dataUser = await funGlobal_getUserById({ - // userId: userLoginId as string, - // }); - - // if (dataUser?.masterUserRoleId != "1") return redirect("/dev/home"); - - // const activationUser = await funGlobal_checkActivationUseById({ - // userId: userLoginId as string, - // }); - - // if (activationUser == false) return redirect("/waiting-room"); - return ( <> {children} - {/* - {children} - */} ); } diff --git a/src/app/dev/map/main/page.tsx b/src/app/dev/map/main/page.tsx index 8b1b6fd6..f7867fa4 100644 --- a/src/app/dev/map/main/page.tsx +++ b/src/app/dev/map/main/page.tsx @@ -1,13 +1,13 @@ -import { map_funGetAllMap } from "@/app_modules/map/fun/get/fun_get_all_map"; -import { Map_View } from "@/app_modules/map/view"; +import { Map_ViewNew } from "@/app_modules/map/view/main_view_new"; const mapboxToken = process.env.MAPBOX_TOKEN!; export default async function Page() { - const dataMap = await map_funGetAllMap(); + // const dataMap = await map_funGetAllMap(); return ( <> - + {/* */} + ); } diff --git a/src/app/dev/portofolio/daftar-portofolio/[id]/page.tsx b/src/app/dev/portofolio/daftar-portofolio/[id]/page.tsx index 45a30f23..2252757b 100644 --- a/src/app/dev/portofolio/daftar-portofolio/[id]/page.tsx +++ b/src/app/dev/portofolio/daftar-portofolio/[id]/page.tsx @@ -1,17 +1,17 @@ -import { Portofolio_ViewListDetail } from "@/app_modules/katalog/portofolio"; -import { portofolio_funGetAllDaftarByid } from "@/app_modules/katalog/portofolio/fun/get/get_all_portofolio"; +import { ListDetailPortofolioNew } from "@/app_modules/katalog/portofolio"; export default async function Page({ params }: { params: { id: string } }) { - const profileId = params.id; - const dataPortofolio = await portofolio_funGetAllDaftarByid({ - profileId, - page: 1, - }); + // const profileId = params.id; + // const dataPortofolio = await portofolio_funGetAllDaftarByid({ + // profileId, + // page: 1, + // }); return ( <> - + {/* */} + ); } diff --git a/src/app/dev/portofolio/main/[id]/layout.tsx b/src/app/dev/portofolio/main/[id]/layout.tsx index 42f4bc01..1be53c84 100644 --- a/src/app/dev/portofolio/main/[id]/layout.tsx +++ b/src/app/dev/portofolio/main/[id]/layout.tsx @@ -1,27 +1,20 @@ -import { funGetUserIdByToken } from "@/app_modules/_global/fun/get"; -import { PortofolioLayout } from "@/app_modules/katalog/portofolio"; -import { portofolio_getOneById } from "@/app_modules/katalog/portofolio/fun/get/get_one_portofolio"; +import { PortofolioLayoutNew } from "@/app_modules/katalog/portofolio"; -export default async function Layout({ - children, - params, -}: { - children: any; - params: { id: string }; -}) { - let portoId = params.id; - const getPorto = await portofolio_getOneById(portoId); - const userLoginId = await funGetUserIdByToken(); +export default async function Layout({ children, params, }: { children: any; params: { id: string }; }) { + // let portoId = params.id; + // const getPorto = await portofolio_getOneById(portoId); + // const userLoginId = await funGetUserIdByToken(); return ( <> - {children} - + */} + {children} ); } diff --git a/src/app/dev/portofolio/main/[id]/page.tsx b/src/app/dev/portofolio/main/[id]/page.tsx index 61d37c14..ab45a811 100644 --- a/src/app/dev/portofolio/main/[id]/page.tsx +++ b/src/app/dev/portofolio/main/[id]/page.tsx @@ -1,20 +1,19 @@ -import { funGetUserIdByToken } from "@/app_modules/_global/fun/get"; -import { ViewPortofolio } from "@/app_modules/katalog/portofolio"; -import { portofolio_getOneById } from "@/app_modules/katalog/portofolio/fun/get/get_one_portofolio"; +import { Portofolio_UiDetailNew } from "@/app_modules/katalog/portofolio"; const mapboxToken = process.env.MAPBOX_TOKEN!; export default async function Page({ params }: { params: { id: string } }) { - const portofolioId = params.id; - const dataPortofolio = await portofolio_getOneById(portofolioId); - const userLoginId = await funGetUserIdByToken(); + // const portofolioId = params.id; + // const dataPortofolio = await portofolio_getOneById(portofolioId); + // const userLoginId = await funGetUserIdByToken(); return ( <> - + /> */} + ); } diff --git a/src/app/dev/profile/edit/[id]/page.tsx b/src/app/dev/profile/edit/[id]/page.tsx index 53e6ca6d..1941dc84 100644 --- a/src/app/dev/profile/edit/[id]/page.tsx +++ b/src/app/dev/profile/edit/[id]/page.tsx @@ -1,14 +1,12 @@ - import EditProfile from "@/app_modules/katalog/profile/edit/view"; import { Profile_getOneProfileAndUserById } from "@/app_modules/katalog/profile/fun/get/get_one_user_profile"; export default async function Page({ params }: { params: { id: string } }) { - let profileId = params.id - const dataProfile = await Profile_getOneProfileAndUserById(profileId) + let profileId = params.id; + const dataProfile = await Profile_getOneProfileAndUserById(profileId); return ( <> - {/* {JSON.stringify(data)} */} ); diff --git a/src/app/lib/api_user_router/route_api_event.ts b/src/app/lib/api_user_router/route_api_event.ts new file mode 100644 index 00000000..9b7094c2 --- /dev/null +++ b/src/app/lib/api_user_router/route_api_event.ts @@ -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}`, +}; diff --git a/src/app/lib/new_fun_user_id.ts b/src/app/lib/new_fun_user_id.ts new file mode 100644 index 00000000..d69660c2 --- /dev/null +++ b/src/app/lib/new_fun_user_id.ts @@ -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; +} \ No newline at end of file diff --git a/src/app/lib/prisma.ts b/src/app/lib/prisma.ts index 553b19ad..a0d1a749 100644 --- a/src/app/lib/prisma.ts +++ b/src/app/lib/prisma.ts @@ -1,17 +1,26 @@ -import { PrismaClient } from '@prisma/client' - -const prismaClientSingleton = () => { - return new PrismaClient() -} - -type PrismaClientSingleton = ReturnType +import { PrismaClient } from '@prisma/client'; +// Singleton PrismaClient untuk pengembangan 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 - -if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma \ No newline at end of file +export default prisma; diff --git a/src/app/lib/realtime_provider.tsx b/src/app/lib/realtime_provider.tsx index 6468a0a0..07919a7f 100644 --- a/src/app/lib/realtime_provider.tsx +++ b/src/app/lib/realtime_provider.tsx @@ -17,6 +17,8 @@ import { gs_votingTiggerBeranda, IRealtimeData, } from "./global_state"; +import { newFunGetUserId } from "./new_fun_user_id"; +import { useState } from "react"; // const WIBU_REALTIME_TOKEN: string | undefined = // process.env.NEXT_PUBLIC_WIBU_REALTIME_TOKEN; @@ -30,12 +32,11 @@ export type TypeNotification = { }; export default function RealtimeProvider({ - userLoginId, WIBU_REALTIME_TOKEN, }: { - userLoginId: string; WIBU_REALTIME_TOKEN: string; }) { + const [userLoginId, setUserLoginId] = useState(""); const [dataRealtime, setDataRealtime] = useAtom(gs_realtimeData); const [newAdminNtf, setNewAdminNtf] = useAtom(gs_admin_ntf); const [newUserNtf, setNewUserNtf] = useAtom(gs_user_ntf); @@ -71,8 +72,15 @@ export default function RealtimeProvider({ gs_donasiTriggerBeranda ); + async function loadUserId() { + const userId = await newFunGetUserId(); + + setUserLoginId(userId as string); + } + useShallowEffect(() => { - // if (WIBU_REALTIME_TOKEN === undefined) return alert("gak dapet key"); + loadUserId(); + try { WibuRealtime.init({ project: "hipmi", @@ -201,7 +209,7 @@ export default function RealtimeProvider({ }, }); } catch (error) { - console.log(error); + console.log("Error!:", error); } }, []); diff --git a/src/app/zCoba/page.tsx b/src/app/zCoba/page.tsx index f07fb56c..8df38920 100644 --- a/src/app/zCoba/page.tsx +++ b/src/app/zCoba/page.tsx @@ -1,18 +1,111 @@ +"use client"; + +import { MainColor } from "@/app_modules/_global/color"; import { funGetUserIdByToken } from "@/app_modules/_global/fun/get"; import Coba_TestLoading from "@/app_modules/zCoba"; +import { + Avatar, + Button, + Center, + FileButton, + Paper, + Stack, +} from "@mantine/core"; +import { IconCamera } from "@tabler/icons-react"; +import { useState } from "react"; +import { DIRECTORY_ID } from "../lib"; +import { TokenStorage } from "../lib/token"; +import { envs } from "@/lib/envs"; -export default async function Page() { - await new Promise((a, b) => { - setTimeout(a, 3000); - }); +export default function Page() { + const [filePP, setFilePP] = useState(null); + const [imgPP, setImgPP] = useState(); - const userLoginId = await funGetUserIdByToken(); + async function onSave() { + const body = { + file: filePP, + dirId: DIRECTORY_ID.profile_foto, + }; + + const token = + "QWERTYUIOPLKJHGFDSAZXCVBNMQAZWSXEDCRFVTGBYHNUJMIKOLPPOIUYTREWQLKJHGFDSAMNBVCXZlghvftyguhijknhbgvcfytguu8okjnhbgvfty7u8oilkjnhgvtygu7u8ojilnkhbgvhujnkhghvjhukjnhb"; + + const formData = new FormData(); + formData.append("file", filePP as any); + + const res = await fetch("/api/upload", { + method: "POST", + body: formData, + }); + + console.log(await res.json()); + } return ( <> - {/* */} - - {/* */} + +
+ {imgPP ? ( + + + + ) : ( + + + + )} +
+ + { + try { + const buffer = URL.createObjectURL( + new Blob([new Uint8Array(await files.arrayBuffer())]) + ); + setImgPP(buffer); + setFilePP(files); + } catch (error) { + console.log(error); + } + }} + accept="image/png,image/jpeg" + > + {(props) => ( + + )} + + + +
); } diff --git a/src/app_modules/_global/button/comp_button_upload_photo.tsx b/src/app_modules/_global/button/comp_button_upload_photo.tsx index 642feddc..8cd0b16b 100644 --- a/src/app_modules/_global/button/comp_button_upload_photo.tsx +++ b/src/app_modules/_global/button/comp_button_upload_photo.tsx @@ -3,6 +3,8 @@ import { Button, FileButton } from "@mantine/core"; import { IconCamera } from "@tabler/icons-react"; import { MainColor } from "../color"; +import { MAX_SIZE } from "../lib"; +import { ComponentGlobal_NotifikasiPeringatan } from "../notif_global"; export function ComponentGlobal_ButtonUploadFileImage({ onSetFile, @@ -19,8 +21,14 @@ export function ComponentGlobal_ButtonUploadFileImage({ new Blob([new Uint8Array(await files.arrayBuffer())]) ); - onSetFile(files); - onSetImage(buffer); + if (files.size > MAX_SIZE) { + ComponentGlobal_NotifikasiPeringatan( + "Ukuran file terlalu besar. Maksimal 2 MB." + ); + } else { + onSetFile(files); + onSetImage(buffer); + } } catch (error) { console.log(error); } diff --git a/src/app_modules/_global/fun/get/fun_get_user_id_by_token.ts b/src/app_modules/_global/fun/get/fun_get_user_id_by_token.ts index d08bc9cb..ed2d0ee0 100644 --- a/src/app_modules/_global/fun/get/fun_get_user_id_by_token.ts +++ b/src/app_modules/_global/fun/get/fun_get_user_id_by_token.ts @@ -7,13 +7,16 @@ import { jwtVerify } from "jose"; import { cookies } from "next/headers"; export async function funGetUserIdByToken() { - const c = cookies().get(process.env.NEXT_PUBLIC_BASE_SESSION_KEY!); + const SESSION_KEY = process.env.NEXT_PUBLIC_BASE_SESSION_KEY!; + // console.log("SESSION_KEY", SESSION_KEY); + const c = cookies().get("hipmi-key"); const cekUser = await decrypt({ token: c?.value as string, encodedKey: process.env.NEXT_PUBLIC_BASE_TOKEN_KEY!, }); + // console.log("userid" , cekUser?.id) // const token = JSON.parse( // await unsealData(c?.value as string, { diff --git a/src/app_modules/_global/fun/upload/fun_upload_to_storage.ts b/src/app_modules/_global/fun/upload/fun_upload_to_storage.ts index 30bc8a51..52155b9b 100644 --- a/src/app_modules/_global/fun/upload/fun_upload_to_storage.ts +++ b/src/app_modules/_global/fun/upload/fun_upload_to_storage.ts @@ -54,6 +54,4 @@ export async function funGlobal_UploadToStorage({ console.error("Error:", error); return { success: false, data: {} }; } - - return { success: false, data: { id: "" } }; } diff --git a/src/app_modules/_global/lib/index.ts b/src/app_modules/_global/lib/index.ts new file mode 100644 index 00000000..78b13e14 --- /dev/null +++ b/src/app_modules/_global/lib/index.ts @@ -0,0 +1,3 @@ +import { MAX_SIZE } from "./max_size"; + +export { MAX_SIZE }; diff --git a/src/app_modules/_global/lib/max_size.ts b/src/app_modules/_global/lib/max_size.ts new file mode 100644 index 00000000..d312cf45 --- /dev/null +++ b/src/app_modules/_global/lib/max_size.ts @@ -0,0 +1,2 @@ +// Maksimal ukuran file dalam byte (2 MB) +export const MAX_SIZE = 2 * 1024 * 1024; // 2 MB diff --git a/src/app_modules/_global/ui/ui_drawer.tsx b/src/app_modules/_global/ui/ui_drawer.tsx index e15e2bea..9cc21141 100644 --- a/src/app_modules/_global/ui/ui_drawer.tsx +++ b/src/app_modules/_global/ui/ui_drawer.tsx @@ -28,13 +28,13 @@ export default function UIGlobal_Drawer({ opened: boolean; close: () => void; component: - | { - id: string; - name: string; - icon: string; - path: string; - }[] - | any[]; + | { + id: string; + name: string; + icon: string; + path: string; + }[] + | any[]; }) { const router = useRouter(); const [isLoading, setIsLoading] = useState(false); @@ -77,21 +77,28 @@ export default function UIGlobal_Drawer({ {component.map((e, i) => ( - + { + setPageId(e?.id); + setIsLoading(true); + router.push(e?.path, { scroll: false }); + }} + > { - setPageId(e?.id); - setIsLoading(true); - router.push(e?.path, {scroll: false}); - }} > - {isLoading && e?.id === pageId ? ( + {/* PAKE LOADING */} + {/* {isLoading && e?.id === pageId ? ( ) : ( e?.icon - )} + )} */} + + + {/* GA PAKE LOADING */} + {e?.icon} + {e?.name} diff --git a/src/app_modules/_global/ui/ui_header_tamplate.tsx b/src/app_modules/_global/ui/ui_header_tamplate.tsx index 6126711c..6f6425e9 100644 --- a/src/app_modules/_global/ui/ui_header_tamplate.tsx +++ b/src/app_modules/_global/ui/ui_header_tamplate.tsx @@ -77,12 +77,21 @@ export default function UIGlobal_LayoutHeaderTamplate({ : router.push(routerLeft, { scroll: false }); }} > - {isLoading ? ( + {/* PAKE LOADING SAAT KLIK BACK */} + {/* {isLoading ? ( ) : iconLeft ? ( iconLeft ) : ( + )} */} + + + {/* GA PAKE LOADING SAAT KLIK BACK */} + {iconLeft ? ( + iconLeft + ) : ( + )} )} diff --git a/src/app_modules/_global/ui/ui_image_preview.tsx b/src/app_modules/_global/ui/ui_image_preview.tsx index 9f37411a..a2057b2d 100644 --- a/src/app_modules/_global/ui/ui_image_preview.tsx +++ b/src/app_modules/_global/ui/ui_image_preview.tsx @@ -28,7 +28,7 @@ export function UIGlobal_ImagePreview({ fileId }: { fileId: string }) { const [isImage, setIsImage] = useState(null); const [isLoading, setIsLoading] = useState(false); - const url = APIs.GET({ fileId: fileId }); + const url = APIs.GET({ fileId: fileId, size: "500" }); useShallowEffect(() => { onLoadImage(); diff --git a/src/app_modules/admin/event/_view/view_detail_peserta.tsx b/src/app_modules/admin/event/_view/view_detail_peserta.tsx index 6c09ef87..c1b76811 100644 --- a/src/app_modules/admin/event/_view/view_detail_peserta.tsx +++ b/src/app_modules/admin/event/_view/view_detail_peserta.tsx @@ -2,6 +2,7 @@ import { MODEL_EVENT_PESERTA } from "@/app_modules/event/model/interface"; import { + Badge, Button, Center, Pagination, @@ -26,6 +27,7 @@ export function AdminEvent_ViewDetailPeserta({ const [isNPage, setNPage] = useState(dataPeserta.nPage); const [isActivePage, setActivePage] = useState(1); + async function onPageClick(p: any) { setActivePage(p); const loadData = await adminEvent_getListPesertaById({ @@ -52,6 +54,15 @@ export function AdminEvent_ViewDetailPeserta({
{e?.User?.Profile?.email}
+ +
+ {e.isPresent ? ( + Hadir + ) : ( + Tidak Hadir + )} +
+ )); @@ -81,6 +92,9 @@ export function AdminEvent_ViewDetailPeserta({
Email
+ +
Konfirmasi Kehadiran
+ {tableRow} diff --git a/src/app_modules/admin/event/_view/view_table_review.tsx b/src/app_modules/admin/event/_view/view_table_review.tsx index 4b9ab12c..4b64fb13 100644 --- a/src/app_modules/admin/event/_view/view_table_review.tsx +++ b/src/app_modules/admin/event/_view/view_table_review.tsx @@ -108,15 +108,15 @@ export default function AdminEvent_ComponentTableReview({ async function onPublish({ eventId, - tanggalSelesai, + tanggal, }: { eventId: string; - tanggalSelesai: Date; + tanggal: Date; }) { const checkStatus = await event_checkStatus({ id: eventId }); if (checkStatus) { - if (moment(tanggalSelesai).diff(Date.now(), "minutes") < 0) + if (moment(tanggal).diff(Date.now(), "minutes") < 0) return ComponentGlobal_NotifikasiPeringatan( "Waktu acara telah lewat, Report untuk memberitahu user !" ); @@ -267,7 +267,7 @@ export default function AdminEvent_ComponentTableReview({
- +
@@ -286,7 +286,7 @@ export default function AdminEvent_ComponentTableReview({ onClick={() => onPublish({ eventId: e.id, - tanggalSelesai: e.tanggalSelesai, + tanggal: e.tanggal, }) } > @@ -297,7 +297,7 @@ export default function AdminEvent_ComponentTableReview({ leftIcon={} radius={"xl"} onClick={async () => { - const checkStatus = await event_checkStatus({ id: eventId }); + const checkStatus = await event_checkStatus({ id: e.id }); if (checkStatus) { open(); diff --git a/src/app_modules/admin/event/fun/get/get_list_peserta_by_id.ts b/src/app_modules/admin/event/fun/get/get_list_peserta_by_id.ts index 7809a34a..b5b9764c 100644 --- a/src/app_modules/admin/event/fun/get/get_list_peserta_by_id.ts +++ b/src/app_modules/admin/event/fun/get/get_list_peserta_by_id.ts @@ -22,6 +22,7 @@ export async function adminEvent_getListPesertaById({ eventId: eventId, }, select: { + isPresent: true, User: { include: { Profile: true, diff --git a/src/app_modules/admin/event/table_status/table_publish.tsx b/src/app_modules/admin/event/table_status/table_publish.tsx index 01316545..1553c712 100644 --- a/src/app_modules/admin/event/table_status/table_publish.tsx +++ b/src/app_modules/admin/event/table_status/table_publish.tsx @@ -50,20 +50,20 @@ function TableStatus({ listPublish }: { listPublish: any }) { const [eventId, setEventId] = useState(""); const [loading, setLoading] = useState(false); - const [origin, setOrigin] = useState(""); + const [origin, setOrigin] = useState(""); - useShallowEffect(() => { - onLoadOrigin(setOrigin); - // if (typeof window !== "undefined") { - // setOrigin(window.location.origin); - // } - }, [setOrigin]); + 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 onLoadOrigin(setOrigin: any) { + // const res = await fetch("/api/origin-url"); + // const result = await res.json(); + // setOrigin(result.origin); + // } async function onSearch(s: string) { setSearch(s); @@ -97,11 +97,38 @@ function TableStatus({ listPublish }: { listPublish: any }) {
- + + +
+ { + 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)}`; + }} + /> +
+
{e?.Author?.username} @@ -225,6 +252,9 @@ function TableStatus({ listPublish }: { listPublish: any }) {
QR Code
+ +
Download QR
+
Username
diff --git a/src/app_modules/auth/register/view.tsx b/src/app_modules/auth/register/view.tsx index 7c1de36f..a8b6f985 100644 --- a/src/app_modules/auth/register/view.tsx +++ b/src/app_modules/auth/register/view.tsx @@ -41,7 +41,7 @@ export default function Register() { const res = await fetch(`/api/auth/check?id=${kodeId}`); const result = await res.json(); - onSetData(result.data.nomor); + onSetData(result.nomor); } async function onRegistarsi() { @@ -64,6 +64,11 @@ export default function Register() { const result = await res.json(); + if (res.status === 400) { + setLoading(false); + ComponentGlobal_NotifikasiPeringatan(result.message); + } + if (res.status === 200) { localStorage.removeItem("hipmi_auth_code_id"); ComponentGlobal_NotifikasiBerhasil(result.message); @@ -73,11 +78,6 @@ export default function Register() { nomor: data.nomor, }); } - - if (res.status === 400) { - setLoading(false); - ComponentGlobal_NotifikasiPeringatan(result.message); - } } catch (error) { console.log(error); } diff --git a/src/app_modules/auth/validasi/view.tsx b/src/app_modules/auth/validasi/view.tsx index d817b00e..d0b39c01 100644 --- a/src/app_modules/auth/validasi/view.tsx +++ b/src/app_modules/auth/validasi/view.tsx @@ -43,7 +43,7 @@ export default function Validasi() { useShallowEffect(() => { const kodeId = localStorage.getItem("hipmi_auth_code_id"); if (kodeId != null) { - onCheckAuthCode({ kodeId: kodeId as string, onSetData: setData }); + onCheckAuthCode({ kodeId: kodeId as string }); } else { console.log("code id not found"); } @@ -51,27 +51,25 @@ export default function Validasi() { if (triggerOtp) { const kodeId = localStorage.getItem("hipmi_auth_code_id"); if (kodeId != null) { - onCheckAuthCode({ kodeId: kodeId as string, onSetData: setData }); + onCheckAuthCode({ kodeId: kodeId as string }); } else { console.log("code id not found"); } setTriggerOtp(false); } - }, [triggerOtp, setData, setTriggerOtp]); + }, [triggerOtp]); 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, + setData({ + nomor: result.nomor, + code: result.otp, }); } diff --git a/src/app_modules/colab/splash/index.tsx b/src/app_modules/colab/splash/index.tsx index 48839abb..3d6ee713 100644 --- a/src/app_modules/colab/splash/index.tsx +++ b/src/app_modules/colab/splash/index.tsx @@ -17,7 +17,7 @@ export default function Colab_Splash() { setHotMenu(1); // setStatus("Publish"); router.replace(RouterColab.beranda, {scroll: false}); - }, 1000); + }, 500); }, []); return ( diff --git a/src/app_modules/crowd/splash/view.tsx b/src/app_modules/crowd/splash/view.tsx index 65e4e84f..e60ab74a 100644 --- a/src/app_modules/crowd/splash/view.tsx +++ b/src/app_modules/crowd/splash/view.tsx @@ -10,7 +10,7 @@ export default function SplashCrowd() { const router = useRouter(); useShallowEffect(() => { - setTimeout(() => router.push(RouterCrowd.main), 1000); + setTimeout(() => router.push(RouterCrowd.main), 500); }, []); return ( <> diff --git a/src/app_modules/event/_ui/konfirmasi.tsx b/src/app_modules/event/_ui/konfirmasi.tsx index 468e8c14..ecaa99df 100644 --- a/src/app_modules/event/_ui/konfirmasi.tsx +++ b/src/app_modules/event/_ui/konfirmasi.tsx @@ -1,134 +1,592 @@ "use client"; -import { - UIGlobal_LayoutDefault, - UIGlobal_LayoutTamplate, -} from "@/app_modules/_global/ui"; -import { Button, 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 { API_RouteEvent } from "@/app/lib/api_user_router/route_api_event"; +import { RouterEvent } from "@/app/lib/router_hipmi/router_event"; +import { MainColor } from "@/app_modules/_global/color"; +import { ComponentGlobal_CardStyles } from "@/app_modules/_global/component"; import { ComponentGlobal_NotifikasiBerhasil, ComponentGlobal_NotifikasiGagal, } from "@/app_modules/_global/notif_global"; +import { UIGlobal_LayoutDefault } from "@/app_modules/_global/ui"; +import { Button, Center, Group, Skeleton, Stack, Text } from "@mantine/core"; +import { useShallowEffect } from "@mantine/hooks"; +import { useAtom } from "jotai"; +import moment from "moment"; import { useRouter } from "next/navigation"; -import { RouterEvent } from "@/app/lib/router_hipmi/router_event"; import { useState } from "react"; +import { event_funUpdateKehadiran } from "../fun"; +import { Event_funJoinAndConfirmEvent } from "../fun/create/fun_join_and_confirm"; +import { gs_event_hotMenu } from "../global_state"; +import { MODEL_EVENT } from "../model/interface"; +import { Event_funJoinEvent } from "../fun/create/fun_join_event"; +import "moment/locale/id"; export default function Ui_Konfirmasi({ - dataEvent, userLoginId, + eventId, }: { - dataEvent: MODEL_EVENT; userLoginId: string; + eventId: string; }) { // console.log(dataEvent); const router = useRouter(); - const [isLoading, setLoading] = useState(false); + const [data, setData] = useState(null); + const [isJoin, setIsJoin] = useState(null); const [isPresent, setIsPresent] = useState(null); - // useShallowEffect(() => { - // onLoadData({ - // onPublish(val) { - // setData(val); - // }, - // }); - // }, [setData]); - useShallowEffect(() => { - onLoadKehadiran({ - onChange(val) { - setIsPresent(val); - }, - }); - }, [setIsPresent]); + onLoadData(); + }, []); - async function onLoadKehadiran({ - onChange, - }: { - onChange: (val: boolean) => void; - }) { - const checkKehadiran = await event_funCheckKehadiran({ - eventId: dataEvent.id, - userId: userLoginId as string, - }); - - onChange(checkKehadiran); + async function onLoadData() { + const data = await fetch( + API_RouteEvent.get_one_by_id({ eventId: eventId }) + ); + const res = await data.json(); + setData(res.data); } - async function onUpdateKonfirmasi() { - setLoading(true); - const res = await event_funUpdateKehadiran({ - eventId: dataEvent.id, - userId: userLoginId, - }); + // CEK PESERTA + useShallowEffect(() => { + onCheckPeserta(); + }, []); + + async function onCheckPeserta() { + const res = await fetch( + API_RouteEvent.check_peserta({ eventId: eventId, userId: userLoginId }) + ); + const data = await res.json(); + 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); + } + // =========== CEK KEHADIRAN ===========// + + // Jika data kosong + if (data == null && isPresent == null) { + return ; + } + + // Jika data tidak ada + if (data == null) { + return ( + <> + + + ); + } + + // Jika tanggal acara sudah lewat + if (moment(data?.tanggalSelesai).diff(moment(), "minute") < 0) { + return ( + <> + + + ); + } + + // Jika join true + if (isJoin == true && moment(data?.tanggal).diff(moment(), "minute") > 0) { + return ( + <> + + + ); + } + + // Jika belum join dan tanggal mulai acara belum lewat + if (isJoin == false && moment(data?.tanggal).diff(moment(), "minute") > 0) { + return ( + <> + + + ); + } + + // Jika belum join dan tanggal mulai acara sudah lewat + if (isJoin == false && moment(data?.tanggal).diff(moment(), "minute") < 0) { + return ( + <> + + + ); + } + + if (isPresent == false && data) { + return ( + + ); + } + + // Jika sudah join, sudah konfirmasi dan tanggal mulai acara sudah lewat + // if (isPresent && moment(data?.tanggal).diff(moment(), "minute") < 0) + if ( + isPresent && + isJoin && + moment(data?.tanggal).diff(moment(), "minute") < 0 + ) { + return ; + } +} + +function DataNotFound() { + const router = useRouter(); + const [isLoading, setLoading] = useState(false); + const [hotMenu, setHotMenu] = useAtom(gs_event_hotMenu); + + return ( + <> + + + + + + Data Event Tidak Ditemukan + + + + + + + + + ); +} + +function SkeletonIsDataNull() { + return ( + <> + + + + + {" "} + {" "} + +
+ +
+
+
+
+
+ + ); +} + +function UserJoinTrue({ title, tanggal }: { title: string; tanggal: Date }) { + const router = useRouter(); + const [isLoading, setLoading] = useState(false); + const [hotMenu, setHotMenu] = useAtom(gs_event_hotMenu); + + return ( + <> + + + + + + Terima kasih, Bapak/Ibu, Anda telah berhasil bergabung dalam + acara{" "} + + {title} + {" "} + . Mohon ditunggu hingga tanggal{" "} + + {moment(tanggal).format("DD-MM-YYYY")} + {" "} + untuk melakukan konfirmasi kehadiran melalui aplikasi HIPMI APP. + + + + + + + + + ); +} + +function UserAllowToJoin({ + title, + tanggal, + lokasi, + eventId, + userLoginId, +}: { + title: string; + tanggal: Date; + lokasi: string; + eventId: string; + userLoginId: string; +}) { + const router = useRouter(); + const [isLoading, setLoading] = useState(false); + + async function onJoinEvent() { + setLoading(true); + + const data = { + userId: userLoginId, + eventId: eventId, + }; + + const res = await Event_funJoinEvent(data as any); if (res.status === 200) { ComponentGlobal_NotifikasiBerhasil(res.message, 2000); - router.push(RouterEvent.detail_main + dataEvent.id); + router.push(RouterEvent.detail_main + eventId); } else { setLoading(false); ComponentGlobal_NotifikasiGagal(res.message); } } - if (isPresent === null) { - return <>; - } - return ( <> - - {isPresent == null ? ( - - ) : isPresent ? ( - - - - Anda telah terkonfirmasi silahkan kembali ke beranda ! - - {dataEvent.title} - - - - ) : ( - - - - Anda mengkonfirmasi bahwa anda telah datang & ikut menghadir - di event - - {dataEvent.title} - - - - )} + + + + + Halo, Bapak/Ibu. Kami dengan senang hati mengundang Anda untuk + bergabung dalam acara + + {title} + {" "} + yang akan diselenggarakan pada{" "} + + {moment(tanggal).format("LL")} + {" "} + pukul + + {moment(tanggal).format("LT")} + {" "} + di + + {lokasi} + {" "} + . Pastikan Anda sudah melakukan registrasi melalui aplikasi + [Nama Aplikasi] agar dapat berpartisipasi. Kami sangat + menantikan kehadiran Anda. Sampai jumpa di acara ini. + + + + + + + + + ); +} + +function UserNotJoinAndEventReady({ + 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 ( + <> + + + + + + Halo, Bapak/Ibu. Kami mencatat bahwa Anda belum melakukan + registrasi melalui aplikasi untuk mengikuti acara{" "} + + {title}. + {" "} + 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. + + + + + + + + + ); +} + +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 ( + <> + + + + + + Kami mohon maaf, Bapak/Ibu, acara{" "} + + {title} + {" "} + 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. + + + + + + + + + + + + ); +} + +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 ( + <> + + + + + + Terima kasih atas kehadiran Anda di acara{" "} + + {title} + {" "} + pada hari ini. Mohon untuk mengonfirmasi kehadiran Anda dengan + menekan tombol{" "} + + Konfirmasi Kehadiran + {" "} + atau fitur konfirmasi yang tersedia di bawah. Terima kasih dan + selamat menikmati acara. + + + + + + + + + ); +} + +function UserAlreadyConfirm({ title }: { title: string }) { + const router = useRouter(); + const [isLoading, setLoading] = useState(false); + const [hotMenu, setHotMenu] = useAtom(gs_event_hotMenu); + + return ( + <> + + + + + + Terima kasih, Bapak/Ibu, kehadiran Anda di acara{" "} + + {title} + {" "} + telah berhasil dikonfirmasi. Kami senang menyambut Anda dan + semoga acara ini memberikan manfaat yang maksimal. Selamat + mengikuti kegiatan. + + + + + diff --git a/src/app_modules/event/component/card_view/card_beranda.tsx b/src/app_modules/event/component/card_view/card_beranda.tsx index d751c207..adb952fa 100644 --- a/src/app_modules/event/component/card_view/card_beranda.tsx +++ b/src/app_modules/event/component/card_view/card_beranda.tsx @@ -34,11 +34,11 @@ export function ComponentEvent_CardBeranda({ data }: { data: any }) { {data.title} - + {/* {new Intl.DateTimeFormat("id-ID", { dateStyle: "medium", - }).format(data.tanggal)} - + }).format(data?.tanggal)} + */} diff --git a/src/app_modules/event/component/detail/detail_main.tsx b/src/app_modules/event/component/detail/detail_main.tsx index bfcdefea..4625b1e6 100644 --- a/src/app_modules/event/component/detail/detail_main.tsx +++ b/src/app_modules/event/component/detail/detail_main.tsx @@ -4,104 +4,110 @@ import { ComponentGlobal_AvatarAndUsername, ComponentGlobal_CardStyles, } 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 { 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({ - data, + eventId, }: { - data: MODEL_EVENT; + eventId: string; }) { - const tgl = data.tanggal; - const hari = tgl.toLocaleString("id-ID", { dateStyle: "full" }); + const [data, setData] = useState(null); - const jam = tgl.toLocaleTimeString([], { - timeStyle: "short", - hourCycle: "h24", - }); + 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); + } return ( <> - - - + {data == null ? ( + + ) : ( + + + - - - {data ? data.title : null} - - - - Lokasi - - : - - {data ? data.lokasi : null} - - - - - Tipe Acara - - : - - {data ? data.EventMaster_TipeAcara.name : null} - - - - - Tanggal & Waktu + + + {data ? data.title : null} + - Mulai + Lokasi : - - {" "} - {new Intl.DateTimeFormat("id-ID", { - dateStyle: "full", - }).format(data?.tanggal)} - ,{" "} - - {new Intl.DateTimeFormat("id-ID", { - timeStyle: "short", - }).format(data?.tanggal)} - - + {data ? data.lokasi : null} - Selesai + Tipe Acara : - - {" "} - {new Intl.DateTimeFormat("id-ID", { - dateStyle: "full", - }).format(data?.tanggalSelesai)} - ,{" "} - - {new Intl.DateTimeFormat("id-ID", { - timeStyle: "short", - }).format(data?.tanggalSelesai)} - - + {data ? data.EventMaster_TipeAcara.name : null} - - - Deskripsi - {data ? data?.deskripsi : null} + + Tanggal & Waktu + + + Mulai + + : + + + {moment( + data.tanggal?.toLocaleString("id-ID", { + dateStyle: "full", + }) + ).format("dddd, DD MMMM YYYY, LT")} + + + + + + Selesai + + : + + + {moment( + data.tanggalSelesai?.toLocaleString("id-ID", { + dateStyle: "full", + }) + ).format("dddd, DD MMMM YYYY, LT")} + + + + + + + Deskripsi + {data ? data?.deskripsi : null} + - - + + )} ); } diff --git a/src/app_modules/event/component/detail/list_peserta.tsx b/src/app_modules/event/component/detail/list_peserta.tsx index 73d56a58..0089b2f2 100644 --- a/src/app_modules/event/component/detail/list_peserta.tsx +++ b/src/app_modules/event/component/detail/list_peserta.tsx @@ -3,9 +3,12 @@ import { ActionIcon, Avatar, + Badge, Center, Grid, Group, + Loader, + Skeleton, Stack, Text, Title, @@ -26,55 +29,112 @@ 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"; +import { ScrollOnly } from "next-scroll-loader"; +import { event_newGetListPesertaById } from "../../fun"; export default function ComponentEvent_ListPeserta({ - listPeserta, total, + eventId, + isNewPeserta, }: { - listPeserta: MODEL_EVENT_PESERTA[]; total: number; + eventId: string; + isNewPeserta?: boolean | null; }) { const router = useRouter(); + const [data, setData] = useState(null); + const [activePage, setActivePage] = useState(1); + + 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 ( <> - - -
- Daftar Peserta ({total}) -
- - {_.isEmpty(listPeserta) ? ( + {data === null ? ( + + ) : ( + +
- - - Tidak ada peserta - - + Daftar Peserta ({total})
- ) : ( - - {listPeserta.map((e, i) => ( - - {/* */} + {_.isEmpty(data) ? ( +
+ + - Tidak ada peserta - + +
+ ) : ( + // + // {data.map((e, i) => ( + // + // + + // {/* */} + // + // ))} + // + ( +
+ +
+ )} + data={data} + setData={setData as any} + moreData={async () => { + const loadData = await event_newGetListPesertaById({ + eventId: eventId as string, + page: activePage + 1, + }); + + setActivePage((val) => val + 1); + + return loadData; + }} + > + {(item) => ( - - {/* */} -
- ))} -
- )} -
-
+ )} + + )} +
+
+ )} ); } @@ -112,11 +172,7 @@ function ComponentEvent_AvatarAndUsername({ } } - const tglMulai = moment(tanggalMulai).diff(moment(), "minutes"); - - const tglSelesai = moment(tanggalSelesai).diff(moment(), "minutes"); - - // console.log("mulai:", tglMulai, "selesai:", tglSelesai); + const tglMulai = moment(tanggalMulai).diff(moment(), "minutes") < 0; return ( <> @@ -153,20 +209,16 @@ function ComponentEvent_AvatarAndUsername({ - {/* {component && ( - - - {component} - - - )} */} - - {tglMulai < 0 && ( - + {tglMulai && ( + - {isPresent ? "Hadir" : "-"} + {isPresent ? ( + Hadir + ) : ( + - + )} diff --git a/src/app_modules/event/component/index.ts b/src/app_modules/event/component/index.ts index d9cc4eeb..6180e8a6 100644 --- a/src/app_modules/event/component/index.ts +++ b/src/app_modules/event/component/index.ts @@ -1,5 +1,11 @@ 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_ComponentSkeletonListPeserta from "./skeleton/comp_skeleton_list_peserta"; export { Event_ComponentSkeletonDetailData }; export { Event_ComponentCreateButton }; +export { Event_ComponentSkeletonBeranda }; +export { Event_ComponentSkeletonDetail }; +export { Event_ComponentSkeletonListPeserta }; diff --git a/src/app_modules/event/component/skeleton/comp_skeleton_beranda.tsx b/src/app_modules/event/component/skeleton/comp_skeleton_beranda.tsx new file mode 100644 index 00000000..e45a9247 --- /dev/null +++ b/src/app_modules/event/component/skeleton/comp_skeleton_beranda.tsx @@ -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) => ( + + + + + + + + + + + + + + + + + + ))} + + ); +} diff --git a/src/app_modules/event/component/skeleton/comp_skeleton_detail.tsx b/src/app_modules/event/component/skeleton/comp_skeleton_detail.tsx new file mode 100644 index 00000000..200491a5 --- /dev/null +++ b/src/app_modules/event/component/skeleton/comp_skeleton_detail.tsx @@ -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 ( + <> + + + + + + + + + + + + +
+ +
+ + + + + + + + + + +
+
+ + ); +} diff --git a/src/app_modules/event/component/skeleton/comp_skeleton_list_peserta.tsx b/src/app_modules/event/component/skeleton/comp_skeleton_list_peserta.tsx new file mode 100644 index 00000000..9cca2112 --- /dev/null +++ b/src/app_modules/event/component/skeleton/comp_skeleton_list_peserta.tsx @@ -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 ( + <> + + +
+ +
+ + + {Array.from(new Array(3)).map((e, i) => ( + + + + + + + + + + + + ))} + +
+
+ + ); +} diff --git a/src/app_modules/event/detail/kontribusi/index.tsx b/src/app_modules/event/detail/kontribusi/index.tsx index ee709ea4..6d667ad1 100644 --- a/src/app_modules/event/detail/kontribusi/index.tsx +++ b/src/app_modules/event/detail/kontribusi/index.tsx @@ -3,25 +3,19 @@ import { Stack } from "@mantine/core"; import ComponentEvent_DetailMainData from "../../component/detail/detail_main"; import ComponentEvent_ListPeserta from "../../component/detail/list_peserta"; -import { MODEL_EVENT, MODEL_EVENT_PESERTA } from "../../model/interface"; export default function Event_DetailKontribusi({ - dataEvent, - listKontributor, + eventId, totalPeserta, }: { - dataEvent: MODEL_EVENT; - listKontributor: MODEL_EVENT_PESERTA[]; + eventId: string; totalPeserta: number; }) { return ( <> - - + + ); diff --git a/src/app_modules/event/detail/main_detail/index.tsx b/src/app_modules/event/detail/main_detail/index.tsx index 71376d11..3438ba1a 100644 --- a/src/app_modules/event/detail/main_detail/index.tsx +++ b/src/app_modules/event/detail/main_detail/index.tsx @@ -1,11 +1,12 @@ "use client"; +import { API_RouteEvent } from "@/app/lib/api_user_router/route_api_event"; import { IRealtimeData } from "@/app/lib/global_state"; import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil"; import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal"; import notifikasiToUser_funCreate from "@/app_modules/notifikasi/fun/create/create_notif_to_user"; -import { Button, Stack } from "@mantine/core"; -import { useRouter } from "next/navigation"; +import { Button, Skeleton, Stack } from "@mantine/core"; +import { useShallowEffect } from "@mantine/hooks"; import { useState } from "react"; import { WibuRealtime } from "wibu-pkg"; import ComponentEvent_DetailMainData from "../../component/detail/detail_main"; @@ -13,31 +14,43 @@ import ComponentEvent_ListPeserta from "../../component/detail/list_peserta"; import { Event_countTotalPesertaById } from "../../fun/count/count_total_peserta_by_id"; import { Event_funJoinEvent } from "../../fun/create/fun_join_event"; import { Event_getListPesertaById } from "../../fun/get/get_list_peserta_by_id"; -import { MODEL_EVENT, MODEL_EVENT_PESERTA } from "../../model/interface"; export default function Event_DetailMain({ - dataEvent, - listPeserta, userLoginId, - isJoin, totalPeserta, + eventId, }: { - dataEvent: MODEL_EVENT; - listPeserta: MODEL_EVENT_PESERTA[]; userLoginId: string; - isJoin: boolean; totalPeserta: number; + eventId: string; }) { - const router = useRouter(); const [total, setTotal] = useState(totalPeserta); - const [peserta, setPeserta] = useState(listPeserta); const [isLoading, setLoading] = useState(false); + const [isJoinSuccess, setIsJoinSuccess] = useState(null); + const [isNewPeserta, setIsNewPeserta] = useState(null); + + useShallowEffect(() => { + onCheckPeserta(); + }, []); + + async function onCheckPeserta() { + const res = await fetch( + API_RouteEvent.check_peserta({ eventId: eventId, userId: userLoginId }) + ); + const data = await res.json(); + setIsJoinSuccess(data); + } return ( <> - - {isJoin ? ( + + + {isJoinSuccess == null ? ( + + ) : isJoinSuccess ? ( @@ -50,10 +63,11 @@ export default function Event_DetailMain({ onClick={() => { onJoin( userLoginId, - dataEvent.id, - setPeserta, + eventId, setTotal, - setLoading + setLoading, + setIsJoinSuccess, + setIsNewPeserta ); }} > @@ -61,7 +75,11 @@ export default function Event_DetailMain({ )} - + ); @@ -70,9 +88,11 @@ export default function Event_DetailMain({ async function onJoin( userId: string, eventId: string, - setPeserta: any, setTotal: any, - setLoading: any + setLoading: any, + setIsJoinSuccess: (val: boolean | null) => void, + setIsNewPeserta: any + ) { const body = { userId: userId, @@ -84,7 +104,7 @@ async function onJoin( const res = await Event_funJoinEvent(body as any); if (res.status === 200) { const resPeserta = await Event_getListPesertaById(eventId); - setPeserta(resPeserta); + setIsNewPeserta(true); const resTotal = await Event_countTotalPesertaById(eventId); setTotal(resTotal); @@ -111,7 +131,7 @@ async function onJoin( }); } } - + setIsJoinSuccess(true); setLoading(true); ComponentGlobal_NotifikasiBerhasil(res.message, 2000); } else { diff --git a/src/app_modules/event/detail/publish/index.tsx b/src/app_modules/event/detail/publish/index.tsx index 9afb7e66..71df87a8 100644 --- a/src/app_modules/event/detail/publish/index.tsx +++ b/src/app_modules/event/detail/publish/index.tsx @@ -6,20 +6,17 @@ import { MODEL_EVENT } from "../../model/interface"; export default function Event_DetailPublish({ dataEvent, - listPeserta, totalPeserta, + eventId, }: { dataEvent: MODEL_EVENT; - listPeserta: any[]; totalPeserta: number; + eventId: string; }) { return ( <> - + ); } diff --git a/src/app_modules/event/detail/riwayat/index.tsx b/src/app_modules/event/detail/riwayat/index.tsx index 3d9ef6e9..774eced6 100644 --- a/src/app_modules/event/detail/riwayat/index.tsx +++ b/src/app_modules/event/detail/riwayat/index.tsx @@ -1,63 +1,27 @@ "use client"; -import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil"; -import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal"; -import { - Stack -} from "@mantine/core"; +import { Stack } from "@mantine/core"; import { useRouter } from "next/navigation"; import { useState } from "react"; import ComponentEvent_DetailMainData from "../../component/detail/detail_main"; import ComponentEvent_ListPeserta from "../../component/detail/list_peserta"; -import { Event_countTotalPesertaById } from "../../fun/count/count_total_peserta_by_id"; -import { Event_funJoinEvent } from "../../fun/create/fun_join_event"; -import { Event_getListPesertaById } from "../../fun/get/get_list_peserta_by_id"; -import { MODEL_EVENT, MODEL_EVENT_PESERTA } from "../../model/interface"; export default function Event_DetailRiwayat({ - dataEvent, - listPeserta, totalPeserta, + eventId, }: { - dataEvent: MODEL_EVENT; - listPeserta: MODEL_EVENT_PESERTA[]; totalPeserta: number; + eventId: string; }) { const router = useRouter(); const [total, setTotal] = useState(totalPeserta); - const [peserta, setPeserta] = useState(listPeserta); + return ( <> - - + + ); } - -async function onJoin( - userId: string, - eventId: string, - setPeserta: any, - setTotal: any -) { - const body = { - userId: userId, - eventId: eventId, - }; - - await Event_funJoinEvent(body as any).then(async (res) => { - if (res.status === 200) { - await Event_getListPesertaById(eventId).then(async (val) => { - await Event_countTotalPesertaById(eventId).then((ttl) => { - setPeserta(val); - setTotal(ttl); - ComponentGlobal_NotifikasiBerhasil(res.message, 2000); - }); - }); - } else { - ComponentGlobal_NotifikasiGagal(res.message); - } - }); -} diff --git a/src/app_modules/event/fun/create/fun_join_and_confirm.ts b/src/app_modules/event/fun/create/fun_join_and_confirm.ts new file mode 100644 index 00000000..6cee969c --- /dev/null +++ b/src/app_modules/event/fun/create/fun_join_and_confirm.ts @@ -0,0 +1,23 @@ +"use server"; + +import prisma from "@/app/lib/prisma"; +import { MODEL_EVENT_PESERTA } from "../../model/interface"; +import { revalidatePath } from "next/cache"; + +export async function Event_funJoinAndConfirmEvent(data: MODEL_EVENT_PESERTA) { + const join = await prisma.event_Peserta.create({ + data: { + eventId: data.eventId, + userId: data.userId, + isPresent: true, + }, + }); + + if (!join) return { status: 400, message: "Gagal Join & Konfirmasi" }; + + revalidatePath("/dev/event/detail/main"); + return { + status: 200, + message: "Berhasil Join & Konfirmasi", + }; +} diff --git a/src/app_modules/event/fun/get/new_get_list_peserta.ts b/src/app_modules/event/fun/get/new_get_list_peserta.ts new file mode 100644 index 00000000..cf44bf0c --- /dev/null +++ b/src/app_modules/event/fun/get/new_get_list_peserta.ts @@ -0,0 +1,43 @@ +"use server"; + +import prisma from "@/app/lib/prisma"; + +export async function event_newGetListPesertaById({ + eventId, + page, +}: { + eventId: string; + page: number; +}) { + const takeData = 10; + const skipData = page * takeData - takeData; + + const data = await prisma.event_Peserta.findMany({ + take: takeData, + skip: skipData, + orderBy: { + updatedAt: "desc", + }, + where: { + eventId: eventId, + }, + select: { + id: true, + active: true, + createdAt: true, + updatedAt: true, + userId: true, + + isPresent: true, + User: { + select: { + Profile: true, + }, + }, + Event: true, + eventId: true, + }, + }); + + return data; +} diff --git a/src/app_modules/event/fun/index.ts b/src/app_modules/event/fun/index.ts index 39702477..b63c8c35 100644 --- a/src/app_modules/event/fun/index.ts +++ b/src/app_modules/event/fun/index.ts @@ -1,6 +1,7 @@ import { event_funUpdateKehadiran } from "./edit/fun_update_konfirmasi_by_user_id"; import { event_funCheckKehadiran } from "./get/fun_check_kehadiran"; import { event_funCheckPesertaByUserId } from "./get/fun_check_peserta_by_user_id"; +import { event_newGetListPesertaById } from "./get/new_get_list_peserta"; import { event_getAllByStatusId } from "./get/status/get_all_by_status_id"; import { event_getMasterStatus } from "./master/get_status_event"; @@ -9,3 +10,4 @@ export { event_getMasterStatus }; export { event_funCheckPesertaByUserId }; export { event_funUpdateKehadiran }; export { event_funCheckKehadiran }; +export { event_newGetListPesertaById }; diff --git a/src/app_modules/event/main/beranda.tsx b/src/app_modules/event/main/beranda.tsx index 5714cc6a..33565488 100644 --- a/src/app_modules/event/main/beranda.tsx +++ b/src/app_modules/event/main/beranda.tsx @@ -5,7 +5,16 @@ import { RouterEvent } from "@/app/lib/router_hipmi/router_event"; import { AccentColor } from "@/app_modules/_global/color"; import ComponentGlobal_CreateButton from "@/app_modules/_global/component/button_create"; import ComponentGlobal_IsEmptyData from "@/app_modules/_global/component/is_empty_data"; -import { Affix, Box, Button, Center, Loader, rem } from "@mantine/core"; +import { + Affix, + Box, + Button, + Center, + Loader, + rem, + Skeleton, + Paper, +} from "@mantine/core"; import { useShallowEffect } from "@mantine/hooks"; import { useAtom } from "jotai"; import _ from "lodash"; @@ -14,13 +23,11 @@ import { useState } from "react"; import { ComponentEvent_CardBeranda } from "../component/card_view/card_beranda"; import { event_getListAllPublish } from "../fun/get/get_list_all_publish"; import { MODEL_EVENT } from "../model/interface"; +import { Event_ComponentSkeletonBeranda } from "../component"; +import { API_RouteEvent } from "@/app/lib/api_user_router/route_api_event"; -export default function Event_Beranda({ - dataEvent, -}: { - dataEvent: MODEL_EVENT[]; -}) { - const [data, setData] = useState(dataEvent); +export default function Event_Beranda() { + const [data, setData] = useState(null); const [activePage, setActivePage] = useState(1); const [isLoading, setIsLoading] = useState(false); @@ -31,23 +38,27 @@ export default function Event_Beranda({ const [isShowUpdate, setIsShowUpdate] = useState(false); useShallowEffect(() => { - onLoadData({ - onPublish(val) { - setData(val); - }, - }); - }, [setData]); + setIsShowUpdate(false); + loadData(); + }, []); useShallowEffect(() => { if (isTriggerEventBeranda) { setIsShowUpdate(true); } - }, [isTriggerEventBeranda, setIsShowUpdate]); + }, [isTriggerEventBeranda]); - async function onLoadData({ onPublish }: { onPublish: (val: any) => void }) { + async function loadData() { + const res = await fetch(API_RouteEvent.get_all({ page: activePage })); + const data = await res.json(); + setData(data.data as any); + } + + async function onLoadNewData() { setIsLoading(true); - const loadData = await event_getListAllPublish({ page: 1 }); - onPublish(loadData); + const res = await fetch(API_RouteEvent.get_all({ page: 1 })); + const data = await res.json(); + setData(data.data as any); setIsShowUpdate(false); setIsTriggerEventBeranca(false); @@ -71,13 +82,7 @@ export default function Event_Beranda({ radius={"xl"} opacity={0.8} onClick={() => { - onLoadData({ - onPublish(val) { - setData(val); - }, - }); - - + onLoadNewData(); }} > Update beranda @@ -87,7 +92,10 @@ export default function Event_Beranda({ )} - {_.isEmpty(data) ? ( + + {data == null ? ( + + ) : _.isEmpty(data) ? ( ) : ( @@ -99,7 +107,7 @@ export default function Event_Beranda({
)} data={data} - setData={setData} + setData={setData as any} moreData={async () => { const loadData = await event_getListAllPublish({ page: activePage + 1, diff --git a/src/app_modules/event/splash/index.tsx b/src/app_modules/event/splash/index.tsx index e6d75e20..bd06d4ca 100644 --- a/src/app_modules/event/splash/index.tsx +++ b/src/app_modules/event/splash/index.tsx @@ -16,7 +16,7 @@ export default function Event_SplashScreen() { setTimeout(() => { router.replace(RouterEvent.beranda); setHotMenu(0); - }, 1000); + }, 500); }, []); return ( <> diff --git a/src/app_modules/forum/splash/index.tsx b/src/app_modules/forum/splash/index.tsx index 205abb33..49d9eda6 100644 --- a/src/app_modules/forum/splash/index.tsx +++ b/src/app_modules/forum/splash/index.tsx @@ -11,7 +11,7 @@ export default function Forum_Splash() { useShallowEffect(() => { setTimeout(() => { router.replace(RouterForum.beranda, { scroll: false }); - }, 1000); + }, 500); }, []); return ( diff --git a/src/app_modules/home/component/body_home.tsx b/src/app_modules/home/component/body_home.tsx new file mode 100644 index 00000000..d5984b8d --- /dev/null +++ b/src/app_modules/home/component/body_home.tsx @@ -0,0 +1,193 @@ +import { AccentColor, MainColor } from "@/app_modules/_global/color"; +import ComponentGlobal_IsEmptyData from "@/app_modules/_global/component/is_empty_data"; +import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global"; +import { ActionIcon, Box, Group, Image, Paper, SimpleGrid, Skeleton, Stack, Text } from "@mantine/core"; +import { useShallowEffect } from "@mantine/hooks"; +import { IconUserSearch } from "@tabler/icons-react"; +import _ from "lodash"; +import { useRouter } from "next/navigation"; +import { useState } from "react"; +import { apiGetDataHome } from "../fun/get/api_home"; +import { listMenuHomeBody, menuHomeJob } from "./list_menu_home"; + +export default function BodyHome() { + const router = useRouter() + const [dataUser, setDataUser] = useState({}) + const [dataJob, setDataJob] = useState([]) + const [loadingJob, setLoadingJob] = useState(true) + + useShallowEffect(() => { + cekUserLogin() + getHomeJob() + }, []); + + + async function cekUserLogin() { + try { + const response = await apiGetDataHome("?cat=cek_profile") + if (response.success) { + setDataUser(response.data); + } + } catch (error) { + console.error(error); + } + } + + async function getHomeJob() { + try { + setLoadingJob(true) + const response = await apiGetDataHome("?cat=job") + if (response.success) { + setDataJob(response.data); + } + } catch (error) { + console.error(error); + } finally { + setLoadingJob(false) + } + } + + return ( + + + logo + + + + + {listMenuHomeBody.map((e, i) => ( + { + if (dataUser.profile === undefined || dataUser?.profile === null) { + return ComponentGlobal_NotifikasiPeringatan( + "Lengkapi Profile" + ); + } else { + if (e.link === "") { + return ComponentGlobal_NotifikasiPeringatan( + "Cooming Soon !!" + ); + } else { + router.push(e.link, { scroll: false }); + } + } + }} + > + + + {e.icon} + + + {e.name} + + + + ))} + + + {/* Job View */} + + { + if (dataUser.profile === undefined || dataUser?.profile === null) { + return ComponentGlobal_NotifikasiPeringatan( + "Lengkapi Profile" + ); + } else { + if (menuHomeJob.link === "") { + return ComponentGlobal_NotifikasiPeringatan( + "Cooming Soon !!" + ); + } else { + return router.push(menuHomeJob.link, { scroll: false }); + } + } + }} + > + + + {menuHomeJob.icon} + + + {menuHomeJob.name} + + + { + loadingJob ? + Array(2) + .fill(null) + .map((_, i) => ( + + + + + + )) + : _.isEmpty(dataJob) ? + () + : ( + + {dataJob.map((e, i) => ( + + + + + + + + {e?.Author.username} + + + {e?.title} + + + + + ))} + + ) + } + + + + + ); +} \ No newline at end of file diff --git a/src/app_modules/home/component/footer_home.tsx b/src/app_modules/home/component/footer_home.tsx new file mode 100644 index 00000000..f116b19d --- /dev/null +++ b/src/app_modules/home/component/footer_home.tsx @@ -0,0 +1,113 @@ +import { APIs } from "@/app/lib"; +import { RouterProfile } from "@/app/lib/router_hipmi/router_katalog"; +import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global"; +import { ActionIcon, Box, Center, SimpleGrid, Stack, Text } from "@mantine/core"; +import { useShallowEffect } from "@mantine/hooks"; +import { IconUserCircle } from "@tabler/icons-react"; +import { useRouter } from "next/navigation"; +import { useState } from "react"; +import { apiGetDataHome } from "../fun/get/api_home"; +import { Home_ComponentAvatarProfile } from "./comp_avatar_profile"; +import { listMenuHomeFooter } from "./list_menu_home"; + +export default function FooterHome() { + const router = useRouter() + const [dataUser, setDataUser] = useState({}) + + useShallowEffect(() => { + cekUserLogin(); + }, []); + + + async function cekUserLogin() { + try { + const response = await apiGetDataHome("?cat=cek_profile") + if (response.success) { + setDataUser(response.data); + } + } catch (error) { + console.error(error); + } + } + + return ( + + + {listMenuHomeFooter.map((e) => ( +
+ { + if (dataUser.profile === undefined || dataUser?.profile === null) { + ComponentGlobal_NotifikasiPeringatan("Lengkapi Profile"); + } else { + if (e.link == "") { + ComponentGlobal_NotifikasiPeringatan("Cooming Soon") + } else { + router.push(e.link, { scroll: false }) + } + } + }} + > + + {e.icon} + + + {e.name} + + +
+ ))} + +
+ { + if (dataUser.profile === undefined || dataUser?.profile === null) { + router.push(RouterProfile.create, { scroll: false }); + } else { + router.push( + RouterProfile.katalogOLD + `${dataUser?.profile}`, + { scroll: false } + ); + } + }} + > + + {dataUser.profile === undefined || dataUser?.profile === null + ? + + : + + } + + + Profile + + +
+
+
+ ); +} \ No newline at end of file diff --git a/src/app_modules/home/component/list_menu_home.tsx b/src/app_modules/home/component/list_menu_home.tsx new file mode 100644 index 00000000..8b9de429 --- /dev/null +++ b/src/app_modules/home/component/list_menu_home.tsx @@ -0,0 +1,67 @@ +import { RouterColab } from '@/app/lib/router_hipmi/router_colab'; +import { RouterEvent } from '@/app/lib/router_hipmi/router_event'; +import { RouterForum } from '@/app/lib/router_hipmi/router_forum'; +import { RouterJob } from '@/app/lib/router_hipmi/router_job'; +import { RouterMap } from '@/app/lib/router_hipmi/router_map'; +import { RouterVote } from '@/app/lib/router_hipmi/router_vote'; +import { IconAffiliate, IconBriefcase, IconHeartHandshake, IconMap2, IconMessages, IconPackageImport, IconPresentation, IconShoppingBag } from '@tabler/icons-react'; + + +// yg ada di footer home +export const listMenuHomeFooter = [ + { + id: 1, + name: "Forums", + icon: , + link: RouterForum.splash, + }, + { + id: 2, + name: "MarketPlace", + icon: , + link: "", + }, + { + id: 3, + name: "Business Maps", + icon: , + link: RouterMap.splash, + }, +]; + + +// yg ada di kotak2 home (body) +export const listMenuHomeBody = [ + { + id: 1, + name: "Event", + icon: , + link: RouterEvent.splash, + }, + { + id: 2, + name: "Collaboration", + icon: , + link: RouterColab.splash, + }, + + { + id: 3, + name: "Voting", + icon: , + link: RouterVote.splash, + }, + + { + id: 4, + name: "Crowd Funding", + icon: , + link: `/dev/crowd/splash`, + }, +]; + +export const menuHomeJob = { + name: "Job Vacancy", + icon: , + link: RouterJob.spalsh, +}; \ No newline at end of file diff --git a/src/app_modules/home/component/ui_home.tsx b/src/app_modules/home/component/ui_home.tsx index 9ce1203d..a87ce053 100644 --- a/src/app_modules/home/component/ui_home.tsx +++ b/src/app_modules/home/component/ui_home.tsx @@ -104,7 +104,7 @@ export function Home_UiView({ border: `2px solid ${AccentColor.blue}`, }} > - logo + logo diff --git a/src/app_modules/home/fun/get/api_home.ts b/src/app_modules/home/fun/get/api_home.ts new file mode 100644 index 00000000..e55ec5eb --- /dev/null +++ b/src/app_modules/home/fun/get/api_home.ts @@ -0,0 +1,4 @@ +export const apiGetDataHome = async (path?: string) => { + const response = await fetch(`/api/new/home${(path) ? path : ''}`) + return await response.json().catch(() => null) +} \ No newline at end of file diff --git a/src/app_modules/home/index.ts b/src/app_modules/home/index.ts index 07785dd4..e0eda0b5 100644 --- a/src/app_modules/home/index.ts +++ b/src/app_modules/home/index.ts @@ -1,4 +1,6 @@ +import { listMenuHomeFooter } from './component/list_menu_home'; import HomeView from "./view_home"; +import HomeViewNew from "./view_home_new"; import Home_UserNotActive from "./user_non_active"; -export { HomeView, Home_UserNotActive as Home_UserNonActive }; +export { HomeView, HomeViewNew, listMenuHomeFooter, Home_UserNotActive as Home_UserNonActive }; diff --git a/src/app_modules/home/view_home.tsx b/src/app_modules/home/view_home.tsx index 88e38bd1..4d6a5cc4 100644 --- a/src/app_modules/home/view_home.tsx +++ b/src/app_modules/home/view_home.tsx @@ -1,21 +1,15 @@ "use client"; - -import { useEffect, useState } from "react"; +import { gs_count_ntf, gs_user_ntf } from "@/app/lib/global_state"; +import { useShallowEffect } from "@mantine/hooks"; +import { useAtom } from "jotai"; +import { useState } from "react"; import UIGlobal_LayoutHeaderTamplate from "../_global/ui/ui_header_tamplate"; import UIGlobal_LayoutTamplate from "../_global/ui/ui_layout_tamplate"; import { MODEL_JOB } from "../job/model/interface"; -import { - ComponentHome_ButtonHeaderLeft, - ComponentHome_ButtonHeaderRight, -} from "./component/button_header"; +import notifikasi_countUserNotifikasi from "../notifikasi/fun/count/fun_count_by_id"; +import { ComponentHome_ButtonHeaderLeft, ComponentHome_ButtonHeaderRight, } from "./component/button_header"; import { Home_UiFooter, Home_UiView } from "./component/ui_home"; import { MODEL_USER } from "./model/interface"; -import { useShallowEffect } from "@mantine/hooks"; -import { gs_count_ntf, gs_user_ntf } from "@/app/lib/global_state"; -import { useAtom } from "jotai"; -import notifikasi_countUserNotifikasi from "../notifikasi/fun/count/fun_count_by_id"; -import { Center, Text, Title } from "@mantine/core"; -import { useRouter } from "next/navigation"; export default function HomeView({ dataUser, @@ -26,7 +20,6 @@ export default function HomeView({ dataJob: MODEL_JOB[]; countNotifikasi: number; }) { - const router = useRouter(); const [countNtf, setCountNtf] = useState(countNotifikasi); const [newUserNtf, setNewUserNtf] = useAtom(gs_user_ntf); const [countLoadNtf, setCountLoadNtf] = useAtom(gs_count_ntf); @@ -60,15 +53,11 @@ export default function HomeView({ onLoad(loadNotif); } - // console.log(dataUser, "dipage") return ( <> - // HIPMI - //
({}) + const router = useRouter(); + + + useShallowEffect(() => { + onLoadNotifikasi({ + onLoad(val) { + setCountNtf(val); + }, + }); + + setCountNtf(countLoadNtf as any); + }, [countLoadNtf, setCountNtf]); + + useShallowEffect(() => { + setCountNtf(countNtf + newUserNtf); + setNewUserNtf(0); + }, [newUserNtf, setCountNtf]); + + async function onLoadNotifikasi({ onLoad }: { onLoad: (val: any) => void }) { + const loadNotif = await notifikasi_countUserNotifikasi(); + onLoad(loadNotif); + } + + useShallowEffect(() => { + cekUserLogin(); + }, []); + + + async function cekUserLogin() { + try { + const response = await apiGetDataHome("?cat=cek_profile") + if (response.success) { + setDataUser(response.data); + } + } catch (error) { + console.error(error); + } + } + + return ( + <> + { + if (dataUser.profile === undefined || dataUser?.profile === null) { + ComponentGlobal_NotifikasiPeringatan("Lengkapi Profile"); + } else { + router.push(RouterUserSearch.main, { scroll: false }); + } + }} + > + + + } + customButtonRight={ + { + if (dataUser.profile === undefined || dataUser?.profile === null) { + ComponentGlobal_NotifikasiPeringatan("Lengkapi Profile"); + } else { + router.push(RouterNotifikasi.categoryApp({ name: "semua" }), { + scroll: false, + }); + } + }} + > + { + countNotifikasi > 0 + ? + + {countNotifikasi > 99 ? "99+" : countNotifikasi} + + } + > + + + : + + } + + + } + /> + } + + footer={} + > + + + + ); +} diff --git a/src/app_modules/katalog/component/drawer_katalog_new.tsx b/src/app_modules/katalog/component/drawer_katalog_new.tsx new file mode 100644 index 00000000..ab0ef95c --- /dev/null +++ b/src/app_modules/katalog/component/drawer_katalog_new.tsx @@ -0,0 +1,151 @@ +import { RouterAdminDashboard } from "@/app/lib/router_hipmi/router_admin"; +import { + RouterPortofolio, + RouterProfile, +} from "@/app/lib/router_hipmi/router_katalog"; +import { AccentColor } from "@/app_modules/_global/color"; +import { + gs_admin_navbar_menu, + gs_admin_navbar_subMenu, +} from "@/app_modules/admin/_admin_global/new_global_state"; +import Component_ButtonLogout from "@/app_modules/auth/logout/view"; +import { + ActionIcon, + Drawer, + Group, + SimpleGrid, + Stack, + Text, +} from "@mantine/core"; +import { IconDashboard } from "@tabler/icons-react"; +import { + IconEdit, + IconPencilPlus, + IconPhotoEdit, + IconPolaroid, + IconX, +} from "@tabler/icons-react"; +import { useAtom } from "jotai"; +import { useParams, useRouter } from "next/navigation"; + +export default function DrawerKatalogNew({ + opened, + close, + userRoleId, + userId, +}: { + opened: boolean; + close: () => void; + userRoleId: string; + userId: string; +}) { + const param = useParams<{ id: string }>(); + const router = useRouter(); + const [activeId, setActiveId] = useAtom(gs_admin_navbar_menu); + const [activeChildId, setActiveChildId] = useAtom(gs_admin_navbar_subMenu); + + const listPage = [ + { + id: "1", + name: "Edit profile", + icon: , + path: RouterProfile.edit + param.id, + }, + { + id: "2", + name: "Ubah foto profile", + icon: , + path: RouterProfile.update_foto_profile + param.id, + }, + { + id: "3", + name: "Ubah latar belakang", + icon: , + path: RouterProfile.update_foto_background + param.id, + }, + { + id: "4", + name: "Tambah portofolio", + icon: , + path: RouterPortofolio.create + param.id, + }, + ]; + + return ( + <> + close()} + position={"bottom"} + size={"auto"} + withCloseButton={false} + styles={{ + content: { + padding: 0, + position: "absolute", + margin: "auto", + backgroundColor: "transparent", + left: 0, + right: 0, + width: 500, + }, + body: { + backgroundColor: AccentColor.darkblue, + borderTop: `2px solid ${AccentColor.blue}`, + borderRight: `1px solid ${AccentColor.blue}`, + borderLeft: `1px solid ${AccentColor.blue}`, + borderRadius: "20px 20px 0px 0px", + color: "white", + paddingBottom: "5%", + }, + }} + > + + + + + + + + {listPage.map((e, i) => ( + { + router.push(e.path, { scroll: false }); + }} + > + + {e.icon} + + + {e.name} + + + ))} + + + {userRoleId != "1" && userRoleId != "" && ( + + { + setActiveId("Main"); + setActiveChildId(""); + router.push(RouterAdminDashboard.main_admin, { + scroll: false, + }); + }} + > + + + + Dashboard Admin + + + )} + + + + + ); +} diff --git a/src/app_modules/katalog/component/regular_expressions.ts b/src/app_modules/katalog/component/regular_expressions.ts index 526ff127..bb809be0 100644 --- a/src/app_modules/katalog/component/regular_expressions.ts +++ b/src/app_modules/katalog/component/regular_expressions.ts @@ -1,2 +1,3 @@ export var validRegex = /^([a-zA-Z0-9\.!#$%&'*+/=?^_`{|}~-]+)@([a-zA-Z0-9])+.([a-z]+)(.[a-z]+)?$/; +export const gmailRegex = /^[a-zA-Z0-9._%+-]+@gmail\.com$/; \ No newline at end of file diff --git a/src/app_modules/katalog/index.ts b/src/app_modules/katalog/index.ts index 9892f2b6..165c1ec3 100644 --- a/src/app_modules/katalog/index.ts +++ b/src/app_modules/katalog/index.ts @@ -1,2 +1,4 @@ +import ViewKatalogNew from "./view_katalog_new"; export { Katalog_MainView } from "./view_katalog"; +export { ViewKatalogNew } diff --git a/src/app_modules/katalog/main/index.ts b/src/app_modules/katalog/main/index.ts index 793e49ee..127d7b75 100644 --- a/src/app_modules/katalog/main/index.ts +++ b/src/app_modules/katalog/main/index.ts @@ -1,3 +1,5 @@ import KatalogLayout from "./layout"; +import LayoutKatalogNew from "./layout_new"; export { KatalogLayout }; +export { LayoutKatalogNew } diff --git a/src/app_modules/katalog/main/layout_new.tsx b/src/app_modules/katalog/main/layout_new.tsx new file mode 100644 index 00000000..56e24577 --- /dev/null +++ b/src/app_modules/katalog/main/layout_new.tsx @@ -0,0 +1,66 @@ +'use client' +import { funGetUserIdByToken } from "@/app_modules/_global/fun/get"; +import { UIGlobal_LayoutHeaderTamplate, UIGlobal_LayoutTamplate } from "@/app_modules/_global/ui"; +import { apiGetUserProfile } from "@/app_modules/user"; +import { ActionIcon } from "@mantine/core"; +import { useDisclosure, useShallowEffect } from "@mantine/hooks"; +import { IconDotsVertical } from "@tabler/icons-react"; +import { useParams } from "next/navigation"; +import { useState } from "react"; +import DrawerKatalogNew from "../component/drawer_katalog_new"; + +export default function LayoutKatalogNew({ children }: { children: any }) { + const param = useParams<{ id: string }>() + const [authorId, setAuthorId] = useState("") + const [userRoleId, setUserRoleId] = useState("") + const [userLoginId, setUserLoginId] = useState("") + const [opened, { open, close }] = useDisclosure() + const [loading, setLoading] = useState(true); + + async function getProfile() { + try { + setLoading(true) + const response = await apiGetUserProfile(`?profile=${param.id}`) + const response2 = await funGetUserIdByToken() + if (response.success) { + setAuthorId(response.data.id) + setUserRoleId(response.data.masterUserRoleId) + setUserLoginId(response2) + } + } catch (error) { + console.error(error); + } finally { + setLoading(false) + } + } + + useShallowEffect(() => { + getProfile() + }, []) + + return ( + <> + : + authorId == userLoginId ? ( + open()}> + + + ) : ( + + ) + } + /> + } + > + {children} + close()} userRoleId={userRoleId} userId={userLoginId} /> + + + ) +} \ No newline at end of file diff --git a/src/app_modules/katalog/portofolio/component/button/comp_button_selanjutnya.tsx b/src/app_modules/katalog/portofolio/component/button/comp_button_selanjutnya.tsx index c7e3fcd5..41c037b9 100644 --- a/src/app_modules/katalog/portofolio/component/button/comp_button_selanjutnya.tsx +++ b/src/app_modules/katalog/portofolio/component/button/comp_button_selanjutnya.tsx @@ -30,6 +30,7 @@ export function Portofolio_ComponentButtonSelanjutnya({ const [loading, setLoading] = useState(false); async function onSubmit() { + setLoading(true); const porto = { namaBisnis: dataPortofolio.namaBisnis, masterBidangBisnisId: dataPortofolio.masterBidangBisnisId, @@ -56,7 +57,6 @@ export function Portofolio_ComponentButtonSelanjutnya({ fileId: uploadFileToStorage.data.id, }); if (res.status === 201) { - setLoading(true); ComponentGlobal_NotifikasiBerhasil("Berhasil disimpan"); router.replace(RouterMap.create + res.id, { scroll: false }); } else { diff --git a/src/app_modules/katalog/portofolio/component/button_delete_new.tsx b/src/app_modules/katalog/portofolio/component/button_delete_new.tsx new file mode 100644 index 00000000..84d890d2 --- /dev/null +++ b/src/app_modules/katalog/portofolio/component/button_delete_new.tsx @@ -0,0 +1,97 @@ +import { funGetUserIdByToken } from "@/app_modules/_global/fun/get"; +import { ComponentGlobal_NotifikasiBerhasil, ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global"; +import { UIGlobal_Modal } from "@/app_modules/_global/ui"; +import { Button } from "@mantine/core"; +import { useShallowEffect } from "@mantine/hooks"; +import { IconTrash } from "@tabler/icons-react"; +import { useParams, useRouter } from "next/navigation"; +import { useState } from "react"; +import { apiDeletePortofolio, apiGetOnePortofolioById } from "../lib/api_portofolio"; +import { IDetailPortofolioBisnis } from "../lib/type_portofolio"; + +export default function ComponentPortofolio_ButtonDeleteNew() { + const param = useParams<{ id: string }>() + const [openModal, setModal] = useState(false) + const [loadingDel, setLoadingDel] = useState(false) + const [userLoginId, setUserLoginId] = useState("") + const [dataPorto, setDataPorto] = useState() + const router = useRouter() + + + async function onDelete() { + try { + setLoadingDel(true) + const response = await apiDeletePortofolio(param.id) + if (response.success) { + ComponentGlobal_NotifikasiBerhasil(response.message) + router.back() + } else { + ComponentGlobal_NotifikasiGagal(response.message); + } + } catch (error) { + console.error(error) + ComponentGlobal_NotifikasiGagal("Gagal menghapus portofolio"); + } finally { + setLoadingDel(false) + } + } + + async function funGetPortofolio() { + try { + const response = await apiGetOnePortofolioById(param.id, "bisnis") + const response2 = await funGetUserIdByToken() + if (response.success) { + setDataPorto(response.data) + setUserLoginId(response2) + } + } catch (error) { + console.error(error); + } + } + + useShallowEffect(() => { + funGetPortofolio() + }, []); + + + return ( + <> + {userLoginId === dataPorto?.authorId ? ( + + ) : ( + "" + )} + + setModal(false)} + buttonKiri={ + + } + buttonKanan={ + + } + /> + + ) +} \ No newline at end of file diff --git a/src/app_modules/katalog/portofolio/component/button_more_new.tsx b/src/app_modules/katalog/portofolio/component/button_more_new.tsx new file mode 100644 index 00000000..3f788f8e --- /dev/null +++ b/src/app_modules/katalog/portofolio/component/button_more_new.tsx @@ -0,0 +1,123 @@ +import { RouterPortofolio } from "@/app/lib/router_hipmi/router_katalog"; +import { RouterMap } from "@/app/lib/router_hipmi/router_map"; +import { UIGlobal_Drawer } from "@/app_modules/_global/ui"; +import { ActionIcon } from "@mantine/core"; +import { useShallowEffect } from "@mantine/hooks"; +import { IconEdit, IconPhotoEdit, IconId, IconMapPin2, IconMapPin, IconDotsVertical } from "@tabler/icons-react"; +import { useParams } from "next/navigation"; +import { useState } from "react"; +import { apiGetOnePortofolioById } from "../lib/api_portofolio"; +import { funGetUserIdByToken } from "@/app_modules/_global/fun/get"; + +export default function ComponentPortofolio_ButtonMoreNew() { + const param = useParams<{ id: string }>() + const [userLoginId, setUserLoginId] = useState("") + const [authorId, setAuthorId] = useState("") + const [mapId, setMapId] = useState(true) + const [openDrawer, setOpenDrawer] = useState(false) + + const listPage = [ + { + id: "1", + name: "Edit detail ", + icon: , + path: RouterPortofolio.edit_data_bisnis + `${param.id}`, + }, + { + id: "2", + name: "Edit logo ", + icon: , + path: RouterPortofolio.edit_logo_bisnis + `${param.id}`, + }, + { + id: "3", + name: "Edit sosial media", + icon: , + path: RouterPortofolio.edit_medsos_bisnis + `${param.id}`, + }, + { + id: "4", + name: "Edit data map", + icon: , + path: RouterMap.edit + `${param.id}`, + }, + { + id: "5", + name: "Custom pin map", + icon: , + path: RouterMap.custom_pin + `${param.id}`, + }, + ]; + + const listPage2 = [ + { + id: "1", + name: "Edit detail ", + icon: , + path: RouterPortofolio.edit_data_bisnis + `${param.id}`, + }, + { + id: "2", + name: "Edit logo ", + icon: , + path: RouterPortofolio.edit_logo_bisnis + `${param.id}`, + }, + { + id: "3", + name: "Edit sosial media", + icon: , + path: RouterPortofolio.edit_medsos_bisnis + `${param.id}`, + }, + { + id: "4", + name: "Edit data map", + icon: , + path: RouterMap.create + `${param.id}`, + }, + { + id: "5", + name: "Custom pin map", + icon: , + path: RouterMap.custom_pin + `${param.id}`, + }, + ]; + + + async function funGetPortofolio() { + try { + const response = await apiGetOnePortofolioById(param.id, "bisnis") + const response3 = await apiGetOnePortofolioById(param.id, "lokasi") + const response2 = await funGetUserIdByToken() + if (response.success) { + setAuthorId(response.data.authorId) + setMapId((response3.data?.mapId !== null && response3.data?.mapId !== undefined) ? true : false) + setUserLoginId(response2) + } + } catch (error) { + console.error(error); + } + } + + useShallowEffect(() => { + funGetPortofolio() + }, []); + + + return ( + <> + {userLoginId === authorId ? ( + setOpenDrawer(true)}> + + + ) : ( + + )} + + setOpenDrawer(false)} + component={mapId ? listPage : listPage2} + /> + + ) +} \ No newline at end of file diff --git a/src/app_modules/katalog/portofolio/index.ts b/src/app_modules/katalog/portofolio/index.ts index 062117f7..e123bbff 100644 --- a/src/app_modules/katalog/portofolio/index.ts +++ b/src/app_modules/katalog/portofolio/index.ts @@ -1,3 +1,5 @@ +import { IListPortofolio } from './lib/type_portofolio'; +import { apiGetPortofolioByProfile } from './lib/api_portofolio'; import CreatePortofolio from "./create/view"; import CreatePortofolioLayout from "./create/layout"; import PortofolioLayout from "./ui/ui_layout"; @@ -8,6 +10,9 @@ import Portofolio_EditMedsosBisnis from "./edit/medsos/ui_edit_medsos"; import LayoutPortofolio_EditDataBisnis from "./edit/data/layout"; import LayoutPortofolio_EditLogoBisnis from "./edit/logo/layout"; import LayoutPortofolio_EditMedsosBisnis from "./edit/medsos/layout"; +import ListDetailPortofolioNew from './view/list_detail_portofolio_new'; +import Portofolio_UiDetailNew from './ui/ui_detail_portofolio_new'; +import PortofolioLayoutNew from './ui/ui_layout_new'; export { CreatePortofolio, @@ -20,6 +25,11 @@ export { LayoutPortofolio_EditDataBisnis, LayoutPortofolio_EditLogoBisnis, LayoutPortofolio_EditMedsosBisnis, + apiGetPortofolioByProfile, }; +export type { IListPortofolio }; export { Portofolio_ViewListDetail } from "./view/view_list_detail_portofolio"; +export { ListDetailPortofolioNew } +export { Portofolio_UiDetailNew } +export { PortofolioLayoutNew } diff --git a/src/app_modules/katalog/portofolio/lib/api_portofolio.ts b/src/app_modules/katalog/portofolio/lib/api_portofolio.ts new file mode 100644 index 00000000..c152514d --- /dev/null +++ b/src/app_modules/katalog/portofolio/lib/api_portofolio.ts @@ -0,0 +1,19 @@ +export const apiGetPortofolioByProfile = async (path?: string) => { + const response = await fetch(`/api/new/portofolio${(path) ? path : ''}`) + return await response.json().catch(() => null) +} + +export const apiGetOnePortofolioById = async (path: string, cat:string) => { + const response = await fetch(`/api/new/portofolio/${path}?cat=${cat}`); + return await response.json().catch(() => null); +} + +export const apiDeletePortofolio = async (path: string) => { + const response = await fetch(`/api/new/portofolio/${path}`, { + method: "DELETE", + headers: { + "Content-Type": "application/json", + }, + }); + return await response.json().catch(() => null); +} \ No newline at end of file diff --git a/src/app_modules/katalog/portofolio/lib/type_portofolio.ts b/src/app_modules/katalog/portofolio/lib/type_portofolio.ts new file mode 100644 index 00000000..1a543763 --- /dev/null +++ b/src/app_modules/katalog/portofolio/lib/type_portofolio.ts @@ -0,0 +1,35 @@ +export interface IListPortofolio { + id: string + id_Portofolio: string + profileId: string + namaBisnis: string +} + +export interface IDetailPortofolioBisnis { + id_Portofolio: string + namaBisnis: string + alamatKantor: string + tlpn: string + deskripsi: string + logoId: string + bidangBisnis: string + authorId: string +} + +export interface IDetailPortofolioLokasi { + mapId: string + logoId: string + namePin: string + latitude: string + longitude: string + imageId: string + pinId: string +} + +export interface IDetailPortofolioSosmed { + facebook: string + twitter: string + instagram: string + tiktok: string + youtube: string +} \ No newline at end of file diff --git a/src/app_modules/katalog/portofolio/ui/ui_detail_data_new.tsx b/src/app_modules/katalog/portofolio/ui/ui_detail_data_new.tsx new file mode 100644 index 00000000..92d2cead --- /dev/null +++ b/src/app_modules/katalog/portofolio/ui/ui_detail_data_new.tsx @@ -0,0 +1,131 @@ +import { AccentColor, MainColor } from "@/app_modules/_global/color"; +import { ComponentGlobal_LoadImage } from "@/app_modules/_global/component"; +import { Paper, Stack, Group, Title, SimpleGrid, Box, Grid, Divider, Text } from "@mantine/core"; +import { IconBuildingSkyscraper, IconListDetails, IconPhoneCall, IconMapPin, IconPinned } from "@tabler/icons-react"; +import { useState } from "react"; +import { IDetailPortofolioBisnis } from "../lib/type_portofolio"; +import { useParams } from "next/navigation"; +import { apiGetOnePortofolioById } from "../lib/api_portofolio"; +import { useShallowEffect } from "@mantine/hooks"; +import SkeletonDetailBisnis from "./ui_skeleton_detail_bisnis"; + +export default function Portofolio_UiDetailDataNew() { + const [loading, setLoading] = useState(true) + const param = useParams<{ id: string }>() + const [dataPorto, setDataPorto] = useState(); + + async function funGetPortofolio() { + try { + setLoading(true) + const response = await apiGetOnePortofolioById(param.id, "bisnis"); + if (response.success) { + setDataPorto(response.data); + } + } catch (error) { + console.error(error); + } finally { + setLoading(false) + } + } + + useShallowEffect(() => { + funGetPortofolio() + }, []); + + return ( + <> + + { + loading ? + + : + + + Data Bisnis + + id: {" "} + + #{dataPorto?.id_Portofolio} + + + + + + + + + + + + + + + + + + {dataPorto?.namaBisnis} + + + + + + + + {dataPorto?.bidangBisnis} + + + + + + + + {dataPorto?.tlpn} + + + + + + + + {dataPorto?.alamatKantor} + + + + + + + + + + + + + Tentang Kami + + + {dataPorto?.deskripsi} + + + } + + + + ) +} \ No newline at end of file diff --git a/src/app_modules/katalog/portofolio/ui/ui_detail_map_new.tsx b/src/app_modules/katalog/portofolio/ui/ui_detail_map_new.tsx new file mode 100644 index 00000000..b24770bd --- /dev/null +++ b/src/app_modules/katalog/portofolio/ui/ui_detail_map_new.tsx @@ -0,0 +1,133 @@ +import { APIs } from "@/app/lib"; +import { AccentColor } from "@/app_modules/_global/color"; +import { defaultMapZoom } from "@/app_modules/map/lib/default_lat_long"; +import { Paper, Stack, Title, Avatar, Skeleton, Text } from "@mantine/core"; +import "mapbox-gl/dist/mapbox-gl.css"; +import { useParams } from "next/navigation"; +import { useState } from "react"; +import { AttributionControl, Map, Marker, NavigationControl, ScaleControl, } from "react-map-gl"; +import { IDetailPortofolioLokasi } from "../lib/type_portofolio"; +import { apiGetOnePortofolioById } from "../lib/api_portofolio"; +import { useShallowEffect } from "@mantine/hooks"; +import { ComponentMap_DetailData, ComponentMap_DrawerDetailData } from "@/app_modules/map/_component"; +import ComponentGlobal_IsEmptyData from "@/app_modules/_global/component/is_empty_data"; + +export default function Portofolio_UiMapNew({ mapboxToken }: { mapboxToken: string }) { + const [loading, setLoading] = useState(true) + const param = useParams<{ id: string }>() + const [dataPorto, setDataPorto] = useState() + const [openDrawer, setOpenDrawer] = useState(false) + + async function funGetPortofolio() { + try { + setLoading(true) + const response = await apiGetOnePortofolioById(param.id, "lokasi"); + if (response.success) { + setDataPorto(response.data); + } + } catch (error) { + console.error(error); + } finally { + setLoading(false) + } + } + + useShallowEffect(() => { + funGetPortofolio() + }, []); + + + return ( + <> + + + + Lokasi Bisnis + + { + loading ? + + : + dataPorto?.mapId === null || dataPorto?.mapId === undefined ? + + : + + { + setOpenDrawer(true); + }} + pitchAlignment="auto" + > + + + + + + + + + + + } + + + + setOpenDrawer(false)} + mapId={String(dataPorto?.mapId)} + component={} + /> + + + ) +} \ No newline at end of file diff --git a/src/app_modules/katalog/portofolio/ui/ui_detail_media_new.tsx b/src/app_modules/katalog/portofolio/ui/ui_detail_media_new.tsx new file mode 100644 index 00000000..132fe798 --- /dev/null +++ b/src/app_modules/katalog/portofolio/ui/ui_detail_media_new.tsx @@ -0,0 +1,131 @@ +import { AccentColor } from "@/app_modules/_global/color"; +import { Paper, Title, Stack, Grid, Text, Skeleton, Box } from "@mantine/core"; +import { IconBrandFacebook, IconBrandInstagram, IconBrandTiktok, IconBrandTwitter, IconBrandYoutube } from "@tabler/icons-react"; +import { useParams } from "next/navigation"; +import { useState } from "react"; +import { IDetailPortofolioSosmed } from "../lib/type_portofolio"; +import { apiGetOnePortofolioById } from "../lib/api_portofolio"; +import { useShallowEffect } from "@mantine/hooks"; + +export default function Portofolio_UiSosialMediaNew() { + const [loading, setLoading] = useState(true) + const param = useParams<{ id: string }>() + const [dataPorto, setDataPorto] = useState(); + + async function funGetPortofolio() { + try { + setLoading(true) + const response = await apiGetOnePortofolioById(param.id, "sosmed"); + if (response.success) { + setDataPorto(response.data); + } + } catch (error) { + console.error(error); + } finally { + setLoading(false) + } + } + + useShallowEffect(() => { + funGetPortofolio() + }, []); + + + return ( + <> + + Media Sosial Bisnis + { + loading ? + + {[...Array(4)].map((_, index) => ( + + + + + + + + + + + ))} + + : + + + + + + + {dataPorto?.facebook ? ( + {dataPorto?.facebook} + ) : ( + "-" + )} + + + + + + + + {dataPorto?.instagram ? ( + {dataPorto?.instagram} + ) : ( + "-" + )} + + + + + + + + {dataPorto?.tiktok ? ( + {dataPorto?.tiktok} + ) : ( + "-" + )} + + + + + + + + {dataPorto?.twitter ? ( + {dataPorto?.twitter} + ) : ( + "-" + )} + + + + + + + + {dataPorto?.youtube ? ( + {dataPorto?.youtube} + ) : ( + "-" + )} + + + + + } + + + ) +} \ No newline at end of file diff --git a/src/app_modules/katalog/portofolio/ui/ui_detail_portofolio_new.tsx b/src/app_modules/katalog/portofolio/ui/ui_detail_portofolio_new.tsx new file mode 100644 index 00000000..a0203528 --- /dev/null +++ b/src/app_modules/katalog/portofolio/ui/ui_detail_portofolio_new.tsx @@ -0,0 +1,19 @@ +'use client' +import { Stack } from "@mantine/core"; +import Portofolio_UiDetailDataNew from "./ui_detail_data_new"; +import Portofolio_UiMapNew from "./ui_detail_map_new"; +import Portofolio_UiSosialMediaNew from "./ui_detail_media_new"; +import ComponentPortofolio_ButtonDeleteNew from "../component/button_delete_new"; + +export default function Portofolio_UiDetailNew({ mapboxToken }: { mapboxToken: string }) { + return ( + <> + + + + + + + + ) +} \ No newline at end of file diff --git a/src/app_modules/katalog/portofolio/ui/ui_layout_new.tsx b/src/app_modules/katalog/portofolio/ui/ui_layout_new.tsx new file mode 100644 index 00000000..9f6b5d75 --- /dev/null +++ b/src/app_modules/katalog/portofolio/ui/ui_layout_new.tsx @@ -0,0 +1,20 @@ +'use client' +import { UIGlobal_LayoutHeaderTamplate, UIGlobal_LayoutTamplate } from "@/app_modules/_global/ui"; +import ComponentPortofolio_ButtonMoreNew from "../component/button_more_new"; + +export default function PortofolioLayoutNew({ children }: { children: any }) { + return ( + <> + } + /> + } + > + {children} + + + ) +} \ No newline at end of file diff --git a/src/app_modules/katalog/portofolio/ui/ui_list_detail_portofolio_new.tsx b/src/app_modules/katalog/portofolio/ui/ui_list_detail_portofolio_new.tsx new file mode 100644 index 00000000..9add314b --- /dev/null +++ b/src/app_modules/katalog/portofolio/ui/ui_list_detail_portofolio_new.tsx @@ -0,0 +1,59 @@ +import ComponentGlobal_Loader from "@/app_modules/_global/component/loader"; +import { Box, Center } from "@mantine/core"; +import { ScrollOnly } from "next-scroll-loader"; +import { useState } from "react"; +import { ComponentPortofolio_DaftarBoxView } from "../component/card_view_daftar"; +import { portofolio_funGetAllDaftarByid } from "../fun/get/get_all_portofolio"; +import { MODEL_PORTOFOLIO } from "../model/interface"; +import { useParams } from "next/navigation"; +import { useShallowEffect } from "@mantine/hooks"; +import { apiGetPortofolioByProfile } from "../lib/api_portofolio"; + +export default function Portofolio_UiListDetailNew() { + const param = useParams<{ id: string }>() + const profileId = param.id + const [data, setData] = useState([]) + const [activePage, setActivePage] = useState(1) + + async function getPortofolio() { + try { + const response = await apiGetPortofolioByProfile(`?profile=${param.id}&cat=portofolio&page=1`) + if (response.success) { + setData(response.data); + } + } catch (error) { + console.error(error); + } + } + + + useShallowEffect(() => { + getPortofolio() + }, []); + + return <> + + ( +
+ +
+ )} + data={data} + setData={setData} + moreData={async () => { + const loadData = await portofolio_funGetAllDaftarByid({ + profileId, + page: activePage + 1, + }); + setActivePage((val) => val + 1); + + return loadData; + }} + > + {(item) => } +
+
+ ; +} \ No newline at end of file diff --git a/src/app_modules/katalog/portofolio/ui/ui_skeleton_detail_bisnis.tsx b/src/app_modules/katalog/portofolio/ui/ui_skeleton_detail_bisnis.tsx new file mode 100644 index 00000000..b8708f23 --- /dev/null +++ b/src/app_modules/katalog/portofolio/ui/ui_skeleton_detail_bisnis.tsx @@ -0,0 +1,35 @@ +import { Box, Grid, Group, Skeleton, Stack } from "@mantine/core"; + +export default function SkeletonDetailBisnis() { + return <> + + + + + + + + {[...Array(4)].map((_, index) => ( + + + + + + + + + + + ))} + + + + + + + + + + + ; +} \ No newline at end of file diff --git a/src/app_modules/katalog/portofolio/view/list_detail_portofolio_new.tsx b/src/app_modules/katalog/portofolio/view/list_detail_portofolio_new.tsx new file mode 100644 index 00000000..1920461d --- /dev/null +++ b/src/app_modules/katalog/portofolio/view/list_detail_portofolio_new.tsx @@ -0,0 +1,13 @@ +'use client' +import { UIGlobal_LayoutHeaderTamplate, UIGlobal_LayoutTamplate } from "@/app_modules/_global/ui"; +import Portofolio_UiListDetailNew from "../ui/ui_list_detail_portofolio_new"; + +export default function ListDetailPortofolioNew() { + return ( + <> + } > + + + + ) +} \ No newline at end of file diff --git a/src/app_modules/katalog/profile/_component/button/comp_create_new_profile.tsx b/src/app_modules/katalog/profile/_component/button/comp_create_new_profile.tsx index 02bd0b77..d649d346 100644 --- a/src/app_modules/katalog/profile/_component/button/comp_create_new_profile.tsx +++ b/src/app_modules/katalog/profile/_component/button/comp_create_new_profile.tsx @@ -9,13 +9,13 @@ import { ComponentGlobal_NotifikasiGagal, ComponentGlobal_NotifikasiPeringatan, } from "@/app_modules/_global/notif_global"; +import { gmailRegex } from "@/app_modules/katalog/component/regular_expressions"; import { Button } from "@mantine/core"; import _ from "lodash"; import { useRouter } from "next/navigation"; import { useState } from "react"; import funCreateNewProfile from "../../fun/fun_create_profile"; import { MODEL_PROFILE } from "../../model/interface"; -import { validRegex } from "@/app_modules/katalog/component"; export function Profile_ComponentCreateNewProfile({ value, @@ -38,7 +38,8 @@ export function Profile_ComponentCreateNewProfile({ }; if (_.values(newData).includes("")) return ComponentGlobal_NotifikasiPeringatan("Lengkapi Data"); - if (!newData.email.match(validRegex)) return null; + if (!newData.email.match(gmailRegex)) + return ComponentGlobal_NotifikasiPeringatan("Format email salah"); if (filePP == null) return ComponentGlobal_NotifikasiPeringatan("Lengkapi foto profile"); @@ -47,40 +48,45 @@ export function Profile_ComponentCreateNewProfile({ "Lengkapi background profile" ); - setLoading(true); + try { + setLoading(true); - const uploadPhoto = await funGlobal_UploadToStorage({ - file: filePP, - dirId: DIRECTORY_ID.profile_foto, - }); - if (!uploadPhoto.success) { - setLoading(false); - return ComponentGlobal_NotifikasiPeringatan("Gagal upload foto profile"); - } + const uploadPhoto = await funGlobal_UploadToStorage({ + file: filePP, + dirId: DIRECTORY_ID.profile_foto, + }); + if (!uploadPhoto.success) { + setLoading(false); + return ComponentGlobal_NotifikasiPeringatan( + "Gagal upload foto profile" + ); + } - const uploadBackground = await funGlobal_UploadToStorage({ - file: fileBG, - dirId: DIRECTORY_ID.profile_background, - }); - if (!uploadBackground.success) { - setLoading(false); - return ComponentGlobal_NotifikasiPeringatan( - "Gagal upload background profile" - ); - } + const uploadBackground = await funGlobal_UploadToStorage({ + file: fileBG, + dirId: DIRECTORY_ID.profile_background, + }); + if (!uploadBackground.success) { + setLoading(false); + return ComponentGlobal_NotifikasiPeringatan( + "Gagal upload background profile" + ); + } - const create = await funCreateNewProfile({ - data: newData as any, - imageId: uploadPhoto.data.id, - imageBackgroundId: uploadBackground.data.id, - }); - - if (create.status === 201) { - ComponentGlobal_NotifikasiBerhasil("Berhasil membuat profile", 3000); - router.push(RouterHome.main_home, { scroll: false }); - } else { - ComponentGlobal_NotifikasiGagal(create.message); - setLoading(false); + const create = await funCreateNewProfile({ + data: newData as any, + imageId: uploadPhoto.data.id, + imageBackgroundId: uploadBackground.data.id, + }); + if (create.status === 201) { + ComponentGlobal_NotifikasiBerhasil("Berhasil membuat profile", 3000); + router.push(RouterHome.main_home, { scroll: false }); + } else { + ComponentGlobal_NotifikasiGagal(create.message); + setLoading(false); + } + } catch (error) { + console.log(error); } } diff --git a/src/app_modules/katalog/profile/create/view.tsx b/src/app_modules/katalog/profile/create/view.tsx index 0ae5e658..dce45a60 100644 --- a/src/app_modules/katalog/profile/create/view.tsx +++ b/src/app_modules/katalog/profile/create/view.tsx @@ -6,6 +6,8 @@ import { ComponentGlobal_BoxUploadImage, ComponentGlobal_ErrorInput, } from "@/app_modules/_global/component"; +import { MAX_SIZE } from "@/app_modules/_global/lib"; +import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global"; import { AspectRatio, Avatar, @@ -22,7 +24,7 @@ import { } from "@mantine/core"; import { IconAt, IconCamera, IconUpload } from "@tabler/icons-react"; import { useState } from "react"; -import { validRegex } from "../../component"; +import { gmailRegex } from "../../component/regular_expressions"; import { Profile_ComponentCreateNewProfile } from "../_component"; export default function CreateProfile() { @@ -83,8 +85,15 @@ export default function CreateProfile() { const buffer = URL.createObjectURL( new Blob([new Uint8Array(await files.arrayBuffer())]) ); - setImgPP(buffer); - setFilePP(files); + + if (files.size > MAX_SIZE) { + ComponentGlobal_NotifikasiPeringatan( + "Ukuran file terlalu besar. Maksimal 2 MB." + ); + } else { + setImgPP(buffer); + setFilePP(files); + } } catch (error) { console.log(error); } @@ -138,8 +147,15 @@ export default function CreateProfile() { const buffer = URL.createObjectURL( new Blob([new Uint8Array(await files.arrayBuffer())]) ); - setImgBG(buffer); - setFileBG(files); + + if (files.size > MAX_SIZE) { + ComponentGlobal_NotifikasiPeringatan( + "Ukuran file terlalu besar. Maksimal 2 MB." + ); + } else { + setImgBG(buffer); + setFileBG(files); + } } catch (error) { console.log(error); } @@ -189,7 +205,7 @@ export default function CreateProfile() { maxLength={100} placeholder="Contoh: User@gmail.com" error={ - value.email.length > 0 && !value.email.match(validRegex) ? ( + value.email.length > 0 && !value.email.match(gmailRegex) ? ( ) : ( "" diff --git a/src/app_modules/katalog/profile/edit/view.tsx b/src/app_modules/katalog/profile/edit/view.tsx index 8a907706..9b33f424 100644 --- a/src/app_modules/katalog/profile/edit/view.tsx +++ b/src/app_modules/katalog/profile/edit/view.tsx @@ -4,14 +4,14 @@ import { Button, Loader, Select, Stack, TextInput } from "@mantine/core"; import _ from "lodash"; import { useRouter } from "next/navigation"; import { useState } from "react"; - import { MainColor } from "@/app_modules/_global/color/color_pallet"; import ComponentGlobal_ErrorInput from "@/app_modules/_global/component/error_input"; import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil"; import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal"; -import { validRegex } from "../../component/regular_expressions"; +import { gmailRegex, validRegex } from "../../component/regular_expressions"; import { Profile_funEditById } from "../fun/update/fun_edit_profile_by_id"; import { MODEL_PROFILE } from "../model/interface"; +import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global"; export default function EditProfile({ data }: { data: MODEL_PROFILE }) { const router = useRouter(); @@ -24,8 +24,10 @@ export default function EditProfile({ data }: { data: MODEL_PROFILE }) { const body = dataProfile; // console.log(body) - if (_.values(body).includes("")) return null; - if (!body.email.match(validRegex)) return null; + if (_.values(body).includes("")) + return ComponentGlobal_NotifikasiPeringatan("Lengkapi data"); + if (!body.email.match(gmailRegex)) + return ComponentGlobal_NotifikasiPeringatan("Format email salah"); await Profile_funEditById(body).then((res) => { if (res.status === 200) { @@ -126,7 +128,7 @@ export default function EditProfile({ data }: { data: MODEL_PROFILE }) { dataProfile?.email === "" ? ( ) : dataProfile?.email?.length > 0 && - !dataProfile?.email.match(validRegex) ? ( + !dataProfile?.email.match(gmailRegex) ? ( ) : ( "" diff --git a/src/app_modules/katalog/profile/upload/foto_background/index.tsx b/src/app_modules/katalog/profile/upload/foto_background/index.tsx index 12d03b46..559b003c 100644 --- a/src/app_modules/katalog/profile/upload/foto_background/index.tsx +++ b/src/app_modules/katalog/profile/upload/foto_background/index.tsx @@ -30,7 +30,10 @@ export default function Profile_UpdateFotoBackground({ src={ image ? image - : APIs.GET({ fileId: profile.imageBackgroundId as any }) + : APIs.GET({ + fileId: profile.imageBackgroundId as any, + size: "400", + }) } /> diff --git a/src/app_modules/katalog/profile/upload/foto_profile/index.tsx b/src/app_modules/katalog/profile/upload/foto_profile/index.tsx index 6e49f09f..4f1a960e 100644 --- a/src/app_modules/katalog/profile/upload/foto_profile/index.tsx +++ b/src/app_modules/katalog/profile/upload/foto_profile/index.tsx @@ -27,7 +27,11 @@ export default function UploadFotoProfile({ Avatar diff --git a/src/app_modules/katalog/ui/list_portolio_new.tsx b/src/app_modules/katalog/ui/list_portolio_new.tsx new file mode 100644 index 00000000..ff7d96a4 --- /dev/null +++ b/src/app_modules/katalog/ui/list_portolio_new.tsx @@ -0,0 +1,139 @@ +import { AccentColor, MainColor } from "@/app_modules/_global/color"; +import { Box, Center, Group, Paper, Skeleton, Stack, Text, Title } from "@mantine/core"; +import { apiGetPortofolioByProfile, IListPortofolio } from "../portofolio"; +import { useState } from "react"; +import { useParams, useRouter } from "next/navigation"; +import { useShallowEffect } from "@mantine/hooks"; +import _ from "lodash"; +import { RouterPortofolio } from "@/app/lib/router_hipmi/router_katalog"; +import { IconCaretRight } from "@tabler/icons-react"; + +export default function ListPortofolioProfileNew() { + const router = useRouter(); + const param = useParams<{ id: string }>() + const [loading, setLoading] = useState(true) + const [dataPortofolio, setDataPortofolio] = useState([]) + + async function getPortofolio() { + try { + setLoading(true) + const response = await apiGetPortofolioByProfile(`?profile=${param.id}&cat=profile`) + if (response.success) { + setDataPortofolio(response.data); + } + } catch (error) { + console.error(error); + } finally { + setLoading(false) + } + } + + + useShallowEffect(() => { + getPortofolio() + }, []); + + + return ( + <> + + + + Portofolio + + + + { + loading ? + <> + + + + : + + _.isEmpty(dataPortofolio) ? ( +
+ + - Belum Ada Portofolio - + +
+ ) : ( + + {dataPortofolio.map((e, i) => ( + { + router.push(RouterPortofolio.main_detail + e?.id); + }} + style={{ + backgroundColor: MainColor.darkblue, + border: `2px solid ${AccentColor.blue}`, + borderRadius: "10px ", + padding: "15px", + color: "white", + }} + > + + + + {e?.namaBisnis} + + + #{e.id_Portofolio} + + + + + + + + ))} + + ) + } + + { + loading ? <> + : + _.isEmpty(dataPortofolio) ? ( + "" + ) : ( + + + router.push( + RouterPortofolio.daftar_portofolio + param.id, + { scroll: false } + ) + } + fw={"bold"} + fz={"sm"} + > + Lihat semua + + + ) + } +
+
+
+ + ) +} \ No newline at end of file diff --git a/src/app_modules/katalog/ui/profile_detail.tsx b/src/app_modules/katalog/ui/profile_detail.tsx new file mode 100644 index 00000000..e5c4ca20 --- /dev/null +++ b/src/app_modules/katalog/ui/profile_detail.tsx @@ -0,0 +1,131 @@ +import { AccentColor } from "@/app_modules/_global/color"; +import { apiGetUserProfile, IUserProfile } from "@/app_modules/user"; +import { Box, Center, Group, Stack, Text, ThemeIcon } from "@mantine/core"; +import { useShallowEffect } from "@mantine/hooks"; +import { IconBrandGmail, IconGenderFemale, IconGenderMale, IconHome, IconPhone } from "@tabler/icons-react"; +import { useParams } from "next/navigation"; +import { useState } from "react"; +import { Profile_ComponentAvatarProfile, Profile_ComponentLoadBackgroundImage } from "../profile/_component"; +import SkeletonProfile from "./skeleton_profile"; + +export default function ProfileDetail() { + const param = useParams<{ id: string }>() + const [loading, setLoading] = useState(true) + const [dataProfile, setDataProfile] = useState() + const listInformation = [ + { + icon: , + value: "+" + dataProfile?.nomor, + }, + { + icon: , + value: dataProfile?.email, + }, + { + icon: , + value: dataProfile?.alamat, + }, + { + icon: + dataProfile?.jenisKelamin === "Laki-laki" ? ( + + ) : ( + + ), + value: dataProfile?.jenisKelamin, + }, + ]; + + + async function getProfile() { + try { + setLoading(true) + const response = await apiGetUserProfile(`?profile=${param.id}`) + if (response.success) { + setDataProfile(response.data); + } + } catch (error) { + console.error(error); + } finally { + setLoading(false) + } + } + + + useShallowEffect(() => { + getProfile() + }, []); + + return <> + + { + loading ? + : + <> + + + + +
+ +
+ + + {dataProfile?.name} + + + @{dataProfile?.username} + + +
+
+ + + {listInformation.map((e, i) => ( + + + {e.icon} + + + {e?.value} + + + ))} + + + + } +
+ ; +} \ No newline at end of file diff --git a/src/app_modules/katalog/ui/skeleton_profile.tsx b/src/app_modules/katalog/ui/skeleton_profile.tsx new file mode 100644 index 00000000..bc64b0da --- /dev/null +++ b/src/app_modules/katalog/ui/skeleton_profile.tsx @@ -0,0 +1,42 @@ +import { Avatar, Box, Center, Grid, Skeleton, Stack } from "@mantine/core"; + +export default function SkeletonProfile() { + return ( + <> + + + +
+ +
+
+ + + + + + + {[...Array(4)].map((_, index) => ( + + + + + + + + + + + ))} + +
+ + ) +} \ No newline at end of file diff --git a/src/app_modules/katalog/view_katalog_new.tsx b/src/app_modules/katalog/view_katalog_new.tsx new file mode 100644 index 00000000..108e2c93 --- /dev/null +++ b/src/app_modules/katalog/view_katalog_new.tsx @@ -0,0 +1,15 @@ +'use client' +import { Stack } from "@mantine/core"; +import ProfileDetail from "./ui/profile_detail"; +import ListPortofolioProfileNew from "./ui/list_portolio_new"; + +export default function ViewKatalogNew() { + return ( + <> + + + + + + ) +} \ No newline at end of file diff --git a/src/app_modules/map/_component/button/comp_button_save_pin.tsx b/src/app_modules/map/_component/button/comp_button_save_pin.tsx index 8af85a08..40a398d2 100644 --- a/src/app_modules/map/_component/button/comp_button_save_pin.tsx +++ b/src/app_modules/map/_component/button/comp_button_save_pin.tsx @@ -11,6 +11,7 @@ import { useRouter } from "next/navigation"; import { map_funCreatePin } from "../../fun/create/fun_create_pin"; import { DIRECTORY_ID } from "@/app/lib"; import { funGlobal_UploadToStorage } from "@/app_modules/_global/fun"; +import { useState } from "react"; export function ComponentMap_ButtonSavePin({ namePin, @@ -26,7 +27,10 @@ export function ComponentMap_ButtonSavePin({ file: File; }) { const router = useRouter(); + const [loading, setLoading] = useState(false) + async function onSavePin() { + setLoading(true) const uploadFileToStorage = await funGlobal_UploadToStorage({ file: file, dirId: DIRECTORY_ID.map_image, @@ -49,15 +53,19 @@ export function ComponentMap_ButtonSavePin({ res.status === 200 ? (ComponentGlobal_NotifikasiBerhasil(res.message), router.back()) : ComponentGlobal_NotifikasiGagal(res.message); + + setLoading(false) } return ( <> + + + +
+ } + + + + + + +
+ + + ); +} \ No newline at end of file diff --git a/src/app_modules/map/lib/api_map.ts b/src/app_modules/map/lib/api_map.ts new file mode 100644 index 00000000..f0368959 --- /dev/null +++ b/src/app_modules/map/lib/api_map.ts @@ -0,0 +1,9 @@ +export const apiGetAllMap = async (path?: string) => { + const response = await fetch(`/api/new/map${(path) ? path : ''}`) + return await response.json().catch(() => null) +} + +export const apiGetOneMapById = async (path: string) => { + const response = await fetch(`/api/new/map/${path}`); + return await response.json().catch(() => null); +} diff --git a/src/app_modules/map/lib/type_map.ts b/src/app_modules/map/lib/type_map.ts new file mode 100644 index 00000000..f4b21aa6 --- /dev/null +++ b/src/app_modules/map/lib/type_map.ts @@ -0,0 +1,24 @@ +export interface IDataMap { + id: string + namePin: string + latitude: string + longitude: string + pinId: string + logoId: string + imageId: string +} + +export interface IDataMapDetailAuthor { + id: string + name: string + imageId: string +} + +export interface IDataMapDetailBisnis { + id: string + alamatKantor: string + tlpn: string + deskripsi: string + namaBisnis: string + bidangBisnis: string +} \ No newline at end of file diff --git a/src/app_modules/map/ui/ui_map_new.tsx b/src/app_modules/map/ui/ui_map_new.tsx new file mode 100644 index 00000000..2ce61efc --- /dev/null +++ b/src/app_modules/map/ui/ui_map_new.tsx @@ -0,0 +1,123 @@ +"use client"; +import { APIs } from "@/app/lib"; +import { AccentColor } from "@/app_modules/_global/color/color_pallet"; +import ComponentGlobal_IsEmptyData from "@/app_modules/_global/component/is_empty_data"; +import { Avatar, Loader, Stack } from "@mantine/core"; +import { useShallowEffect } from "@mantine/hooks"; +import "mapbox-gl/dist/mapbox-gl.css"; +import { useState } from "react"; +import Map, { AttributionControl, Marker, NavigationControl, ScaleControl, } from "react-map-gl"; +import { ComponentMap_DetailData, ComponentMap_DrawerDetailData } from "../_component"; +import { apiGetAllMap } from "../lib/api_map"; +import { defaultLatLong, defaultMapZoom } from "../lib/default_lat_long"; +import { IDataMap } from "../lib/type_map"; + +export function UiMap_MapBoxViewNew({ mapboxToken, }: { mapboxToken: string }) { + const [mapId, setMapId] = useState(""); + const [openDrawer, setOpenDrawer] = useState(false); + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + + useShallowEffect(() => { + onLoadData(); + }, []); + + async function onLoadData() { + try { + setLoading(true) + const response = await apiGetAllMap() + if (response.success) { + setData(response.data) + } + } catch (error) { + console.error(error) + } finally { + setLoading(false) + } + } + + if (!mapboxToken) + return ; + + return ( + <> + + { + loading ? + + + + : + + {data.map((e, i) => ( + + + { + setMapId(e.id); + setOpenDrawer(true); + }} + > + + + + + ))} + + + + + + } + + + setOpenDrawer(false)} + mapId={mapId} + component={} + /> + + {/* setOpenDrawer(false)} mapId={mapId}/> */} + + ); +} diff --git a/src/app_modules/map/ui/ui_splash.tsx b/src/app_modules/map/ui/ui_splash.tsx index d945b96c..607f58b8 100644 --- a/src/app_modules/map/ui/ui_splash.tsx +++ b/src/app_modules/map/ui/ui_splash.tsx @@ -11,7 +11,7 @@ export function UiMap_SplashView() { useShallowEffect(() => { setTimeout(() => { - router.replace(RouterMap.main_view, { scroll: false }), 1000; + router.replace(RouterMap.main_view, { scroll: false }), 500; }); }, []); return ( diff --git a/src/app_modules/map/view/main_view_new.tsx b/src/app_modules/map/view/main_view_new.tsx new file mode 100644 index 00000000..5c9cfb0a --- /dev/null +++ b/src/app_modules/map/view/main_view_new.tsx @@ -0,0 +1,13 @@ +import UIGlobal_LayoutTamplate from "@/app_modules/_global/ui/ui_layout_tamplate"; +import { ComponentMap_Header } from "../_component"; +import { UiMap_MapBoxViewNew } from "../ui/ui_map_new"; + +export async function Map_ViewNew({ mapboxToken }: { mapboxToken: string }) { + return ( + <> + }> + + + + ); +} diff --git a/src/app_modules/user/index.ts b/src/app_modules/user/index.ts new file mode 100644 index 00000000..8779b5f7 --- /dev/null +++ b/src/app_modules/user/index.ts @@ -0,0 +1,5 @@ +import { IUserProfile } from './lib/type_user'; +import { apiGetUserProfile } from "./lib/api_user"; + +export { apiGetUserProfile }; +export type { IUserProfile }; diff --git a/src/app_modules/user/lib/api_user.ts b/src/app_modules/user/lib/api_user.ts new file mode 100644 index 00000000..7fca1371 --- /dev/null +++ b/src/app_modules/user/lib/api_user.ts @@ -0,0 +1,4 @@ +export const apiGetUserProfile = async (path?: string) => { + const response = await fetch(`/api/new/user${(path) ? path : ''}`) + return await response.json().catch(() => null) +} \ No newline at end of file diff --git a/src/app_modules/user/lib/type_user.ts b/src/app_modules/user/lib/type_user.ts new file mode 100644 index 00000000..2f5a2177 --- /dev/null +++ b/src/app_modules/user/lib/type_user.ts @@ -0,0 +1,14 @@ +export interface IUserProfile { + id: string + username: string + nomor: string + active:boolean + masterUserRoleId: string + idProfile: string + name: string + email: string + alamat: string + jenisKelamin: string + imageId: string + imageBackgroundId: string +} \ No newline at end of file diff --git a/src/app_modules/vote/splash/index.tsx b/src/app_modules/vote/splash/index.tsx index 17a90c19..5a348b18 100644 --- a/src/app_modules/vote/splash/index.tsx +++ b/src/app_modules/vote/splash/index.tsx @@ -24,7 +24,7 @@ export default function Vote_Splash() { setTabsStatus("Publish"); setTabsRiwayat("Semua"); router.replace(RouterVote.beranda); - }, 1000); + }, 500); }, []); return ( diff --git a/src/middleware.ts b/src/middleware.ts index 30cee1e5..f4cd23ab 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -19,8 +19,12 @@ const middlewareConfig: MiddlewareConfig = { userPath: "/dev/home", publicRoutes: [ "/", + "/api/upload", + "/api/validation", "/api/auth/*", "/api/origin-url", + "/api/user", + "/api/event/*", "/login", "/register", "/validasi", @@ -29,6 +33,7 @@ const middlewareConfig: MiddlewareConfig = { "/auth/api/login", "/aset/global/main_background.png", "/aset/logo/logo-hipmi.png", + "/api/new/*" ], encodedKey: process.env.NEXT_PUBLIC_BASE_TOKEN_KEY!, sessionKey: process.env.NEXT_PUBLIC_BASE_SESSION_KEY!,