diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index b8a6ce8..9a702b6 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -59,6 +59,7 @@ model Village {
Project Project[]
Division Division[]
ColorTheme ColorTheme[]
+ BannerImage BannerImage[]
}
model Group {
@@ -481,6 +482,18 @@ model ColorTheme {
updatedAt DateTime @updatedAt
}
+model BannerImage {
+ id String @id @default(cuid())
+ Village Village? @relation(fields: [idVillage], references: [id])
+ idVillage String?
+ title String
+ extension String
+ image String
+ isActive Boolean @default(true)
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+}
+
model Subscription {
id String @id @default(cuid())
data Json
diff --git a/public/icon-192x192.png b/public/icon-192x192.png
index 807489a..4a2d41b 100644
Binary files a/public/icon-192x192.png and b/public/icon-192x192.png differ
diff --git a/public/icon2-192x192.png b/public/icon2-192x192.png
new file mode 100644
index 0000000..807489a
Binary files /dev/null and b/public/icon2-192x192.png differ
diff --git a/src/app/(application)/banner/edit/[id]/page.tsx b/src/app/(application)/banner/edit/[id]/page.tsx
index 6dea5fd..1df7437 100644
--- a/src/app/(application)/banner/edit/[id]/page.tsx
+++ b/src/app/(application)/banner/edit/[id]/page.tsx
@@ -1,3 +1,7 @@
-export default function Page({ params }: { params: { id: string } }) {
- return
Edit Banner
;
+import { EditBanner } from "@/module/banner";
+
+export default function Page() {
+ return (
+
+ );
}
\ No newline at end of file
diff --git a/src/app/(application)/banner/viewfile/page.tsx b/src/app/(application)/banner/viewfile/page.tsx
new file mode 100644
index 0000000..768f17e
--- /dev/null
+++ b/src/app/(application)/banner/viewfile/page.tsx
@@ -0,0 +1,10 @@
+import { ViewfileBanner } from '@/module/banner';
+import React from 'react';
+
+function Page() {
+ return (
+
+ );
+}
+
+export default Page;
diff --git a/src/app/(application)/web-push/page.tsx b/src/app/(application)/web-push/page.tsx
index 24e988c..0162ceb 100644
--- a/src/app/(application)/web-push/page.tsx
+++ b/src/app/(application)/web-push/page.tsx
@@ -2,10 +2,10 @@ import { NotificationManager } from "@/module/_global/components/notification_ma
const publicKey = process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY!;
-console.log(
- process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY,
- process.env.VAPID_PRIVATE_KEY
-);
+// console.log(
+// process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY,
+// process.env.VAPID_PRIVATE_KEY
+// );
export default function Page() {
return (
diff --git a/src/app/api/.gitkeep b/src/app/api/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/src/app/api/banner/[id]/route.ts b/src/app/api/banner/[id]/route.ts
new file mode 100644
index 0000000..22ec8d2
--- /dev/null
+++ b/src/app/api/banner/[id]/route.ts
@@ -0,0 +1,113 @@
+import { DIR, funDeleteFile, funUploadFile, prisma } from "@/module/_global";
+import { funGetUserByCookies } from "@/module/auth";
+import { createLogUser } from "@/module/user";
+import { NextResponse } from "next/server";
+
+
+// GET ONE BANNER
+export async function GET(request: Request, context: { params: { id: string } }) {
+ try {
+ const { id } = context.params;
+ const user = await funGetUserByCookies()
+ if (user.id == undefined) {
+ return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 });
+ }
+
+ const data = await prisma.bannerImage.findUnique({
+ where: {
+ id: String(id)
+ }
+ })
+
+ return NextResponse.json({ success: true, message: "Berhasil mendapatkan banner", data }, { status: 200 });
+ } catch (error) {
+ console.error(error);
+ return NextResponse.json({ success: false, message: "Gagal mendapatkan banner, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
+ }
+}
+
+
+// DELETE BANNER
+export async function DELETE(request: Request, context: { params: { id: string } }) {
+ try {
+ const { id } = context.params;
+ const user = await funGetUserByCookies()
+ if (user.id == undefined) {
+ return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 });
+ }
+
+ const upd = await prisma.bannerImage.update({
+ where: {
+ id: String(id)
+ },
+ data: {
+ isActive: false
+ }
+ })
+
+
+ // create log user
+ const log = await createLogUser({ act: 'DELETE', desc: 'User menghapus banner', table: 'bannerImage', data: id })
+
+ return NextResponse.json({ success: true, message: "Berhasil menghapus banner" }, { status: 200 });
+
+ } catch (error) {
+ console.error(error);
+ return NextResponse.json({ success: false, message: "Gagal menghapus banner, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
+ }
+}
+
+
+// UPDATE BANNER
+export async function PUT(request: Request, context: { params: { id: string } }) {
+ try {
+ const { id } = context.params;
+ const user = await funGetUserByCookies()
+ if (user.id == undefined) {
+ return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 });
+ }
+
+ const body = await request.formData()
+ const file = body.get("file") as File
+ const data = body.get("data")
+ const { title } = JSON.parse(data as string)
+
+
+ const upd = await prisma.bannerImage.update({
+ where: {
+ id: String(id)
+ },
+ data: {
+ title
+ },
+ select: {
+ image: true
+ }
+ })
+
+ if (String(file) != "undefined" && String(file) != "null") {
+ const fExt = file.name.split(".").pop()
+ const fileName = id + '.' + fExt;
+ const newFile = new File([file], fileName, { type: file.type });
+ await funDeleteFile({ fileId: String(upd.image) })
+ const upload = await funUploadFile({ file: newFile, dirId: DIR.banner })
+ await prisma.bannerImage.update({
+ where: {
+ id: id
+ },
+ data: {
+ image: upload.data.id
+ }
+ })
+ }
+
+ // create log user
+ const log = await createLogUser({ act: 'UPDATE', desc: 'User mengupdate data banner', table: 'bannerImage', data: user.id })
+
+ return NextResponse.json({ success: true, message: "Berhasil mengupdate banner" }, { status: 200 });
+
+ } catch (error) {
+ console.error(error);
+ return NextResponse.json({ success: false, message: "Gagal mengupdate banner, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
+ }
+}
\ No newline at end of file
diff --git a/src/app/api/banner/route.ts b/src/app/api/banner/route.ts
new file mode 100644
index 0000000..a8010ae
--- /dev/null
+++ b/src/app/api/banner/route.ts
@@ -0,0 +1,74 @@
+import { DIR, funUploadFile, funViewDir, prisma } from "@/module/_global";
+import { funGetUserByCookies } from "@/module/auth";
+import { createLogUser } from "@/module/user";
+import { NextResponse } from "next/server";
+
+
+// GET ALL BANNER
+export async function GET() {
+ try {
+ const user = await funGetUserByCookies()
+ if (user.id == undefined) {
+ return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 });
+ }
+
+ const data = await prisma.bannerImage.findMany({
+ where: {
+ isActive: true,
+ idVillage: user.idVillage
+ },
+ orderBy: {
+ createdAt: 'desc'
+ }
+ });
+
+ return NextResponse.json({ success: true, message: "Berhasil mendapatkan banner", data }, { status: 200 });
+ } catch (error) {
+ console.error(error);
+ return NextResponse.json({ success: false, message: "Gagal mendapatkan data banner, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
+ }
+}
+
+
+// CREATE BANNER
+export async function POST(request: Request) {
+ try {
+ const user = await funGetUserByCookies()
+ if (user.id == undefined) {
+ return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 });
+ }
+
+ const body = await request.formData()
+ const file = body.get("file") as File;
+ const data = body.get("data");
+
+ const { title } = JSON.parse(data as string)
+
+ const fExt = file.name.split(".").pop()
+ const fName = file.name.replace("." + fExt, "")
+ const newFile = new File([file], file.name, { type: file.type });
+
+ const ini = funViewDir({ dirId: DIR.user })
+ const upload = await funUploadFile({ file: newFile, dirId: DIR.banner })
+ if (upload.success) {
+ const create = await prisma.bannerImage.create({
+ data: {
+ title: title,
+ idVillage: user.idVillage,
+ extension: String(fExt),
+ image: upload.data.id
+ }
+ })
+
+ // create log user
+ const log = await createLogUser({ act: 'CREATE', desc: 'User menambah data banner baru', table: 'bannerImage', data: user.id })
+
+ return Response.json({ success: true, message: 'Sukses menambah data banner' }, { status: 200 });
+ } else {
+ return Response.json({ success: false, message: 'Gagal menambah data banner' }, { status: 200 });
+ }
+ } catch (error) {
+ console.error(error);
+ return NextResponse.json({ success: false, message: "Gagal menambahkan banner, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
+ }
+}
\ No newline at end of file
diff --git a/src/app/api/home/route.ts b/src/app/api/home/route.ts
index a447f50..6f6b3d2 100644
--- a/src/app/api/home/route.ts
+++ b/src/app/api/home/route.ts
@@ -1,6 +1,6 @@
import { prisma } from "@/module/_global";
import { funGetUserByCookies } from "@/module/auth";
-import _, { ceil } from "lodash";
+import _, { ceil, some } from "lodash";
import moment from "moment";
import "moment/locale/id";
import { NextResponse } from "next/server";
@@ -35,11 +35,21 @@ export async function GET(request: Request) {
isActive: true,
}
}
- } else {
+ } else if (roleUser == "admin" || roleUser == "cosupadmin") {
kondisi = {
isActive: true,
idGroup: idGroup
}
+ } else {
+ kondisi = {
+ isActive: true,
+ idGroup: idGroup,
+ ProjectMember: {
+ some: {
+ idUser: user.id
+ }
+ }
+ }
}
const data = await prisma.project.findMany({
@@ -133,17 +143,31 @@ export async function GET(request: Request) {
kondisi = {
isActive: true,
Division: {
+ isActive: true,
idVillage: idVillage,
Group: {
isActive: true,
}
}
}
+ } else if (roleUser == "admin" || roleUser == "cosupadmin") {
+ kondisi = {
+ isActive: true,
+ Division: {
+ isActive: true,
+ idGroup: idGroup
+ }
+ }
} else {
kondisi = {
isActive: true,
Division: {
- idGroup: idGroup
+ isActive: true,
+ DivisionMember: {
+ some: {
+ idUser: user.id
+ }
+ }
}
}
}
@@ -185,18 +209,33 @@ export async function GET(request: Request) {
isActive: true,
category: 'FILE',
Division: {
+ isActive: true,
idVillage: idVillage,
Group: {
isActive: true,
}
}
}
+ } else if (roleUser == "admin" || roleUser == "cosupadmin") {
+ kondisi = {
+ isActive: true,
+ category: 'FILE',
+ Division: {
+ isActive: true,
+ idGroup: idGroup
+ }
+ }
} else {
kondisi = {
isActive: true,
category: 'FILE',
Division: {
- idGroup: idGroup
+ isActive: true,
+ DivisionMember: {
+ some: {
+ idUser: user.id
+ }
+ }
}
}
}
@@ -284,7 +323,7 @@ export async function GET(request: Request) {
dateEnd: true,
createdAt: true,
status: true,
- idDivision:true,
+ idDivision: true,
DivisionCalendar: {
select: {
title: true,
@@ -327,18 +366,33 @@ export async function GET(request: Request) {
isActive: true,
status: 1,
Division: {
+ isActive: true,
idVillage: idVillage,
Group: {
isActive: true,
}
}
}
+ } else if (roleUser == "admin" || roleUser == "cosupadmin") {
+ kondisi = {
+ isActive: true,
+ status: 1,
+ Division: {
+ idGroup: idGroup,
+ isActive: true
+ }
+ }
} else {
kondisi = {
isActive: true,
status: 1,
Division: {
- idGroup: idGroup
+ isActive: true,
+ DivisionMember: {
+ some: {
+ idUser: user.id
+ }
+ }
}
}
}
diff --git a/src/app/api/send-notification/route.ts b/src/app/api/send-notification/route.ts
index 81fc90e..8e6bea9 100644
--- a/src/app/api/send-notification/route.ts
+++ b/src/app/api/send-notification/route.ts
@@ -36,9 +36,9 @@ export async function POST() {
const subscriptionData = sub.data as any;
await webpush.sendNotification(subscriptionData, notificationPayload);
- console.log(
- `Notification sent successfully to ${subscriptionData.endpoint}`
- );
+ // console.log(
+ // `Notification sent successfully to ${subscriptionData.endpoint}`
+ // );
successCount++;
} catch (error: any) {
console.error(
diff --git a/src/app/api/user/route.ts b/src/app/api/user/route.ts
index 6fed7bf..80ea26a 100644
--- a/src/app/api/user/route.ts
+++ b/src/app/api/user/route.ts
@@ -167,7 +167,7 @@ export async function POST(request: Request) {
const cekPhone = await prisma.user.count({
where: {
- phone: data.phone
+ phone: "62" + data.phone
},
});
@@ -177,7 +177,7 @@ export async function POST(request: Request) {
data: {
nik: data.nik,
name: data.name,
- phone: data.phone,
+ phone: "62" + data.phone,
email: data.email,
gender: data.gender,
idGroup: groupFix,
diff --git a/src/module/_global/bin/val_global.ts b/src/module/_global/bin/val_global.ts
index 2442734..906b7d7 100644
--- a/src/module/_global/bin/val_global.ts
+++ b/src/module/_global/bin/val_global.ts
@@ -5,15 +5,16 @@ import { RefObject } from "react";
export const pwd_key_config = "fchgvjknlmdfnbvghhujlaknsdvjbhknlkmsdbdyu567t8y9u30r4587638y9uipkoeghjvuyi89ipkoefmnrjbhtiu4or9ipkoemnjfbhjiuoijdklnjhbviufojkejnshbiuojijknehgruyu"
export const globalRole = hookstate('')
export const DIR = {
+ parentDir: "cm0x8a1as0001bp5te7354yrp",
task: "cm0xhcqf0000dacbbixjb09yn",
project: "cm0xhc9sv000bacbb7rfikw1k",
document: "cm0xhbkf50009acbbtw03qo4l",
village: "cm0xhb91o0007acbbkx8rk8hj",
user: "cm0x8dbwn0005bp5tgmfcthzw",
-
+ banner: "cm1sxex19004938bjvyaq8vta"
}
-export const keyWibu= 'padahariminggukuturutayahkekotanaikdelmanistimewakududukdimuka'
+export const keyWibu = 'padahariminggukuturutayahkekotanaikdelmanistimewakududukdimuka'
export const TEMA = hookstate({
utama: "#19345E",
diff --git a/src/module/_global/fun/view_dir.ts b/src/module/_global/fun/view_dir.ts
new file mode 100644
index 0000000..0005934
--- /dev/null
+++ b/src/module/_global/fun/view_dir.ts
@@ -0,0 +1,22 @@
+export async function funViewDir({ dirId }: { dirId: string }) {
+
+ try {
+ const res = await fetch("https://wibu-storage.wibudev.com/api/dir/" + dirId + "/tree", {
+ method: "GET",
+ 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: {} }
+ }
+}
\ No newline at end of file
diff --git a/src/module/_global/index.ts b/src/module/_global/index.ts
index 0e87f99..d9ee900 100644
--- a/src/module/_global/index.ts
+++ b/src/module/_global/index.ts
@@ -25,6 +25,7 @@ import NotificationCustome from "./components/notification_custome";
import { ScrollProvider } from "./components/scroll_provider";
import SkeletonUser from "./components/skeleton_user";
import SkeletonList from "./components/skeleton_list";
+import { funViewDir } from "./fun/view_dir";
export { WARNA };
export { LayoutLogin };
@@ -59,3 +60,4 @@ export { currentScroll }
export { SkeletonUser }
export { SkeletonList }
export { keyWibu }
+export { funViewDir }
diff --git a/src/module/announcement/ui/create_announcement.tsx b/src/module/announcement/ui/create_announcement.tsx
index 5dbe027..25d72cf 100644
--- a/src/module/announcement/ui/create_announcement.tsx
+++ b/src/module/announcement/ui/create_announcement.tsx
@@ -19,14 +19,13 @@ export default function CreateAnnouncement() {
const memberGroup = useHookstate(globalMemberAnnouncement)
const memberValue = memberGroup.get() as GroupData[]
const [selectedFiles, setSelectedFiles] = useState([])
+ const [loadingKonfirmasi, setLoadingKonfirmasi] = useState(false)
const router = useRouter()
const tema = useHookstate(TEMA)
const [data, setData] = useWibuRealtime({
WIBU_REALTIME_TOKEN: keyWibu,
project: "sdm"
})
-
-
const [isChooseMember, setIsChooseMember] = useState(false)
const [isData, setisData] = useState({
title: "",
@@ -37,8 +36,10 @@ export default function CreateAnnouncement() {
desc: false
});
+
async function onSubmit() {
try {
+ setLoadingKonfirmasi(true)
const response = await funCreateAnnouncement({
title: isData.title,
desc: isData.desc,
@@ -56,9 +57,11 @@ export default function CreateAnnouncement() {
} catch (error) {
console.error(error)
toast.error("Gagal menambahkan pengumuman, coba lagi nanti");
+ } finally {
+ setLoadingKonfirmasi(false)
+ setOpen(false)
}
- setOpen(false)
}
async function loadData() {
@@ -69,18 +72,31 @@ export default function CreateAnnouncement() {
loadData()
}, [])
- function onToChooseMember() {
- setIsChooseMember(true)
- }
-
- if (isChooseMember) return { setIsChooseMember(false) }} />
function onCheck() {
- if (Object.values(touched).some((v) => v == true))
+ const cek = checkAll()
+ if (!cek)
return false
+
+ if (memberValue.length == 0)
+ return toast.error("Error! silahkan pilih divisi")
+
setOpen(true)
}
+ function checkAll() {
+ let nilai = true
+ if (isData.title === "") {
+ setTouched(touched => ({ ...touched, title: true }))
+ nilai = false
+ }
+ if (isData.desc === "") {
+ setTouched(touched => ({ ...touched, desc: true }))
+ nilai = false
+ }
+ return nilai
+ }
+
function onValidation(kategori: string, val: string) {
if (kategori == 'title') {
@@ -100,6 +116,8 @@ export default function CreateAnnouncement() {
}
}
+ if (isChooseMember) return { setIsChooseMember(false) }} />
+
return (
>} />
@@ -151,7 +169,7 @@ export default function CreateAnnouncement() {
padding: 10,
borderRadius: 10
}}
- onClick={() => { onToChooseMember() }}
+ onClick={() => { setIsChooseMember(true) }}
>
Tambah divisi penerima pengumuman
@@ -162,7 +180,7 @@ export default function CreateAnnouncement() {
Divisi Terpilih
{(memberGroup.length === 0) ? (
- Belum ada anggota
+ Belum ada divisi yang dipilih
) : memberGroup.get().map((v: any, i: any) => {
return (
@@ -195,13 +213,14 @@ export default function CreateAnnouncement() {
Simpan
- setOpen(false)}
+ setOpen(false)}
description="Apakah Anda yakin ingin menambahkan data?"
onYes={(val) => {
if (val) {
onSubmit()
+ } else {
+ setOpen(false)
}
- setOpen(false)
}} />
diff --git a/src/module/announcement/ui/create_users_announcement.tsx b/src/module/announcement/ui/create_users_announcement.tsx
index b4c1037..7d2e7e5 100644
--- a/src/module/announcement/ui/create_users_announcement.tsx
+++ b/src/module/announcement/ui/create_users_announcement.tsx
@@ -1,15 +1,16 @@
"use client";
-import { LayoutNavbarNew, TEMA, WARNA } from '@/module/_global';
+import { LayoutNavbarNew, TEMA } from '@/module/_global';
import { funGetGroupDivision } from '@/module/group/lib/api_group';
-import { Box, Button, Divider, Flex, Group, rem, Skeleton, Stack, Text } from '@mantine/core';
-import { useMediaQuery, useShallowEffect } from '@mantine/hooks';
-import React, { useState } from 'react';
-import { FaCheck } from 'react-icons/fa';
-import { GroupData } from '../lib/type_announcement';
import { useHookstate } from '@hookstate/core';
-import { globalMemberAnnouncement } from '../lib/val_announcement';
-import { FaMinus } from 'react-icons/fa6';
+import { ActionIcon, Box, Button, Divider, Group, rem, Skeleton, Stack, Text } from '@mantine/core';
+import { useMediaQuery, useShallowEffect } from '@mantine/hooks';
+import { useState } from 'react';
import toast from 'react-hot-toast';
+import { FaCheck } from 'react-icons/fa';
+import { FaMinus } from 'react-icons/fa6';
+import { HiChevronLeft } from 'react-icons/hi2';
+import { GroupData } from '../lib/type_announcement';
+import { globalMemberAnnouncement } from '../lib/val_announcement';
@@ -112,7 +113,13 @@ export default function CreateUsersAnnouncement({ onClose }: { onClose: (val: an
return (
-
>} />
+
+ { onClose(true) }} bg={tema.get().bgIcon} size="lg" radius="lg" aria-label="Settings">
+
+
+
+ } title="Tambah Divisi Penerima Pengumuman" menu={<>>} />
()
const [loading, setLoading] = useState(true)
@@ -75,6 +75,7 @@ export default function EditAnnouncement() {
toast.error("Gagal mendapatkan pengumuman, coba lagi nanti")
} finally {
setLoading(false)
+ setOpen(false)
}
}
@@ -94,30 +95,24 @@ export default function EditAnnouncement() {
if (response.success) {
toast.success(response.message)
- setLoadingSubmit(false)
router.push(`/announcement/${param.id}`)
} else {
toast.error(response.message)
}
- setLoadingSubmit(false)
} catch (error) {
console.error(error)
toast.error("Gagal mengedit pengumuman, coba lagi nanti");
} finally {
setLoadingSubmit(false)
+ setOpen(false)
}
- setOpen(false)
}
-
-
-
- if (isChooseDivisi) return { setChooseDivisi(false) }} />
-
-
function onCheck() {
if (Object.values(touched).some((v) => v == true))
return false
+ if (memberGroup.get().length == 0)
+ return toast.error("Error! silahkan pilih divisi")
setOpen(true)
}
@@ -140,6 +135,8 @@ export default function EditAnnouncement() {
}
}
+ if (isChooseDivisi) return { setChooseDivisi(false) }} />
+
return (
<>
>} />
@@ -160,7 +157,7 @@ export default function EditAnnouncement() {
:
<>
{
- return (
-
- {v.name}
-
-
-
- {
- v.Division.map((division: any) => {
- return
- {division.name}
-
- })
- }
-
-
-
-
- );
+ <>
+ Divisi Terpilih
+ {
+ memberGroup.get().length == 0 ? Belum ada divisi yang dipilih :
+ memberGroup.get().map((v: any, i: any) => {
+ return (
+
+ {v.name}
+
+
+
+ {
+ v.Division.map((division: any) => {
+ return
+ {division.name}
+
+ })
+ }
+
+
+
+
+ );
+
+ })
+ }
+ >
- }
- )
}
@@ -282,8 +285,9 @@ export default function EditAnnouncement() {
onYes={(val) => {
if (val) {
onSubmit()
+ } else {
+ setOpen(false)
}
- setOpen(false)
}} />
>
)
diff --git a/src/module/announcement/ui/edit_choose_member.tsx b/src/module/announcement/ui/edit_choose_member.tsx
index 5f234d0..642883e 100644
--- a/src/module/announcement/ui/edit_choose_member.tsx
+++ b/src/module/announcement/ui/edit_choose_member.tsx
@@ -1,17 +1,16 @@
"use client";
-import { LayoutNavbarNew, TEMA, WARNA } from '@/module/_global';
+import { LayoutNavbarNew, TEMA } from '@/module/_global';
import { funGetGroupDivision } from '@/module/group/lib/api_group';
-import { Box, Button, Divider, Flex, Group, rem, Skeleton, Stack, Text } from '@mantine/core';
-import { useMediaQuery, useShallowEffect } from '@mantine/hooks';
-import React, { useState } from 'react';
-import { FaCheck } from 'react-icons/fa';
-import { GroupData, GroupDataEditAnnouncement } from '../lib/type_announcement';
import { useHookstate } from '@hookstate/core';
-import { globalMemberEditAnnouncement } from '../lib/val_announcement';
-import { FaMinus } from 'react-icons/fa6';
+import { ActionIcon, Box, Button, Divider, Group, rem, Skeleton, Stack, Text } from '@mantine/core';
+import { useMediaQuery, useShallowEffect } from '@mantine/hooks';
+import { useState } from 'react';
import toast from 'react-hot-toast';
-
-
+import { FaCheck } from 'react-icons/fa';
+import { FaMinus } from 'react-icons/fa6';
+import { HiChevronLeft } from 'react-icons/hi2';
+import { GroupData } from '../lib/type_announcement';
+import { globalMemberEditAnnouncement } from '../lib/val_announcement';
interface CheckedState {
[key: string]: string[];
@@ -111,7 +110,13 @@ export default function EditChooseMember({ onClose }: { onClose: (val: any) => v
return (
-
>} />
+
+ { onClose(true) }} bg={tema.get().bgIcon} size="lg" radius="lg" aria-label="Settings">
+
+
+
+ } title="Tambah Divisi Penerima Pengumuman" menu={<>>} />
{
- if (res.status == 200) {
- setValPhone(cekLogin.phone)
- setOTP(code)
- setUser(cekLogin.id)
- setVerif(true)
- setLoading(false)
- toast.success('Kode verifikasi telah dikirim')
- } else {
- toast.error('Internal Server Error')
- setLoading(false)
+ try {
+ const res = await fetch(`https://wa.wibudev.com/code?nom=${cekLogin.phone}&text=*DARMASABA*%0A%0A
+ JANGAN BERIKAN KODE RAHASIA ini kepada siapa pun TERMASUK PIHAK DARMASABA. Masukkan otentikasi: *${encodeURIComponent(code)}*`).then(
+ async (res) => {
+ if (res.status == 200) {
+ setValPhone(cekLogin.phone)
+ setOTP(code)
+ setUser(cekLogin.id)
+ setVerif(true)
+ setLoading(false)
+ toast.success('Kode verifikasi telah dikirim')
+ } else {
+ console.error(res.status)
+ toast.error('Internal Server Error')
+ setLoading(false)
+ }
}
- }
- )
+ )
+ } catch (error) {
+ console.error(error)
+ toast.error('Internal Server Error')
+ }finally{
+ setLoading(false)
+ }
} else {
return toast.error(cekLogin.message)
}
diff --git a/src/module/auth/varification/view/view_verification.tsx b/src/module/auth/varification/view/view_verification.tsx
index 374c099..d345b4c 100644
--- a/src/module/auth/varification/view/view_verification.tsx
+++ b/src/module/auth/varification/view/view_verification.tsx
@@ -14,26 +14,30 @@ export default function ViewVerification({ phone, otp, user }: IVerification) {
const [isLoading, setLoading] = useState(false)
async function onResend() {
- const code = Math.floor(Math.random() * 1000) + 1000
-
- const res = await fetch(`https://wa.wibudev.com/code?nom=${phone}&text=*DARMASABA*%0A%0A
-JANGAN BERIKAN KODE RAHASIA ini kepada siapa pun TERMASUK PIHAK DARMASABA. Masukkan otentikasi: *${encodeURIComponent(code)}*`)
- .then(
- async (res) => {
- if (res.status == 200) {
- toast.success('Kode verifikasi telah dikirim')
- setOTP(code)
- } else {
- toast.error('Internal Server Error')
+ try {
+ const code = Math.floor(Math.random() * 1000) + 1000
+ const res = await fetch(`https://wa.wibudev.com/code?nom=${phone}&text=*DARMASABA*%0A%0A
+ JANGAN BERIKAN KODE RAHASIA ini kepada siapa pun TERMASUK PIHAK DARMASABA. Masukkan otentikasi: *${encodeURIComponent(code)}*`)
+ .then(
+ async (res) => {
+ if (res.status == 200) {
+ toast.success('Kode verifikasi telah dikirim')
+ setOTP(code)
+ } else {
+ toast.error('Internal Server Error')
+ }
}
- }
- );
+ );
+ } catch (error) {
+ console.error(error)
+ toast.error('Internal Server Error')
+ }
}
async function getVerification() {
setLoading(true)
if (isOTP == inputOTP) {
- const setCookies = await funSetCookies({ user: user })
+ const setCookies: any = await funSetCookies({ user: user })
if (setCookies.success) {
toast.success(setCookies.message)
diff --git a/src/module/banner/index.ts b/src/module/banner/index.ts
index 9b3343f..1aa792a 100644
--- a/src/module/banner/index.ts
+++ b/src/module/banner/index.ts
@@ -1,4 +1,6 @@
import NavbarBanner from "./ui/navbar_banner";
import ListBanner from "./ui/list_banner";
import CreateBanner from "./ui/create_banner";
-export {NavbarBanner, ListBanner, CreateBanner}
\ No newline at end of file
+import EditBanner from "./ui/edit_banner";
+import ViewfileBanner from "./ui/viewfile_banner";
+export { NavbarBanner, ListBanner, CreateBanner, EditBanner, ViewfileBanner }
diff --git a/src/module/banner/lib/api_banner.ts b/src/module/banner/lib/api_banner.ts
new file mode 100644
index 0000000..54dd40a
--- /dev/null
+++ b/src/module/banner/lib/api_banner.ts
@@ -0,0 +1,35 @@
+export const funGetAllBanner = async (path?: string) => {
+ const response = await fetch(`/api/banner${(path) ? path : ''}`, { next: { tags: ['banner'] } });
+ return await response.json().catch(() => null);
+}
+
+export const funDeleteBanner = async (path: string) => {
+ const response = await fetch(`/api/banner/${path}`, {
+ method: "DELETE",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ });
+ return await response.json().catch(() => null);
+};
+
+export const funCreateBanner = async (data: FormData) => {
+ const response = await fetch(`/api/banner`, {
+ method: "POST",
+ body: data,
+ });
+ return await response.json().catch(() => null);
+}
+
+export const funGetOneBanner = async (path: string) => {
+ const response = await fetch(`/api/banner/${path}`)
+ return await response.json().catch(() => null);
+}
+
+export const funEditBanner = async (path: string, data: FormData) => {
+ const response = await fetch(`/api/banner/${path}`, {
+ method: "PUT",
+ body: data,
+ });
+ return await response.json().catch(() => null);
+}
diff --git a/src/module/banner/lib/git.keep b/src/module/banner/lib/git.keep
deleted file mode 100644
index e69de29..0000000
diff --git a/src/module/banner/lib/type_banner.ts b/src/module/banner/lib/type_banner.ts
new file mode 100644
index 0000000..82b03e2
--- /dev/null
+++ b/src/module/banner/lib/type_banner.ts
@@ -0,0 +1,19 @@
+export interface IDataBanner {
+ id: string
+ title: string
+ extension: string
+ image: string
+}[]
+
+export interface IEditDataBanner {
+ id: string
+ title: string
+ extension: string
+ image: string
+}
+export interface ICreateDataBanner {
+ id: string
+ title: string
+ extension: string
+ image: string
+}
diff --git a/src/module/banner/ui/create_banner.tsx b/src/module/banner/ui/create_banner.tsx
index 954cf34..25e938d 100644
--- a/src/module/banner/ui/create_banner.tsx
+++ b/src/module/banner/ui/create_banner.tsx
@@ -1,71 +1,206 @@
'use client'
-import { LayoutNavbarNew, WARNA } from '@/module/_global';
-import { Box, Button, FileInput, Group, Paper, rem, Text, TextInput } from '@mantine/core';
-import { IconUpload, IconPhoto, IconX } from '@tabler/icons-react';
-import { Dropzone, DropzoneProps, IMAGE_MIME_TYPE } from '@mantine/dropzone';
-import React from 'react';
+import { LayoutNavbarNew, TEMA } from '@/module/_global';
+import LayoutModal from '@/module/_global/layout/layout_modal';
+import { useHookstate } from '@hookstate/core';
+import { Box, Button, Group, Image, Paper, rem, Text, TextInput } from '@mantine/core';
+import { Dropzone } from '@mantine/dropzone';
+import { IconPhoto, IconUpload, IconX } from '@tabler/icons-react';
+import _ from 'lodash';
+import { useRouter } from 'next/navigation';
+import { useRef, useState } from 'react';
+import toast from 'react-hot-toast';
+import { funCreateBanner } from '../lib/api_banner';
+import { title } from 'process';
+
+function CreateBanner() {
+ const router = useRouter();
+ const [isModal, setModal] = useState(false);
+ const tema = useHookstate(TEMA)
+ const [loadingKonfirmasi, setLoadingKonfirmasi] = useState(false)
+ const [listData, setListData] = useState({
+ title: "",
+ image: ""
+
+ });
+ const [imgForm, setImgForm] = useState()
+ const openRef = useRef<() => void>(null)
+ const [img, setIMG] = useState()
+ const [touched, setTouched] = useState({
+ title: false,
+ image: false
+ })
+
+
+ function onValidation(kategori: string, val: any) {
+ if (kategori == 'title') {
+ setListData({ ...listData, title: val })
+ if (val === "") {
+ setTouched({ ...touched, title: true })
+ } else {
+ setTouched({ ...touched, title: false })
+ }
+ } else if (kategori == 'image') {
+ if (imgForm) {
+ setTouched({ ...touched, image: false })
+ } else {
+ setTouched({ ...touched, image: true })
+ }
+ }
+ }
+
+
+ async function onSubmit(val: boolean) {
+ if (!imgForm || !listData.title) {
+ toast.error("Mohon lengkapi semua data");
+ }
+ try {
+ setLoadingKonfirmasi(true)
+ const fd = new FormData()
+ fd.append("file", imgForm)
+ fd.append("data", JSON.stringify(
+ {
+ title: listData.title,
+ image: listData.image
+ }
+ ))
+ const res = await funCreateBanner(fd);
+ if (res.success) {
+ toast.success(res.message);
+ router.push('/banner')
+ } else {
+ toast.error(res.message);
+ }
+ setModal(false);
+ } catch (error) {
+ toast.error("Error");
+ } finally {
+ setLoadingKonfirmasi(false)
+ setModal(false);
+ }
+ }
+
+ // async function loadData() {
+ // const
+ // }
-function CreateBanner(props: Partial) {
return (
- >} />
+
console.log('accepted files', files)}
- onReject={(files) => console.log('rejected files', files)}
- maxSize={5 * 1024 ** 2}
- accept={IMAGE_MIME_TYPE}
- {...props}
+ openRef={openRef}
+ onDrop={async (files) => {
+ if (!files || _.isEmpty(files))
+ return toast.error('Tidak ada gambar yang dipilih')
+ const file = files[0]
+ setImgForm(file)
+ const buffer = URL.createObjectURL(new Blob([new Uint8Array(await files[0].arrayBuffer())]))
+ setIMG(buffer)
+ onValidation('image', files[0])
+ }}
+ activateOnClick={false}
+ maxSize={1 * 1024 ** 2}
+ accept={['image/png', 'imagfe/jpeg', 'image/heic']}
+ onReject={(files) => {
+ return toast.error('File yang diizinkan: .png, .jpg, dan .heic dengan ukuran maksimal 1 MB')
+ }}
+ onClick={() => openRef.current?.()}
>
-
-
-
-
-
-
-
-
-
-
-
-
- Upload File
-
-
- File Tidak Boleh Melebihi 500mb
-
-
-
+ {
+ img ?
+
+ :
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Klik Untuk Upload Image
+
+
+ Ukuran Foto Tidak Boleh Lebih Dari 1MB
+
+
+
+ }
+
Judul Banner}
+ label={Judul Banner}
+ value={listData.title}
placeholder='Judul Banner'
+ onChange={(e) => {
+ setListData({ ...listData, title: e.target.value })
+ onValidation('title', e.target.value)
+ }}
styles={{
input: {
- border: `1px solid ${"#D6D8F6"}`,
+ border: `1px solid ${touched.title ? 'red' : "#D6D8F6"}`,
borderRadius: 10,
},
}}
+
+
/>
-
+
+
+
+ setModal(false)}
+ description="Apakah anda yakin ingin menambahkan banner ini?"
+ onYes={(val) => {
+ if (val) {
+ onSubmit(val);
+ } else {
+ setModal(false);
+ }
+ }}
+
+ />
);
}
diff --git a/src/module/banner/ui/edit_banner.tsx b/src/module/banner/ui/edit_banner.tsx
new file mode 100644
index 0000000..411c731
--- /dev/null
+++ b/src/module/banner/ui/edit_banner.tsx
@@ -0,0 +1,188 @@
+'use client'
+import { LayoutNavbarNew, TEMA, WARNA } from '@/module/_global';
+import LayoutModal from '@/module/_global/layout/layout_modal';
+import { useHookstate } from '@hookstate/core';
+import { Box, Button, Image, Paper, rem, TextInput } from '@mantine/core';
+import { Dropzone } from '@mantine/dropzone';
+import { useShallowEffect } from '@mantine/hooks';
+import _ from 'lodash';
+import { useParams, useRouter } from 'next/navigation';
+import { useRef, useState } from 'react';
+import toast from 'react-hot-toast';
+import { funEditBanner, funGetOneBanner } from '../lib/api_banner';
+import { IEditDataBanner } from '../lib/type_banner';
+
+
+export default function EditBanner() {
+ const router = useRouter()
+ const param = useParams<{ id: string }>()
+ const tema = useHookstate(TEMA)
+ const [isModal, setModal] = useState(false)
+ const [data, setData] = useState({
+ id: "",
+ title: "",
+ extension: "",
+ image: "",
+ });
+ const openRef = useRef<() => void>(null)
+ const [img, setIMG] = useState()
+ const [imgForm, setImgForm] = useState()
+ const [loading, setLoading] = useState(false)
+ const [touched, setTouched] = useState({
+ title: false,
+ image: false
+ })
+
+
+ function onValidation(kategori: string, val: any) {
+ if (kategori == 'title') {
+ setData({ ...data, title: val })
+ if (val === "") {
+ setTouched({ ...touched, title: true })
+ } else {
+ setTouched({ ...touched, title: false })
+ }
+ } else if (kategori == 'image') {
+ if (imgForm) {
+ setTouched({ ...touched, image: false })
+ } else {
+ setTouched({ ...touched, image: true })
+ }
+ }
+ }
+
+
+ async function getOneData() {
+ try {
+ const res = await funGetOneBanner(param.id)
+ console.log(res)
+ setData(res.data)
+ setIMG(`https://wibu-storage.wibudev.com/api/files/${res.data.image}`)
+ } catch (error) {
+ console.error(error)
+ }
+ }
+
+ async function onSubmit(val: boolean) {
+ try {
+ setLoading(true)
+ const fd = new FormData()
+ fd.append("file", imgForm)
+ fd.append("data", JSON.stringify(
+ {
+ id: data.id,
+ title: data.title,
+ image: data.image,
+ extension: data.extension
+ }
+ ))
+
+ const res = await funEditBanner(param.id, fd)
+
+ if (res.success) {
+ toast.success(res.message)
+ router.push('/banner')
+ } else {
+ toast.error(res.message)
+ }
+ } catch (error) {
+ toast.error("Error");
+ } finally {
+ setLoading(false)
+ setModal(false)
+ }
+ }
+
+ useShallowEffect(() => {
+ getOneData()
+ }, [])
+
+ return (
+
+ >} />
+
+
+
+ {
+ if (!files || _.isEmpty(files))
+ return toast.error("Tidak Ada Gambar Yang Dipilih")
+ setImgForm(files[0])
+ const buffer = URL.createObjectURL(new Blob([new Uint8Array(await files[0].arrayBuffer())]))
+ setIMG(buffer)
+ onValidation('image', files[0])
+ }}
+ activateOnClick={false}
+ maxSize={1 * 1024 ** 2}
+ accept={['image/png', 'image/jpeg', 'image/heic']}
+ onReject={(files) => {
+ return toast.error('File yang diizinkan: .png, .jpg, dan .heic dengan ukuran maksimal 1 MB')
+ }}
+ onClick={() => openRef.current?.()}
+ >
+
+
+
+
+ {
+ setData({ ...data, title: e.target.value })
+ onValidation('title', e.target.value)
+ }}
+ styles={{
+ input: {
+ border: `1px solid ${touched.title ? 'red' : "#D6D8F6"}`,
+ borderRadius: 10,
+ },
+ }}
+ required
+ size='md'
+ />
+
+
+
+
+ setModal(false)}
+ description="Apakah Anda yakin ingin mengedit banner ini?"
+ onYes={(val) => {
+ if (val) {
+ onSubmit(val)
+ } else {
+ setModal(false)
+ }
+ }}
+ />
+
+
+
+
+ );
+}
+
diff --git a/src/module/banner/ui/list_banner.tsx b/src/module/banner/ui/list_banner.tsx
index 3283170..4d8de51 100644
--- a/src/module/banner/ui/list_banner.tsx
+++ b/src/module/banner/ui/list_banner.tsx
@@ -1,77 +1,237 @@
'use client'
-import { LayoutDrawer, SkeletonSingle, TEMA, WARNA } from '@/module/_global';
+import { currentScroll, LayoutDrawer, LayoutModalViewFile, TEMA, WARNA } from '@/module/_global';
+import LayoutModal from '@/module/_global/layout/layout_modal';
import { useHookstate } from '@hookstate/core';
-import { Anchor, Box, Flex, Group, Image, SimpleGrid, Stack, Text, TextInput } from '@mantine/core';
-import _ from 'lodash';
-import { useRouter } from 'next/navigation';
-import React, { useState } from 'react';
+import { ActionIcon, Anchor, Box, Flex, Group, Image, Paper, SimpleGrid, Stack, Text, TextInput } from '@mantine/core';
+import { useParams, useRouter } from 'next/navigation';
+import { useEffect, useState } from 'react';
import { FaFile, FaPencil, FaTrash } from 'react-icons/fa6';
+import { IDataBanner } from '../lib/type_banner';
+import toast from 'react-hot-toast';
+import { useShallowEffect } from '@mantine/hooks';
+import { funDeleteBanner, funGetAllBanner, funGetOneBanner } from '../lib/api_banner';
import { HiMagnifyingGlass } from 'react-icons/hi2';
-import { IoAddCircle } from 'react-icons/io5';
function ListBanner() {
+ const [isList, setIsList] = useState(false)
const tema = useHookstate(TEMA)
- const [searchQuery, setSearchQuery] = useState('')
- const [loading, setLoading] = useState(true);
- const [isData, setData] = useState([]);
- const [valChoose, setValChoose] = useState("");
const router = useRouter();
-
-
+ const param = useParams<{ id: string }>()
+ const [isOpenModalView, setOpenModalView] = useState(false)
+ const [isOpenModal, setOpenModal] = useState(false)
const [openDrawer, setOpenDrawer] = useState(false);
+ const [idDataStorage, setIdDataStorage] = useState('')
+ const [isExtension, setExtension] = useState('')
+ const [loading, setLoading] = useState(true)
+ const [isData, setData] = useState([])
+ const [idData, setIdData] = useState('')
+ const [isPage, setPage] = useState(1)
+ const [searchQuerry, setSearchQuerry] = useState('')
+ // const { value: containerRef } = useHookstate(currentScroll);
+
+ const handleList = () => {
+ setIsList(!isList)
+ }
+
+ const fetchData = async (loading: boolean) => {
+ try {
+ if (loading)
+ setLoading(true)
+ const response = await funGetAllBanner('?search=' + searchQuerry)
+ if (response.success) {
+ setData(response.data.map((banner: { image: any; }) => ({ ...banner, image: banner.image })));
+ } else {
+ toast.error(response.message)
+ }
+ setLoading(false)
+ } catch (error) {
+ console.error(error)
+ toast.error("Gagal mendapatkan banner, coba lagi nanti");
+ } finally {
+ setLoading(false)
+ }
+ }
+
+ function searchBanner(search: string) {
+ setSearchQuerry(search)
+ setPage(1)
+ }
+
+
+ useShallowEffect(() => {
+ fetchData(true)
+ }, [searchQuerry])
+
+ useShallowEffect(() => {
+ fetchData(false)
+ }, [isPage])
+
+
+ async function onDelete(id: string) {
+ try {
+ const res = await funDeleteBanner(id);
+ if (res.success) {
+ toast.success(res.message)
+ setData(isData.filter((banner) => banner.id !== id));
+ setIdData("")
+ setIdDataStorage("")
+ setOpenDrawer(false)
+ } else {
+ toast.error(res.message);
+ }
+ } catch (error) {
+ console.error(error);
+ toast.error("Gagal menghapus banner, coba lagi nanti");
+ }
+
+ }
+
+
+
return (
-
-
+
+
+ }
+ placeholder='pencarian'
+ value={searchQuerry}
+ onChange={(val) => { searchBanner(val.target.value) }}
+ />
+
+
+
+
- {[...Array(5)].map((_, index) => (
- { setOpenDrawer(true) }}>
- Banner {index + 1}
-
-
+ {isData.map((v, index) => (
+ {
+ setIdData(v.id);
+ setIdDataStorage(v.image);
+ setExtension(v.extension);
+ setOpenDrawer(true)
+ }
+ }
+ style={{
+ width: '100%',
+ maxWidth: 550,
+ height: 85,
+ backgroundColor: 'transparent',
+ border: `1px solid ${tema.get().bgTotalKegiatan}`
+
+ }}>
+
+
+
+
+
+ {v.title}
+
+
+
))}
- setOpenDrawer(false)}
- title={{"Menu"}}
- >
-
-
-
-
-
- Edit
-
-
-
-
-
-
-
- View File
-
-
-
-
-
-
-
- Hapus
-
-
-
-
+
+ setOpenDrawer(false)}>
+
+
+
+ router.push(`/banner/edit/${idData}`)} direction="column" align="center" justify="center" pb={20}>
+
+
+
+
+ Edit
+
+
+
+
+ { setOpenModalView(true) }} direction={"column"} align={"center"} justify={"center"}>
+
+
+
+
+ Lihat File
+
+
+
+ { setOpenModal(true) }} direction={"column"} align={"center"} justify={"center"}>
+
+
+
+
+ Hapus
+
+
+
+
+
+
+ setOpenModal(false)}
+ description='Apakah Anda yakin ingin menghapus banner?'
+ onYes={(val) => {
+ if (val) {
+ onDelete(idData)
+ }
+ setOpenModal(false)
+ }} />
+
+ setOpenModalView(false)} file={idDataStorage} extension={isExtension} fitur="image" />
);
}
-
export default ListBanner;
+
+
+
+
+
+// useEffect(() => {
+// const handleScroll = async () => {
+// if (containerRef && containerRef.current) {
+// const scrollTop = containerRef.current.scrollTop;
+// const containerHeight = containerRef.current.clientHeight;
+// const scrollHeight = containerRef.current.scrollHeight;
+
+// if (scrollTop + containerHeight + 1 >= scrollHeight) {
+// setPage(isPage + 1)
+// }
+// }
+// };
+
+// const container = containerRef?.current;
+// container?.addEventListener("scroll", handleScroll);
+
+// return () => {
+// container?.removeEventListener("scroll", handleScroll);
+// };
+// }, [containerRef, isPage]);
+
diff --git a/src/module/banner/ui/viewfile_banner.tsx b/src/module/banner/ui/viewfile_banner.tsx
new file mode 100644
index 0000000..ea022a3
--- /dev/null
+++ b/src/module/banner/ui/viewfile_banner.tsx
@@ -0,0 +1,13 @@
+import { LayoutNavbarNew } from '@/module/_global';
+import { Box } from '@mantine/core';
+import React from 'react';
+
+function ViewfileBanner() {
+ return (
+
+ >}/>
+
+ );
+}
+
+export default ViewfileBanner;
diff --git a/src/module/calender/ui/create_calender_division_caleder.tsx b/src/module/calender/ui/create_calender_division_caleder.tsx
index 2cfc315..9ec3e2a 100644
--- a/src/module/calender/ui/create_calender_division_caleder.tsx
+++ b/src/module/calender/ui/create_calender_division_caleder.tsx
@@ -1,11 +1,428 @@
-import { Box } from '@mantine/core';
-import React from 'react';
-import NavbarCreateDivisionCalender from './navbar_create_division_calender';
+'use client'
+import { LayoutNavbarNew, TEMA } from '@/module/_global';
+import LayoutModal from '@/module/_global/layout/layout_modal';
+import { useHookstate } from '@hookstate/core';
+import { Avatar, Box, Button, Divider, Grid, Group, rem, Select, SimpleGrid, Stack, Text, Textarea, TextInput } from '@mantine/core';
+import { DateInput, TimeInput } from '@mantine/dates';
+import { useMediaQuery } from '@mantine/hooks';
+import moment from 'moment';
+import { useParams, useRouter } from 'next/navigation';
+import { useState } from 'react';
+import toast from 'react-hot-toast';
+import { IoIosArrowDropright } from 'react-icons/io';
+import { funCreateCalender } from '../lib/api_calender';
+import { IFormMemberCalender } from '../lib/type_calender';
+import { globalCalender } from '../lib/val_calender';
+import CreateUserCalender from './create_user_calender';
export default function CreateCalenderDivisionCaleder() {
+ const [value, setValue] = useState(null);
+ const router = useRouter()
+ const [isModal, setModal] = useState(false)
+ const [loadingModal, setLoadingModal] = useState(false)
+ const member = useHookstate(globalCalender)
+ const memberValue = member.get() as IFormMemberCalender[]
+ const [openMember, setOpenMember] = useState(false)
+ const param = useParams<{ id: string, detail: string }>()
+ const tema = useHookstate(TEMA)
+ const isMobile = useMediaQuery('(max-width: 369px)');
+ const isMobile2 = useMediaQuery("(max-width: 438px)");
+ const [touched, setTouched] = useState({
+ title: false,
+ dateStart: false,
+ timeStart: false,
+ timeEnd: false,
+ repeatEventTyper: false,
+ desc: false,
+ repeatValue: false
+ })
+ const [isData, setData] = useState({
+ idDivision: "",
+ title: "",
+ dateStart: "",
+ timeStart: "",
+ timeEnd: "",
+ linkMeet: "",
+ repeatEventTyper: "",
+ desc: "",
+ repeatValue: "1"
+ })
+
+ async function onSubmit(val: boolean) {
+ try {
+ setLoadingModal(true)
+ const response = await funCreateCalender({
+ idDivision: param.id,
+ title: isData.title,
+ dateStart: isData.dateStart,
+ timeStart: isData.timeStart,
+ timeEnd: isData.timeEnd,
+ linkMeet: isData.linkMeet,
+ repeatEventTyper: isData.repeatEventTyper,
+ desc: isData.desc,
+ repeatValue: isData.repeatValue,
+ member: memberValue
+ })
+
+ if (response.success) {
+ setModal(false)
+ router.push(`/division/${param.id}/calender`)
+ toast.success(response.message)
+ member.set([])
+ } else {
+ toast.error(response.message)
+ setModal(false)
+ }
+ } catch (error) {
+ console.error(error)
+ toast.error("Gagal menambahkan pengumuman, coba lagi nanti");
+ } finally {
+ setModal(false)
+ setLoadingModal(false)
+ }
+ }
+
+ function onCheck() {
+ const cek = checkAll()
+ if (!cek)
+ return false
+
+ if (memberValue.length == 0)
+ return toast.error("Error! silahkan pilih anggota")
+
+ setModal(true)
+ }
+
+ function checkAll() {
+ let nilai = true
+ if (isData.title === "") {
+ setTouched(touched => ({ ...touched, title: true }))
+ nilai = false
+ }
+ if (isData.dateStart === "") {
+ setTouched(touched => ({ ...touched, dateStart: true }))
+ nilai = false
+ }
+ if (isData.timeStart == "") {
+ setTouched(touched => ({ ...touched, timeStart: true }))
+ nilai = false
+ }
+ if (isData.timeEnd == "" || isData.timeStart > isData.timeEnd) {
+ setTouched(touched => ({ ...touched, timeEnd: true }))
+ nilai = false
+ }
+ if (isData.repeatEventTyper == "" || String(isData.repeatEventTyper) == "null") {
+ setTouched(touched => ({ ...touched, repeatEventTyper: true }))
+ nilai = false
+ }
+ if (isData.repeatValue === "" || Number(isData.repeatValue) <= 0) {
+ setTouched(touched => ({ ...touched, repeatValue: true }))
+ nilai = false
+ }
+
+ return nilai
+ }
+
+ function onValidation(kategori: string, val: any) {
+ if (kategori == 'title') {
+ setData({ ...isData, title: val })
+ if (val === "") {
+ setTouched({ ...touched, title: true })
+ } else {
+ setTouched({ ...touched, title: false })
+ }
+ } else if (kategori == 'dateStart') {
+ setValue(val)
+ setData({ ...isData, dateStart: moment(val).format("YYYY-MM-DD") })
+ if (val === "") {
+ setTouched({ ...touched, dateStart: true })
+ } else {
+ setTouched({ ...touched, dateStart: false })
+ }
+ } else if (kategori == 'timeStart') {
+ setData({ ...isData, timeStart: val })
+ if (val == "") {
+ setTouched({ ...touched, timeStart: true })
+ } else {
+ setTouched({ ...touched, timeStart: false })
+ }
+ } else if (kategori == 'timeEnd') {
+ setData({ ...isData, timeEnd: val })
+ if (val == "" || isData.timeStart > val) {
+ setTouched({ ...touched, timeEnd: true })
+ } else {
+ setTouched({ ...touched, timeEnd: false })
+ }
+ } else if (kategori == 'repeatEventTyper') {
+ setData(isData => ({ ...isData, repeatEventTyper: val }))
+ if (val == "once") {
+ setData(isData => ({ ...isData, repeatValue: "1" }))
+ }
+ if (val == "" || String(val) == "null") {
+ setTouched({ ...touched, repeatEventTyper: true })
+ } else {
+ setTouched({ ...touched, repeatEventTyper: false })
+ }
+ } else if (kategori == 'repeatValue') {
+ setData(isData => ({ ...isData, repeatValue: val, }))
+ if (val === "" || Number(val) <= 0) {
+ setTouched(touched => ({ ...touched, repeatValue: true }))
+ } else {
+ setTouched({ ...touched, repeatValue: false })
+ }
+ }
+ }
+
+ if (openMember) return setOpenMember(false)} />
+
return (
-
+
+
+
+ { onValidation('title', event.target.value) }}
+ error={
+ touched.title && (
+ isData.title == "" ? "Nama Acara Tidak Boleh Kosong" : null
+ )
+ }
+ />
+ { onValidation('dateStart', val) }}
+ placeholder="Input Tanggal"
+ label="Tanggal"
+ error={
+ touched.dateStart && (
+ isData.dateStart == "" ? "Tanggal Tidak Boleh Kosong" : null
+ )
+ }
+ />
+
+ onValidation('timeStart', event.target.value)}
+ error={
+ touched.timeStart && (
+ isData.timeStart == "" ? "Waktu Awal Tidak Boleh Kosong" : null
+ )
+ }
+ />
+ onValidation('timeEnd', event.target.value)}
+ error={
+ touched.timeEnd && (
+ isData.timeEnd == "" ? "Waktu Akhir Tidak Boleh Kosong" : null
+ ) ||
+ (isData.timeStart > isData.timeEnd ? "Waktu Akhir Tidak Tepat" : null)
+ }
+ />
+
+ setData({ ...isData, linkMeet: event.target.value })}
+ />
+
+
+
+
+
+ setModal(false)}
+ description="Apakah Anda yakin ingin menambahkan data?"
+ onYes={(val) => {
+ if (val) {
+ onSubmit(val)
+ } else {
+ setModal(false)
+ }
+ }} />
);
-}
+}
\ No newline at end of file
diff --git a/src/module/calender/ui/update_division_calender.tsx b/src/module/calender/ui/update_division_calender.tsx
index 271fac7..9a53bed 100644
--- a/src/module/calender/ui/update_division_calender.tsx
+++ b/src/module/calender/ui/update_division_calender.tsx
@@ -1,21 +1,22 @@
"use client"
import { LayoutNavbarNew, TEMA } from '@/module/_global';
-import { Box, Button, Group, rem, Select, SimpleGrid, Skeleton, Stack, Text, Textarea, TextInput } from '@mantine/core';
-import { DateInput, TimeInput } from '@mantine/dates';
-import React, { useState } from 'react';
-import { useParams, useRouter } from 'next/navigation';
import LayoutModal from '@/module/_global/layout/layout_modal';
-import toast from 'react-hot-toast';
-import { funEditCalenderById, funGetOneCalender, funGetOneCalenderByIdCalendar, } from '../lib/api_calender';
+import { useHookstate } from '@hookstate/core';
+import { Box, Button, Group, rem, Select, SimpleGrid, Skeleton, Stack, Textarea, TextInput } from '@mantine/core';
+import { DateInput, TimeInput } from '@mantine/dates';
import { useShallowEffect } from '@mantine/hooks';
-import { IDetailByIdCalender } from '../lib/type_calender';
import moment from 'moment';
import "moment/locale/id";
+import { useParams, useRouter } from 'next/navigation';
+import { useState } from 'react';
+import toast from 'react-hot-toast';
+import { funEditCalenderById, funGetOneCalenderByIdCalendar } from '../lib/api_calender';
+import { IDetailByIdCalender } from '../lib/type_calender';
import UpdateListUsers from './update_list_users';
-import { useHookstate } from '@hookstate/core';
export default function UpdateDivisionCalender() {
const [isModal, setModal] = useState(false)
+ const [loadingModal, setLoadingModal] = useState(false)
const param = useParams<{ id: string, detail: string }>()
const [isDataCalender, setDataCalender] = useState()
const [openMember, setOpenMember] = useState(false)
@@ -54,35 +55,89 @@ export default function UpdateDivisionCalender() {
const [value, setValue] = useState(null);
const router = useRouter()
- async function onSubmit(val: boolean) {
- try {
- if (val) {
- const response = await funEditCalenderById(param.detail, {
- title: isDataCalender?.title,
- dateStart: isDataCalender?.dateStart,
- timeStart: isDataCalender?.timeStart,
- timeEnd: isDataCalender?.timeEnd,
- linkMeet: isDataCalender?.linkMeet,
- repeatEventTyper: isDataCalender?.repeatEventTyper,
- desc: isDataCalender?.desc,
- repeatValue: isDataCalender?.repeatValue
- })
- if (response.success) {
- setModal(false)
- router.push(`/division/${param.id}/calender`)
- toast.success(response.message)
- } else {
- toast.error(response.message)
- }
+ function onCheck() {
+ if (Object.values(touched).some((v) => v == true))
+ return false
+ setModal(true)
+ }
+
+ async function onSubmit() {
+ try {
+ setLoadingModal(true)
+ const response = await funEditCalenderById(param.detail, {
+ title: isDataCalender?.title,
+ dateStart: isDataCalender?.dateStart,
+ timeStart: isDataCalender?.timeStart,
+ timeEnd: isDataCalender?.timeEnd,
+ linkMeet: isDataCalender?.linkMeet,
+ repeatEventTyper: isDataCalender?.repeatEventTyper,
+ desc: isDataCalender?.desc,
+ repeatValue: isDataCalender?.repeatValue
+ })
+
+ if (response.success) {
+ router.push(`/division/${param.id}/calender`)
+ toast.success(response.message)
+ } else {
+ toast.error(response.message)
}
- setModal(false)
} catch (error) {
console.error(error)
toast.error("Terjadi kesalahan! Silahkan coba kembali");
- setModal(false)
} finally {
setModal(false)
+ setLoadingModal(false)
+ }
+ }
+
+ function onValidation(kategori: string, val: any) {
+ if (kategori == 'title') {
+ setDataCalender({ ...isDataCalender, title: val })
+ if (val === "") {
+ setTouched({ ...touched, title: true })
+ } else {
+ setTouched({ ...touched, title: false })
+ }
+ } else if (kategori == 'dateStart') {
+ setValue(val)
+ setDataCalender({ ...isDataCalender, dateStart: moment(val).format("YYYY-MM-DD") })
+ if (val === "") {
+ setTouched({ ...touched, dateStart: true })
+ } else {
+ setTouched({ ...touched, dateStart: false })
+ }
+ } else if (kategori == 'timeStart') {
+ setDataCalender({ ...isDataCalender, timeStart: val })
+ if (val == "") {
+ setTouched({ ...touched, timeStart: true })
+ } else {
+ setTouched({ ...touched, timeStart: false })
+ }
+ } else if (kategori == 'timeEnd') {
+ setDataCalender({ ...isDataCalender, timeEnd: val })
+ if (val == "" || String(isDataCalender?.timeStart) > String(val)) {
+ setTouched({ ...touched, timeEnd: true })
+ } else {
+ setTouched({ ...touched, timeEnd: false })
+ }
+ } else if (kategori == 'repeatEventTyper') {
+ setDataCalender(isDataCalender => ({ ...isDataCalender, repeatEventTyper: val }))
+ if (val == "once") {
+ setDataCalender(isDataCalender => ({ ...isDataCalender, repeatValue: "1" }))
+ }
+ if (val == "" || String(val) == "null") {
+ setTouched({ ...touched, repeatEventTyper: true })
+ } else {
+ setTouched({ ...touched, repeatEventTyper: false })
+ }
+ } else if (kategori == 'repeatValue') {
+ setDataCalender(isDataCalender => ({ ...isDataCalender, repeatValue: val, }))
+ if (val === "" || Number(val) <= 0) {
+ setTouched(touched => ({ ...touched, repeatValue: true }))
+ } else {
+ setTouched({ ...touched, repeatValue: false })
+ }
}
}
@@ -117,16 +172,7 @@ export default function UpdateDivisionCalender() {
placeholder="Acara"
label="Acara"
defaultValue={isDataCalender?.title}
- onChange={
- (event) => {
- setDataCalender({
- ...isDataCalender,
- title: event.target.value
- })
- setTouched({ ...touched, title: false })
- }
- }
- onBlur={() => setTouched({ ...touched, title: true })}
+ onChange={(event) => { onValidation('title', event.target.value) }}
required
error={
touched.title && (
@@ -145,20 +191,10 @@ export default function UpdateDivisionCalender() {
value={
(isDataCalender?.dateStart == '' || isDataCalender?.dateStart == null) ? null : new Date(isDataCalender.dateStart)
}
- onChange={
- (val) => {
- setValue(val);
- setDataCalender({
- ...isDataCalender,
- dateStart: moment(val).format("YYYY-MM-DD")
- })
- setTouched({ ...touched, dateStart: false })
- }
- }
+ onChange={(val) => { onValidation('dateStart', val) }}
placeholder="Input Tanggal"
label="Tanggal"
minDate={new Date()}
- onBlur={() => setTouched({ ...touched, dateStart: true })}
error={
touched.dateStart && (
isDataCalender?.dateStart == "" ? "Tanggal Tidak Boleh Kosong" : null
@@ -178,17 +214,8 @@ export default function UpdateDivisionCalender() {
}}
size="md"
label="Waktu Awal"
- // value={isDataCalender?.timeStart}
defaultValue={isDataCalender?.timeStart}
- onChange={
- (event) => {
- setDataCalender({
- ...isDataCalender,
- timeStart: event.target.value
- })
- }
- }
- onBlur={() => setTouched({ ...touched, timeStart: true })}
+ onChange={(event) => { onValidation('timeStart', event.target.value) }}
error={touched.timeStart && !isDataCalender?.timeStart ? "Waktu Awal Tidak Boleh Kosong" : null}
required
/>
@@ -201,17 +228,8 @@ export default function UpdateDivisionCalender() {
}}
size="md"
label="Waktu Akhir"
- // value={isDataCalender?.timeEnd}
defaultValue={isDataCalender?.timeEnd}
- onChange={
- (event) => {
- setDataCalender({
- ...isDataCalender,
- timeEnd: event.target.value
- })
- }
- }
- onBlur={() => setTouched({ ...touched, timeEnd: true })}
+ onChange={(event) => { onValidation('timeEnd', event.target.value) }}
required
error={
touched.timeEnd && (
@@ -232,14 +250,7 @@ export default function UpdateDivisionCalender() {
placeholder="Link Meet"
label="Link Meet"
defaultValue={isDataCalender?.linkMeet}
- onChange={
- (event) => {
- setDataCalender({
- ...isDataCalender,
- linkMeet: event.target.value
- })
- }
- }
+ onChange={(event) => { setDataCalender({ ...isDataCalender, linkMeet: event.target.value }) }}
/>
- setModal(false)}
+ setModal(false)}
description="Apakah Anda yakin ingin mengubah data acara ini? Data ini akan mempengaruhi semua data yang terkait"
- onYes={(val) => { onSubmit(val) }} />
+ onYes={(val) => {
+ if (val) {
+ onSubmit()
+ } else {
+ setModal(false)
+ }
+ }} />
);
}
diff --git a/src/module/color_palette/ui/create_palette_color.tsx b/src/module/color_palette/ui/create_palette_color.tsx
index 0842d0d..2c10d8b 100644
--- a/src/module/color_palette/ui/create_palette_color.tsx
+++ b/src/module/color_palette/ui/create_palette_color.tsx
@@ -1,13 +1,12 @@
"use client"
import { LayoutNavbarNew, TEMA } from '@/module/_global';
-import { useHookstate } from '@hookstate/core';
-import { Badge, Box, Button, Center, ColorInput, Flex, Pill, rem, SimpleGrid, Stack, Text, TextInput } from '@mantine/core';
-import React, { useState } from 'react';
-import { funCreateTheme } from '../lib/api_theme';
-import toast from 'react-hot-toast';
-import { useRouter } from 'next/navigation';
import LayoutModal from '@/module/_global/layout/layout_modal';
-import _ from 'lodash';
+import { useHookstate } from '@hookstate/core';
+import { Box, Button, Center, ColorInput, Flex, Pill, rem, SimpleGrid, Stack, TextInput } from '@mantine/core';
+import { useRouter } from 'next/navigation';
+import { useState } from 'react';
+import toast from 'react-hot-toast';
+import { funCreateTheme } from '../lib/api_theme';
export default function CreatePaletteColor() {
const [isValModal, setValModal] = useState(false);
@@ -56,11 +55,46 @@ export default function CreatePaletteColor() {
}
function onCheck() {
- if (Object.values(touched).some((v) => v == true))
+ const cek = checkAll()
+ if (!cek)
return false
setValModal(true)
}
+ function checkAll() {
+ let nilai = true
+ if (isWarna.name === "") {
+ setTouched(touched => ({ ...touched, name: true }))
+ nilai = false
+ }
+ if (isWarna.utama === "" || isWarna.utama.substring(0, 1) !== '#') {
+ setTouched(touched => ({ ...touched, utama: true }))
+ nilai = false
+ }
+ if (isWarna.bgUtama === "" || isWarna.bgUtama.substring(0, 1) !== '#') {
+ setTouched(touched => ({ ...touched, bgUtama: true }))
+ nilai = false
+ }
+ if (isWarna.bgIcon === "" || isWarna.bgIcon.substring(0, 1) !== '#') {
+ setTouched(touched => ({ ...touched, bgIcon: true }))
+ nilai = false
+ }
+ if (isWarna.bgFiturHome === "" || isWarna.bgFiturHome.substring(0, 1) !== '#') {
+ setTouched(touched => ({ ...touched, bgFiturHome: true }))
+ nilai = false
+ }
+ if (isWarna.bgFiturDivision === "" || isWarna.bgFiturDivision.substring(0, 1) !== '#') {
+ setTouched(touched => ({ ...touched, bgFiturDivision: true }))
+ nilai = false
+ }
+ if (isWarna.bgTotalKegiatan === "" || isWarna.bgTotalKegiatan.substring(0, 1) !== '#') {
+ setTouched(touched => ({ ...touched, bgTotalKegiatan: true }))
+ nilai = false
+ }
+
+ return nilai
+ }
+
function onValidation(kategori: string, val: string) {
if (kategori == 'name') {
setWarna({ ...isWarna, name: val })
@@ -239,8 +273,8 @@ export default function CreatePaletteColor() {
}
error={
touched.bgTotalKegiatan && (
- isWarna.bgTotalKegiatan == "" ? "Background Total Kegiatan Tidak Boleh Kosong" :
- isWarna.bgTotalKegiatan.substring(0, 1) != "#" ? "Kode Warna Tidak Valid" : null
+ isWarna.bgTotalKegiatan == "" ? "Background Total Kegiatan Tidak Boleh Kosong" :
+ isWarna.bgTotalKegiatan.substring(0, 1) != "#" ? "Kode Warna Tidak Valid" : null
)
}
/>
diff --git a/src/module/color_palette/ui/edit_palette_color.tsx b/src/module/color_palette/ui/edit_palette_color.tsx
index 087f620..5f6da1b 100644
--- a/src/module/color_palette/ui/edit_palette_color.tsx
+++ b/src/module/color_palette/ui/edit_palette_color.tsx
@@ -1,14 +1,14 @@
"use client"
import { LayoutNavbarNew, TEMA } from '@/module/_global';
+import LayoutModal from "@/module/_global/layout/layout_modal";
import { useHookstate } from '@hookstate/core';
-import { Badge, Box, Button, Center, ColorInput, Flex, Pill, rem, SimpleGrid, Skeleton, Stack, Text, TextInput } from '@mantine/core';
-import React, { useState } from 'react';
-import { IEditTheme } from '../lib/type_theme';
+import { Box, Button, Center, ColorInput, Flex, Pill, rem, SimpleGrid, Skeleton, Stack, TextInput } from '@mantine/core';
+import { useShallowEffect } from '@mantine/hooks';
+import { useParams, useRouter } from 'next/navigation';
+import { useState } from 'react';
import toast from 'react-hot-toast';
import { funEditTheme, funGetThemeById } from '../lib/api_theme';
-import { useParams, useRouter } from 'next/navigation';
-import { useShallowEffect } from '@mantine/hooks';
-import LayoutModal from "@/module/_global/layout/layout_modal";
+import { IEditTheme } from '../lib/type_theme';
export default function EditPaletteColor() {
const tema = useHookstate(TEMA)
@@ -16,6 +16,7 @@ export default function EditPaletteColor() {
const [isModal, setModal] = useState(false)
const param = useParams<{ id: string }>()
const [loading, setLoading] = useState(true)
+ const [loadingKonfirmasi, setLoadingKonfirmasi] = useState(false);
const [touched, setTouched] = useState({
name: false,
utama: false,
@@ -62,6 +63,7 @@ export default function EditPaletteColor() {
async function onSubmit() {
try {
+ setLoadingKonfirmasi(true)
const res = await funEditTheme(param.id, isWarna)
if (res.success) {
toast.success(res.message);
@@ -72,6 +74,9 @@ export default function EditPaletteColor() {
} catch (error) {
console.error(error)
toast.error("Gagal mengedit tema, coba lagi nanti");
+ } finally {
+ setLoadingKonfirmasi(false)
+ setModal(false)
}
}
@@ -381,11 +386,13 @@ export default function EditPaletteColor() {
- setModal(false)} description="Apakah Anda yakin ingin mengubah data?"
+ setModal(false)} description="Apakah Anda yakin ingin mengubah data?"
onYes={(val) => {
- if (val)
+ if (val) {
onSubmit()
- setModal(false)
+ } else {
+ setModal(false)
+ }
}
} />
diff --git a/src/module/discussion/ui/form_create_discussion.tsx b/src/module/discussion/ui/form_create_discussion.tsx
index 1aa8245..e53f844 100644
--- a/src/module/discussion/ui/form_create_discussion.tsx
+++ b/src/module/discussion/ui/form_create_discussion.tsx
@@ -13,6 +13,7 @@ import { funCreateDiscussion } from "../lib/api_discussion";
export default function FormCreateDiscussion({ id }: { id: string }) {
const [isValModal, setValModal] = useState(false)
+ const [loadingModal, setLoadingModal] = useState(false)
const router = useRouter()
const [isImg, setImg] = useState("")
const param = useParams<{ id: string, detail: string }>()
@@ -50,26 +51,25 @@ export default function FormCreateDiscussion({ id }: { id: string }) {
async function createDiscussion(val: boolean) {
try {
- if (val) {
- const response = await funCreateDiscussion({
- desc: isData.desc,
- idDivision: id
- })
+ setLoadingModal(true)
+ const response = await funCreateDiscussion({
+ desc: isData.desc,
+ idDivision: id
+ })
- if (response.success) {
- setDataRealtime(response.notif)
- toast.success(response.message)
- router.push(`/division/${param.id}/discussion/`)
- setValModal(false)
- } else {
- toast.error(response.message)
- }
+ if (response.success) {
+ setDataRealtime(response.notif)
+ toast.success(response.message)
+ router.push(`/division/${param.id}/discussion/`)
+ } else {
+ toast.error(response.message)
}
} catch (error) {
console.error(error);
toast.error("Gagal menambahkan diskusi, coba lagi nanti");
} finally {
setValModal(false)
+ setLoadingModal(false)
}
}
@@ -94,12 +94,12 @@ export default function FormCreateDiscussion({ id }: { id: string }) {
}}
value={isData.desc}
onChange={(e) => setData({ ...isData, desc: e.target.value })}
- onBlur={() => setTouched({ ...touched, desc: true })}
- error={
- touched.desc && (
- isData.desc == "" ? "Form Tidak Boleh Kosong" : null
- )
- }
+ // onBlur={() => setTouched({ ...touched, desc: true })}
+ // error={
+ // touched.desc && (
+ // isData.desc == "" ? "Form Tidak Boleh Kosong" : null
+ // )
+ // }
/>
@@ -130,9 +130,11 @@ export default function FormCreateDiscussion({ id }: { id: string }) {
- setValModal(false)}
+ setValModal(false)}
description="Apakah Anda yakin ingin menambah data?"
- onYes={(val) => { createDiscussion(val) }} />
+ onYes={(val) => {
+ createDiscussion(val)
+ }} />
)
}
\ No newline at end of file
diff --git a/src/module/discussion/ui/form_edit_discussion.tsx b/src/module/discussion/ui/form_edit_discussion.tsx
index e40967f..66cf5d7 100644
--- a/src/module/discussion/ui/form_edit_discussion.tsx
+++ b/src/module/discussion/ui/form_edit_discussion.tsx
@@ -12,6 +12,7 @@ import { useHookstate } from "@hookstate/core"
export default function FormEditDiscussion() {
const [isValModal, setValModal] = useState(false)
+ const [loadingModal, setLoadingModal] = useState(false)
const router = useRouter()
const param = useParams<{ id: string, detail: string }>()
const [isDataOne, setDataOne] = useState("")
@@ -35,43 +36,43 @@ export default function FormEditDiscussion() {
}
}
- async function fetchEditDiscussion(val: boolean) {
+ async function fetchEditDiscussion() {
try {
- if (val) {
- const response = await funEditDiscussion(param.detail, {
- desc: isDataOne
- })
- if (response.success) {
- toast.success(response.message)
- setValModal(false)
- router.push(`/division/${param.id}/discussion/${param.detail}`)
- } else {
- toast.error(response.message)
- }
+ setLoadingModal(true)
+ const response = await funEditDiscussion(param.detail, {
+ desc: isDataOne
+ })
+ if (response.success) {
+ toast.success(response.message)
+ setValModal(false)
+ router.push(`/division/${param.id}/discussion/${param.detail}`)
+ } else {
+ toast.error(response.message)
}
- setValModal(false)
+
} catch (error) {
console.error(error);
setValModal(false)
toast.error("Gagal menambahkan diskusi, coba lagi nanti");
} finally {
setValModal(false)
+ setLoadingModal(false)
}
}
async function getData() {
try {
- setLoading(true)
- const res = await funGetProfileByCookies()
- setIMG(`https://wibu-storage.wibudev.com/api/files/${res.data.img}`)
- setLoading(false)
+ setLoading(true)
+ const res = await funGetProfileByCookies()
+ setIMG(`https://wibu-storage.wibudev.com/api/files/${res.data.img}`)
+ setLoading(false)
} catch (error) {
- console.error(error);
+ console.error(error);
} finally {
- setLoading(false)
+ setLoading(false)
}
- }
-
+ }
+
useShallowEffect(() => {
fetchGetOneDiscussion()
getData()
@@ -84,43 +85,43 @@ export default function FormEditDiscussion() {
- {loading ?
-
- :
-
- }
+ {loading ?
+
+ :
+
+ }
{loading ?
- Array(10)
- .fill(null)
- .map((_, i) => (
-
-
-
- ))
- :
-
-
- }
+ Array(10)
+ .fill(null)
+ .map((_, i) => (
+
+
+
+ ))
+ :
+
+
+ }
@@ -153,9 +154,15 @@ export default function FormEditDiscussion() {
}
- setValModal(false)}
+ setValModal(false)}
description="Apakah Anda yakin ingin mengubah data?"
- onYes={(val) => { fetchEditDiscussion(val) }} />
+ onYes={(val) => {
+ if (val) {
+ fetchEditDiscussion()
+ } else {
+ setValModal(false)
+ }
+ }} />
)
}
\ No newline at end of file
diff --git a/src/module/division_new/ui/create_division.tsx b/src/module/division_new/ui/create_division.tsx
index 6618c5a..4cfab78 100644
--- a/src/module/division_new/ui/create_division.tsx
+++ b/src/module/division_new/ui/create_division.tsx
@@ -1,29 +1,15 @@
"use client";
import { LayoutNavbarNew, TEMA } from "@/module/_global";
-import { useHookstate } from "@hookstate/core";
-import {
- Avatar,
- Box,
- Button,
- Divider,
- Flex,
- Grid,
- Group,
- rem,
- Select,
- Stack,
- Text,
- Textarea,
- TextInput,
-} from "@mantine/core";
-import { useMediaQuery, useShallowEffect } from "@mantine/hooks";
-import { useRouter } from "next/navigation";
-import React, { useState } from "react";
-import { IoIosArrowDropright } from "react-icons/io";
-import { globalMemberDivision } from "../lib/val_division";
-import toast from "react-hot-toast";
import { funGetUserByCookies } from "@/module/auth";
import { funGetAllGroup, IDataGroup } from "@/module/group";
+import { useHookstate } from "@hookstate/core";
+import { Avatar, Box, Button, Divider, Grid, Group, rem, Select, Stack, Text, Textarea, TextInput } from "@mantine/core";
+import { useMediaQuery, useShallowEffect } from "@mantine/hooks";
+import { useRouter } from "next/navigation";
+import { useState } from "react";
+import toast from "react-hot-toast";
+import { IoIosArrowDropright } from "react-icons/io";
+import { globalMemberDivision } from "../lib/val_division";
import NavbarAdminDivision from "./navbar_admin_division";
import NavbarCreateUsers from "./navbar_create_users";
@@ -58,23 +44,14 @@ export default function CreateDivision() {
setRoleUser(loadUser.idUserRole)
}
- function onSubmit() {
- if (roleUser == "supadmin" && (body.idGroup == "" || body.idGroup == null)) {
- return toast.error("Error! grup harus diisi")
- }
-
- if (body.name == "") {
- return toast.error("Error! nama divisi harus diisi")
- }
-
- if (member.length == 0) {
+ function onCheck() {
+ const cek = checkAll()
+ if (!cek)
+ return false
+ if (member.length == 0)
return toast.error("Error! belum ada anggota yang terdaftar")
- }
-
-
setChooseAdmin(true)
-
}
function onToChooseAnggota() {
@@ -86,7 +63,7 @@ export default function CreateDivision() {
function onChooseGroup(val: any) {
member.set([])
- setBody({ ...body, idGroup: val })
+ onValidation('idGroup', val)
}
@@ -95,6 +72,39 @@ export default function CreateDivision() {
loadData();
}, []);
+ function onValidation(kategori: string, val: any) {
+ if (kategori == 'name') {
+ setBody({ ...body, name: val })
+ if (val === "") {
+ setTouched({ ...touched, name: true })
+ } else {
+ setTouched({ ...touched, name: false })
+ }
+ } else if (kategori == 'idGroup') {
+ setBody({ ...body, idGroup: val, })
+ if (val === "" || String(val) == "null") {
+ setTouched(touched => ({ ...touched, idGroup: true }))
+ } else {
+ setTouched({ ...touched, idGroup: false })
+ }
+ } else if (kategori == 'desc') {
+ setBody({ ...body, desc: val })
+ }
+ }
+
+ function checkAll() {
+ let nilai = true
+ if (roleUser == "supadmin" && (body.idGroup === "" || String(body.idGroup) == "null")) {
+ setTouched(touched => ({ ...touched, idGroup: true }))
+ nilai = false
+ }
+ if (body.name === "") {
+ setTouched(touched => ({ ...touched, name: true }))
+ nilai = false
+ }
+ return nilai
+ }
+
if (isChooseAdmin) return {
@@ -133,10 +143,9 @@ export default function CreateDivision() {
onChange={(val) => {
onChooseGroup(val)
}}
- onBlur={() => setTouched({ ...touched, idGroup: true })}
error={
touched.idGroup && (
- body.idGroup == "" ? "Grup Tidak Boleh Kosong" : null
+ body.idGroup == "" || String(body.idGroup) == "null" ? "Grup Tidak Boleh Kosong" : null
)
}
value={body.idGroup}
@@ -150,11 +159,10 @@ export default function CreateDivision() {
required
radius={10}
value={body.name}
- onChange={(val) => { setBody({ ...body, name: val.target.value }) }}
- onBlur={() => setTouched({ ...touched, name: true })}
+ onChange={(val) => { onValidation('name', val.target.value) }}
error={
touched.name && (
- body.name == "" ? "Nama Tidak Boleh Kosong" : null
+ body.name == "" ? "Nama Divisi Tidak Boleh Kosong" : null
)
}
/>
@@ -230,16 +238,7 @@ export default function CreateDivision() {
zIndex: 999,
backgroundColor: `${tema.get().bgUtama}`,
}}>
-
}
- setOpenModal(false)} description='Apakah Anda yakin ingin edit data'
+ setOpenModal(false)} description='Apakah Anda yakin ingin edit data'
onYes={(val) => {
if (val) {
onUpdate()
diff --git a/src/module/division_new/ui/information_division.tsx b/src/module/division_new/ui/information_division.tsx
index 9c8119e..f5d17fa 100644
--- a/src/module/division_new/ui/information_division.tsx
+++ b/src/module/division_new/ui/information_division.tsx
@@ -135,9 +135,9 @@ export default function InformationDivision() {
))
:
- (deskripsi != null && deskripsi != undefined) ?
+ (deskripsi != null && deskripsi != undefined && deskripsi != "") ?
{deskripsi}
- : <>>
+ : Tidak ada deskripsi
}
@@ -195,12 +195,12 @@ export default function InformationDivision() {
}}
>
-
+
-
- {v.name}
-
+
+ {v.name}
+
diff --git a/src/module/group/ui/drawer_group.tsx b/src/module/group/ui/drawer_group.tsx
index f09415b..abba7e1 100644
--- a/src/module/group/ui/drawer_group.tsx
+++ b/src/module/group/ui/drawer_group.tsx
@@ -45,8 +45,10 @@ export default function DrawerGroup({ onSuccess, }: { onSuccess: (val: boolean)
}
function onCheck() {
- if (Object.values(touched).some((v) => v == true))
+ const cek = checkAll()
+ if (!cek) {
return false
+ }
createData()
}
@@ -58,7 +60,15 @@ export default function DrawerGroup({ onSuccess, }: { onSuccess: (val: boolean)
} else {
setTouched({ ...touched, name: false })
}
- }
+ }
+ }
+
+ function checkAll() {
+ if (namaGroup == "" || namaGroup.length < 3) {
+ setTouched({ ...touched, name: true })
+ return false
+ }
+ return true
}
return (
@@ -102,7 +112,7 @@ export default function DrawerGroup({ onSuccess, }: { onSuccess: (val: boolean)
}}
error={
touched.name &&
- (namaGroup == "" ? "Error! harus memasukkan grup" :
+ (namaGroup == "" ? "Grup Tidak Boleh Kosong" :
namaGroup.length < 3 ? "Masukkan Minimal 3 karakter" : ""
)
}
diff --git a/src/module/group/ui/edit_drawer_group.tsx b/src/module/group/ui/edit_drawer_group.tsx
index 238928e..cc34ea3 100644
--- a/src/module/group/ui/edit_drawer_group.tsx
+++ b/src/module/group/ui/edit_drawer_group.tsx
@@ -162,7 +162,7 @@ export default function EditDrawerGroup({ onUpdated, id, isActive, }: { onUpdate
}}
error={
touched.name &&
- (name == "" ? "Error! harus memasukkan grup" :
+ (name == "" ? "Grup Tidak Boleh Kosong" :
name.length < 3 ? "Masukkan Minimal 3 karakter" : ""
)
}
diff --git a/src/module/position/ui/drawer_detail_position.tsx b/src/module/position/ui/drawer_detail_position.tsx
index b68dc3a..7ed430e 100644
--- a/src/module/position/ui/drawer_detail_position.tsx
+++ b/src/module/position/ui/drawer_detail_position.tsx
@@ -18,6 +18,7 @@ export default function DrawerDetailPosition({ onUpdated, id, isActive }: {
const [isModal, setModal] = useState(false)
const refresh = useHookstate(globalRefreshPosition)
const [loading, setLoading] = useState(true)
+ const [loadingEdit, setLoadingEdit] = useState(false)
const tema = useHookstate(TEMA)
const [data, setData] = useState({
id: id,
@@ -27,7 +28,6 @@ export default function DrawerDetailPosition({ onUpdated, id, isActive }: {
const [listGroup, setListGorup] = useState([])
const [touched, setTouched] = useState({
name: false,
- idGroup: false
});
function onCLose() {
@@ -70,6 +70,7 @@ export default function DrawerDetailPosition({ onUpdated, id, isActive }: {
async function onSubmit() {
try {
+ setLoadingEdit(true)
const res = await funEditPosition(id, {
name: data.name,
idGroup: data.idGroup
@@ -88,6 +89,8 @@ export default function DrawerDetailPosition({ onUpdated, id, isActive }: {
} catch (error) {
toast.error('Error');
toast.error("Edit jabatan gagal, coba lagi nanti");
+ } finally {
+ setLoadingEdit(false)
}
}
@@ -98,20 +101,20 @@ export default function DrawerDetailPosition({ onUpdated, id, isActive }: {
function onCheck() {
if (Object.values(touched).some((v) => v == true))
- return false
+ return false
onSubmit()
}
function onValidation(kategori: string, val: string) {
if (kategori == 'name') {
- setData({...data, name: val})
- if (val == "" || val.length < 3) {
- setTouched({ ...touched, name: true })
- } else {
- setTouched({ ...touched, name: false })
- }
+ setData({ ...data, name: val })
+ if (val == "" || val.length < 3) {
+ setTouched({ ...touched, name: true })
+ } else {
+ setTouched({ ...touched, name: false })
+ }
}
- }
+ }
async function nonActive(val: boolean) {
try {
@@ -189,13 +192,12 @@ export default function DrawerDetailPosition({ onUpdated, id, isActive }: {
size="md"
value={String(data.name)}
onChange={(e) => { onValidation('name', e.target.value) }}
- onBlur={() => setTouched({ ...touched, name: true })}
error={
touched.name &&
(data.name == "" ? "Error! harus memasukkan Nama Jabatan" :
data.name.length < 3 ? "Masukkan Minimal 3 karakter" : ""
)
- }
+ }
radius={10}
placeholder="Nama Jabatan"
/>
@@ -208,7 +210,8 @@ export default function DrawerDetailPosition({ onUpdated, id, isActive }: {
size="lg"
radius={30}
fullWidth
- onClick={onSubmit}
+ onClick={() => { onCheck() }}
+ loading={loadingEdit}
>
EDIT
diff --git a/src/module/position/ui/drawer_list_position.tsx b/src/module/position/ui/drawer_list_position.tsx
index fdb4485..83d8ed2 100644
--- a/src/module/position/ui/drawer_list_position.tsx
+++ b/src/module/position/ui/drawer_list_position.tsx
@@ -15,6 +15,7 @@ import { globalRefreshPosition } from "../lib/val_posisition";
export default function DrawerListPosition({ onCreated }: { onCreated: (val: boolean) => void }) {
const roleLogin = useHookstate(globalRole)
const [openDrawerGroup, setOpenDrawerGroup] = useState(false)
+ const [loadingSave, setLoadingSave] = useState(false)
const router = useRouter()
const [listGroup, setListGorup] = useState([])
const refresh = useHookstate(globalRefreshPosition)
@@ -52,6 +53,7 @@ export default function DrawerListPosition({ onCreated }: { onCreated: (val: boo
async function onSubmit() {
try {
+ setLoadingSave(true)
const res = await funCreatePosition({
name: listData.name,
idGroup: listData.idGroup
@@ -70,23 +72,41 @@ export default function DrawerListPosition({ onCreated }: { onCreated: (val: boo
} catch (error) {
toast.error('Error')
+ } finally {
+ setLoadingSave(false)
}
}
function onCheck() {
- if (Object.values(touched).some((v) => v == true))
- return false
+ const check = checkAll()
+ if (!check)
+ return false
onSubmit()
}
-
+
+ function checkAll() {
+ let nilai = true
+ if (listData.name == "" || listData.name.length < 3) {
+ setTouched(touched => ({ ...touched, name: true }))
+ nilai = false
+ }
+
+ if (roleLogin.get() == "supadmin" && listData.idGroup == "") {
+ setTouched(touched => ({ ...touched, idGroup: true }))
+ nilai = false
+ }
+
+ return nilai
+ }
+
function onValidation(kategori: string, val: string) {
if (kategori == 'name') {
- setListData({...listData, name: val})
- if (val == "" || val.length < 3) {
- setTouched({ ...touched, name: true })
- } else {
- setTouched({ ...touched, name: false })
- }
+ setListData({ ...listData, name: val })
+ if (val == "" || val.length < 3) {
+ setTouched({ ...touched, name: true })
+ } else {
+ setTouched({ ...touched, name: false })
+ }
} else if (kategori == 'idGroup') {
setListData({ ...listData, idGroup: val })
if (val == "") {
@@ -95,7 +115,7 @@ export default function DrawerListPosition({ onCreated }: { onCreated: (val: boo
setTouched({ ...touched, idGroup: false })
}
}
- }
+ }
return (
@@ -130,7 +150,7 @@ export default function DrawerListPosition({ onCreated }: { onCreated: (val: boo
sm: "67vh",
lg: "67vh",
xl: "70vh"
-
+
}}>
{
roleLogin.get() == "supadmin" &&
@@ -149,8 +169,7 @@ export default function DrawerListPosition({ onCreated }: { onCreated: (val: boo
radius={10}
mb={5}
withAsterisk
- onChange={(e: any) =>
- { onValidation('idGroup', e) }
+ onChange={(e: any) => { onValidation('idGroup', e) }
}
styles={{
input: {
@@ -185,7 +204,7 @@ export default function DrawerListPosition({ onCreated }: { onCreated: (val: boo
(listData.name == "" ? "Error! harus memasukkan Nama Jabatan" :
listData.name.length < 3 ? "Masukkan Minimal 3 karakter" : ""
)
- }
+ }
required
/>
@@ -196,6 +215,7 @@ export default function DrawerListPosition({ onCreated }: { onCreated: (val: boo
radius={30}
fullWidth
onClick={() => { onCheck() }}
+ loading={loadingSave}
>
SIMPAN
diff --git a/src/module/project/ui/create_project.tsx b/src/module/project/ui/create_project.tsx
index 66b0d80..7ea3f6a 100644
--- a/src/module/project/ui/create_project.tsx
+++ b/src/module/project/ui/create_project.tsx
@@ -24,7 +24,6 @@ import ResultsFile from "./results_file";
export default function CreateProject() {
const router = useRouter();
- const [openDrawer, setOpenDrawer] = useState(false)
const [openDrawerFile, setOpenDrawerFile] = useState(false)
const [openDrawerTask, setOpenDrawerTask] = useState(false)
const [isModal, setModal] = useState(false)
@@ -42,6 +41,7 @@ export default function CreateProject() {
const roleLogin = useHookstate(globalRole)
const isMobile = useMediaQuery('(max-width: 369px)');
const tema = useHookstate(TEMA)
+ const [loadingModal, setLoadingModal] = useState(false)
const [body, setBody] = useState({
idGroup: "",
@@ -50,13 +50,12 @@ export default function CreateProject() {
const [touched, setTouched] = useState({
title: false,
idGroup: false,
- desc: false
});
const [data, setDataRealtime] = useWibuRealtime({
WIBU_REALTIME_TOKEN: keyWibu,
project: "sdm"
- })
+ })
function deleteFile(index: number) {
setListFile([...listFile.filter((val, i) => i !== index)])
@@ -92,7 +91,7 @@ export default function CreateProject() {
function onChooseGroup(val: any) {
member.set([])
- setBody({ ...body, idGroup: val })
+ onValidation('idGroup', val)
}
useShallowEffect(() => {
@@ -102,6 +101,7 @@ export default function CreateProject() {
async function onSubmit() {
try {
+ setLoadingModal(true)
const fd = new FormData();
for (let i = 0; i < fileForm.length; i++) {
fd.append(`file${i}`, fileForm[i]);
@@ -130,6 +130,54 @@ export default function CreateProject() {
} catch (error) {
console.error(error)
toast.error("Gagal menambahkan kegiatan, coba lagi nanti");
+ } finally {
+ setLoadingModal(false)
+ setModal(false)
+ }
+ }
+
+ function onCheck() {
+ const cek = checkAll()
+ if (!cek)
+ return false
+
+ if (dataTask.length == 0)
+ return toast.error("Error! silahkan tambahkan tugas")
+
+ if (memberValue.length == 0)
+ return toast.error("Error! silahkan pilih anggota")
+
+ setModal(true)
+ }
+
+ function checkAll() {
+ let nilai = true
+ if (body.idGroup === "" || String(body.idGroup) == "null") {
+ setTouched(touched => ({ ...touched, idGroup: true }))
+ nilai = false
+ }
+ if (body.title === "") {
+ setTouched(touched => ({ ...touched, title: true }))
+ nilai = false
+ }
+ return nilai
+ }
+
+ function onValidation(kategori: string, val: string) {
+ if (kategori == 'idGroup') {
+ setBody({ ...body, idGroup: val })
+ if (val === "" || String(val) == "null") {
+ setTouched({ ...touched, idGroup: true })
+ } else {
+ setTouched({ ...touched, idGroup: false })
+ }
+ } else if (kategori == 'title') {
+ setBody({ ...body, title: val })
+ if (val === "") {
+ setTouched({ ...touched, title: true })
+ } else {
+ setTouched({ ...touched, title: false })
+ }
}
}
@@ -164,14 +212,12 @@ export default function CreateProject() {
}))}
onChange={(val) => {
onChooseGroup(val)
- setTouched({ ...touched, idGroup: false })
}}
value={(body.idGroup == "") ? null : body.idGroup}
- onBlur={() => setTouched({ ...touched, idGroup: true })}
error={
touched.idGroup && (
- body.idGroup == "" ? "Grup Tidak Boleh Kosong" : null
+ body.idGroup == "" || String(body.idGroup) == "null" ? "Grup Tidak Boleh Kosong" : null
)
}
/>
@@ -190,11 +236,7 @@ export default function CreateProject() {
placeholder="Nama Kegiatan"
size="md"
value={body.title}
- onChange={(e) => {
- setBody({ ...body, title: e.target.value })
- setTouched({ ...touched, title: false })
- }}
- onBlur={() => setTouched({ ...touched, title: true })}
+ onChange={(e) => { onValidation('title', e.target.value) }}
error={
touched.title && (
body.title == "" ? "Kegiatan Tidak Boleh Kosong" : null
@@ -356,16 +398,7 @@ export default function CreateProject() {
size="lg"
radius={30}
fullWidth
- onClick={() => {
- if (
- body.title !== "" &&
- body.idGroup !== ""
- ) {
- setModal(true)
- } else {
- toast.error("Mohon lengkapi data terlebih dahulu");
- }
- }}>
+ onClick={() => { onCheck() }}>
Simpan
@@ -494,13 +527,15 @@ export default function CreateProject() {
- setModal(false)}
+ setModal(false)}
description="Apakah Anda yakin ingin menambahkan data?"
onYes={(val) => {
if (val) {
onSubmit()
+ } else {
+ setModal(false)
}
- setModal(false)
+
}} />
);
diff --git a/src/module/project/ui/edit_task_project.tsx b/src/module/project/ui/edit_task_project.tsx
index 6f8e8bc..d747bd5 100644
--- a/src/module/project/ui/edit_task_project.tsx
+++ b/src/module/project/ui/edit_task_project.tsx
@@ -1,13 +1,13 @@
"use client"
-import { useParams, useRouter } from 'next/navigation';
-import React, { useState } from 'react';
-import toast from 'react-hot-toast';
-import { funEditProject, funGetOneProjectById } from '../lib/api_project';
-import { useShallowEffect } from '@mantine/hooks';
-import { Box, Button, Input, rem, Skeleton, Stack, TextInput } from '@mantine/core';
-import { LayoutNavbarNew, TEMA} from '@/module/_global';
+import { LayoutNavbarNew, TEMA } from '@/module/_global';
import LayoutModal from '@/module/_global/layout/layout_modal';
import { useHookstate } from '@hookstate/core';
+import { Box, Button, rem, Skeleton, Stack, TextInput } from '@mantine/core';
+import { useShallowEffect } from '@mantine/hooks';
+import { useParams, useRouter } from 'next/navigation';
+import { useState } from 'react';
+import toast from 'react-hot-toast';
+import { funEditProject, funGetOneProjectById } from '../lib/api_project';
export default function EditTaskProject() {
const router = useRouter()
@@ -20,13 +20,6 @@ export default function EditTaskProject() {
name: false,
});
- function onVerification() {
- if (name == "")
- return toast.error("Error! harus memasukkan judul Kegiatan")
-
- setOpenModal(true)
- }
-
async function onSubmit() {
try {
const res = await funEditProject(param.id, { name })
@@ -42,6 +35,27 @@ export default function EditTaskProject() {
}
}
+ function onCheck() {
+ if (name == "") {
+ setTouched({ ...touched, name: true })
+ return false
+ }
+ setOpenModal(true)
+ }
+
+
+
+ function onValidation(kategori: string, val: string) {
+ if (kategori == 'title') {
+ setName(val)
+ if (val === "") {
+ setTouched({ ...touched, name: true })
+ } else {
+ setTouched({ ...touched, name: false })
+ }
+ }
+ }
+
async function getOneData() {
try {
setLoading(true)
@@ -69,32 +83,28 @@ export default function EditTaskProject() {
- {loading ?
-
+ {loading ?
+
:
- {
- setName(e.target.value)
- setTouched({ ...touched, name: false })
- }}
- error={
- touched.name && (
- name == "" ? "Judul Kegiatan Tidak Boleh Kosong" : null
- )
- }
- onBlur={() => setTouched({ ...touched, name: true })}
- />
+ { onValidation('title', e.target.value) }}
+ error={
+ touched.name && (
+ name == "" ? "Kegiatan Tidak Boleh Kosong" : null
+ )
+ }
+ />
}
@@ -104,19 +114,19 @@ export default function EditTaskProject() {
backgroundColor: `${tema.get().bgUtama}`,
}}>
{loading ?
-
- :
- { onVerification() }}
- >
- Simpan
-
- }
+
+ :
+ { onCheck() }}
+ >
+ Simpan
+
+ }
diff --git a/src/module/task/ui/create_task.tsx b/src/module/task/ui/create_task.tsx
index 1600c41..510ffd4 100644
--- a/src/module/task/ui/create_task.tsx
+++ b/src/module/task/ui/create_task.tsx
@@ -1,30 +1,29 @@
"use client";
import { keyWibu, LayoutDrawer, LayoutNavbarNew, TEMA } from "@/module/_global";
-import { Avatar, Box, Button, Center, Divider, Flex, Grid, Group, Input, rem, SimpleGrid, Stack, Text, TextInput } from "@mantine/core";
+import LayoutModal from "@/module/_global/layout/layout_modal";
+import { useHookstate } from "@hookstate/core";
+import { Avatar, Box, Button, Divider, Flex, Grid, Group, rem, SimpleGrid, Stack, Text, TextInput } from "@mantine/core";
+import { Dropzone } from '@mantine/dropzone';
+import { useMediaQuery } from "@mantine/hooks";
+import _ from "lodash";
import { useParams, useRouter } from "next/navigation";
-import React, { useRef, useState } from "react";
+import { useRef, useState } from "react";
+import toast from "react-hot-toast";
+import { FaTrash } from "react-icons/fa6";
import { IoIosArrowDropright } from "react-icons/io";
-import { BsFiletypeCsv } from "react-icons/bs";
+import { useWibuRealtime } from "wibu-realtime";
+import { funCreateTask } from "../lib/api_task";
+import { IFormDateTask, IFormMemberTask, IListFileTask } from "../lib/type_task";
+import { globalMemberTask } from "../lib/val_task";
+import ViewDateEndTask from "./create_date_end_task";
import CreateUsersProject from "./create_users_project";
import ResultsDateAndTask from "./results_date-and_task";
import ResultsFile from "./results_file";
-import { useHookstate } from "@hookstate/core";
-import { globalMemberTask } from "../lib/val_task";
-import ViewDateEndTask from "./create_date_end_task";
-import { IFormDateTask, IFormMemberTask, IListFileTask } from "../lib/type_task";
-import { Dropzone } from '@mantine/dropzone';
-import toast from "react-hot-toast";
-import _ from "lodash";
-import { FaTrash } from "react-icons/fa6";
-import LayoutModal from "@/module/_global/layout/layout_modal";
-import { funCreateTask } from "../lib/api_task";
-import { useMediaQuery } from "@mantine/hooks";
-import { useWibuRealtime } from "wibu-realtime";
export default function CreateTask() {
const router = useRouter()
const param = useParams<{ id: string }>()
- const [openDrawer, setOpenDrawer] = useState(false)
+ const [loadingModal, setLoadingModal] = useState(false)
const [openDrawerFile, setOpenDrawerFile] = useState(false)
const [openDrawerTask, setOpenDrawerTask] = useState(false)
const [openMember, setOpenMember] = useState(false)
@@ -44,8 +43,6 @@ export default function CreateTask() {
const tema = useHookstate(TEMA)
const [touched, setTouched] = useState({
title: false,
- task: false,
- member: false
});
const [data, setData] = useWibuRealtime({
WIBU_REALTIME_TOKEN: keyWibu,
@@ -66,6 +63,7 @@ export default function CreateTask() {
async function onSubmit() {
try {
+ setLoadingModal(true)
const fd = new FormData();
for (let i = 0; i < fileForm.length; i++) {
fd.append(`file${i}`, fileForm[i]);
@@ -95,10 +93,51 @@ export default function CreateTask() {
} catch (error) {
console.error(error)
toast.error("Gagal menambahkan tugas divisi, coba lagi nanti");
+ } finally {
+ setLoadingModal(false)
+ setOpenModal(false)
}
}
+ function onCheck() {
+ const cek = checkAll()
+ if (!cek)
+ return false
+
+ if (dataTask.length == 0)
+ return toast.error("Error! silahkan tambahkan tugas")
+
+ if (memberValue.length == 0)
+ return toast.error("Error! silahkan pilih anggota")
+
+ setOpenModal(true)
+ }
+
+
+ function checkAll() {
+ let nilai = true
+ if (title === "") {
+ setTouched(touched => ({ ...touched, title: true }))
+ nilai = false
+ }
+ return nilai
+ }
+
+
+ function onValidation(kategori: string, val: string) {
+ if (kategori == 'title') {
+ setTitle(val)
+ if (val === "") {
+ setTouched({ ...touched, title: true })
+ } else {
+ setTouched({ ...touched, title: false })
+ }
+ }
+ }
+
+
+
if (openTugas) return { setOpenTugas(false) }} onSet={(val) => {
setDataTask([...dataTask, val])
setOpenTugas(false)
@@ -123,11 +162,7 @@ export default function CreateTask() {
size="md"
label="Judul Tugas"
value={title}
- onChange={(e) => {
- setTitle(e.target.value)
- setTouched({ ...touched, title: false })
- }}
- onBlur={() => setTouched({ ...touched, title: true })}
+ onChange={(e) => { onValidation('title', e.target.value) }}
required
error={
touched.title && (
@@ -287,15 +322,7 @@ export default function CreateTask() {
bg={tema.get().utama}
size="lg" radius={30}
fullWidth
- onClick={() => {
- if (
- title !== ""
- ) {
- setOpenModal(true)
- } else {
- toast.error("Semua form harus diisi")
- }
- }}>
+ onClick={() => { onCheck() }}>
Simpan
@@ -412,13 +439,14 @@ export default function CreateTask() {
- setOpenModal(false)}
+ setOpenModal(false)}
description="Apakah Anda yakin ingin menambahkan data?"
onYes={(val) => {
if (val) {
onSubmit()
+ } else {
+ setOpenModal(false)
}
- setOpenModal(false)
}} />
);
diff --git a/src/module/task/ui/edit_detail_task.tsx b/src/module/task/ui/edit_detail_task.tsx
index 926fd9c..d8bbd36 100644
--- a/src/module/task/ui/edit_detail_task.tsx
+++ b/src/module/task/ui/edit_detail_task.tsx
@@ -1,28 +1,15 @@
"use client";
import { LayoutNavbarNew, TEMA } from "@/module/_global";
-import {
- Avatar,
- Box,
- Button,
- Flex,
- Group,
- Input,
- rem,
- SimpleGrid,
- Skeleton,
- Stack,
- Text,
- TextInput,
-} from "@mantine/core";
-import React, { useState } from "react";
-import { DatePicker } from "@mantine/dates";
-import { useParams, useRouter } from "next/navigation";
-import toast from "react-hot-toast";
-import moment from "moment";
-import { funEditDetailTask, funGetDetailTask } from "../lib/api_task";
-import { useShallowEffect } from "@mantine/hooks";
import LayoutModal from "@/module/_global/layout/layout_modal";
import { useHookstate } from "@hookstate/core";
+import { Box, Button, Group, rem, SimpleGrid, Skeleton, Stack, Text, TextInput } from "@mantine/core";
+import { DatePicker } from "@mantine/dates";
+import { useShallowEffect } from "@mantine/hooks";
+import moment from "moment";
+import { useParams, useRouter } from "next/navigation";
+import { useState } from "react";
+import toast from "react-hot-toast";
+import { funEditDetailTask, funGetDetailTask } from "../lib/api_task";
export default function EditDetailTask() {
@@ -185,10 +172,10 @@ export default function EditDetailTask() {
touched.title &&
(title == "" ? "Error! harus memasukkan Judul Tahapan" : ""
)
- }
+ }
onChange={(e) => {
onValidation('title', e.target.value)
- }}
+ }}
/>
}
diff --git a/src/module/task/ui/edit_task.tsx b/src/module/task/ui/edit_task.tsx
index 9e9bb25..6aae983 100644
--- a/src/module/task/ui/edit_task.tsx
+++ b/src/module/task/ui/edit_task.tsx
@@ -1,22 +1,13 @@
"use client";
import { LayoutNavbarNew, TEMA } from "@/module/_global";
-import {
- Box,
- Button,
- Input,
- rem,
- Skeleton,
- Stack,
- Textarea,
- TextInput,
-} from "@mantine/core";
-import React, { useState } from "react";
-import { useParams, useRouter } from "next/navigation";
-import toast from "react-hot-toast";
import LayoutModal from "@/module/_global/layout/layout_modal";
-import { funEditTask, funGetTaskDivisionById } from "../lib/api_task";
-import { useShallowEffect } from "@mantine/hooks";
import { useHookstate } from "@hookstate/core";
+import { Box, Button, rem, Skeleton, Stack, TextInput } from "@mantine/core";
+import { useShallowEffect } from "@mantine/hooks";
+import { useParams, useRouter } from "next/navigation";
+import { useState } from "react";
+import toast from "react-hot-toast";
+import { funEditTask, funGetTaskDivisionById } from "../lib/api_task";
export default function EditTask() {
@@ -31,12 +22,22 @@ export default function EditTask() {
});
function onVerification() {
- if (title == "")
- return toast.error("Error! harus memasukkan judul tugas")
-
+ if (Object.values(touched).some((v) => v == true))
+ return false
setOpenModal(true)
}
+ function onValidation(kategori: string, val: string) {
+ if (kategori == 'title') {
+ setTitle(val)
+ if (val === "") {
+ setTouched({ ...touched, title: true })
+ } else {
+ setTouched({ ...touched, title: false })
+ }
+ }
+ }
+
async function onSubmit() {
try {
const res = await funEditTask(param.detail, { title })
@@ -96,16 +97,12 @@ export default function EditTask() {
label="Judul Tugas"
size="md"
value={title}
- onChange={(e) => {
- setTitle(e.target.value)
- setTouched({ ...touched, title: false })
- }}
+ onChange={(e) => { onValidation('title', e.target.value)}}
error={
touched.title && (
title == "" ? "Error! harus memasukkan judul tugas" : null
)
}
- onBlur={() => setTouched({ ...touched, title: true })}
/>
}
diff --git a/src/module/user/member/ui/create_member.tsx b/src/module/user/member/ui/create_member.tsx
index 208ff1a..060b197 100644
--- a/src/module/user/member/ui/create_member.tsx
+++ b/src/module/user/member/ui/create_member.tsx
@@ -1,25 +1,26 @@
"use client";
-import { globalRole, TEMA, WARNA } from "@/module/_global";
+import { globalRole, TEMA } from "@/module/_global";
import LayoutModal from "@/module/_global/layout/layout_modal";
+import { funGetUserByCookies } from "@/module/auth";
import { funGetAllGroup, IDataGroup } from "@/module/group";
+import { funGetAllPosition } from "@/module/position/lib/api_position";
+import { useHookstate } from "@hookstate/core";
import { Avatar, Box, Button, Indicator, rem, Select, Stack, Text, TextInput } from "@mantine/core";
+import { Dropzone } from "@mantine/dropzone";
+import { useShallowEffect } from "@mantine/hooks";
+import _ from "lodash";
import { useRouter } from "next/navigation";
import { useRef, useState } from "react";
import toast from "react-hot-toast";
-import { IDataPositionMember, IDataROleMember } from "../lib/type_member";
-import { funGetAllPosition } from "@/module/position/lib/api_position";
-import { funCreateMember } from "../lib/api_member";
-import _ from "lodash";
-import { useHookstate } from "@hookstate/core";
-import { useShallowEffect } from "@mantine/hooks";
-import { funGetUserByCookies } from "@/module/auth";
-import { valueRoleUser } from "../../lib/val_user";
import { FaCamera } from "react-icons/fa6";
-import { Dropzone } from "@mantine/dropzone";
+import { valueRoleUser } from "../../lib/val_user";
+import { funCreateMember } from "../lib/api_member";
+import { IDataPositionMember, IDataROleMember } from "../lib/type_member";
export default function CreateMember() {
const router = useRouter();
const [isModal, setModal] = useState(false);
+ const [loadingKonfirmasi, setLoadingKonfirmasi] = useState(false);
const [listGroup, setListGorup] = useState([]);
const [listPosition, setListPosition] = useState([]);
const [listUserRole, setListUserRole] = useState([]);
@@ -100,37 +101,33 @@ export default function CreateMember() {
async function onSubmit(val: boolean) {
try {
- if (_.isEmpty(listData)) {
- return;
- }
- if (val) {
- const fd = new FormData()
- fd.append("file", imgForm)
- fd.append("data", JSON.stringify(
- {
- nik: listData.nik,
- name: listData.name,
- phone: listData.phone,
- email: listData.email,
- gender: listData.gender,
- idGroup: listData.idGroup,
- idPosition: listData.idPosition,
- idUserRole: listData.idUserRole,
- }
- ))
- const res = await funCreateMember(fd);
- if (res.success) {
- toast.success(res.message);
- setModal(false);
- router.push("/member?active=true");
- } else {
- toast.error(res.message);
+ setLoadingKonfirmasi(true)
+ const fd = new FormData()
+ fd.append("file", imgForm)
+ fd.append("data", JSON.stringify(
+ {
+ nik: listData.nik,
+ name: listData.name,
+ phone: listData.phone,
+ email: listData.email,
+ gender: listData.gender,
+ idGroup: listData.idGroup,
+ idPosition: listData.idPosition,
+ idUserRole: listData.idUserRole,
}
+ ))
+ const res = await funCreateMember(fd);
+ if (res.success) {
+ toast.success(res.message);
+ router.push("/member?active=true");
+ } else {
+ toast.error(res.message);
}
setModal(false);
} catch (error) {
toast.error("Error");
} finally {
+ setLoadingKonfirmasi(false)
setModal(false);
}
}
@@ -142,12 +139,61 @@ export default function CreateMember() {
}, []);
function onCheck() {
- if (Object.values(touched).some((v) => v == true))
+ const cek = checkAll()
+ if (!cek)
return false
setModal(true)
}
- function onValidation(kategori: string, val: string) {
+ function checkAll() {
+ let nilai = true
+
+ if (listData.nik === "" || listData.nik.length !== 16) {
+ setTouched(touched => ({ ...touched, nik: true }))
+ nilai = false
+ }
+
+ if (listData.name === "") {
+ setTouched(touched => ({ ...touched, name: true }))
+ nilai = false
+ }
+
+ if (listData.phone == "" || !(listData.phone.length >= 10 && listData.phone.length <= 15)) {
+ setTouched(touched => ({ ...touched, phone: true }))
+ nilai = false
+ }
+
+ if (listData.email == "" || !/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(listData.email)) {
+ setTouched(touched => ({ ...touched, email: true }))
+ nilai = false
+ }
+
+ if (listData.gender == "" || String(listData.gender) == "null") {
+ setTouched(touched => ({ ...touched, gender: true }))
+ nilai = false
+ }
+
+ if (roleLogin.get() == "supadmin" && (listData.idGroup == "" || String(listData.idGroup) == "null")) {
+ setTouched(touched => ({ ...touched, idGroup: true }))
+ nilai = false
+ }
+
+ if (listData.idPosition === "" || String(listData.idPosition) == "null") {
+ setTouched(touched => ({ ...touched, idPosition: true }))
+ nilai = false
+ }
+
+ if (listData.idUserRole === "" || String(listData.idUserRole) == "null") {
+ setTouched(touched => ({ ...touched, idUserRole: true }))
+ nilai = false
+ }
+
+ return nilai
+
+ }
+
+
+ function onValidation(kategori: string, val: any) {
if (kategori == 'nik') {
setListData({ ...listData, nik: val })
if (val === "" || val.length !== 16) {
@@ -178,28 +224,28 @@ export default function CreateMember() {
}
} else if (kategori == 'gender') {
setListData({ ...listData, gender: val })
- if (val == "" || val == "null") {
+ if (val == "" || String(val) == "null") {
setTouched({ ...touched, gender: true })
} else {
setTouched({ ...touched, gender: false })
}
} else if (kategori == 'idGroup') {
- setListData({ ...listData, idGroup: val, idPosition: "", })
- if (val === "") {
- setTouched({ ...touched, idGroup: true })
+ setListData(listData => ({ ...listData, idGroup: val, }))
+ if (val === "" || String(val) == "null") {
+ setTouched(touched => ({ ...touched, idGroup: true }))
} else {
setTouched({ ...touched, idGroup: false })
}
} else if (kategori == 'idPosition') {
- setListData({ ...listData, idPosition: val })
- if (val === "") {
- setTouched({ ...touched, idPosition: true })
+ setListData(listData => ({ ...listData, idPosition: val }))
+ if (val === "" || String(val) == "null") {
+ setTouched(touched => ({ ...touched, idPosition: true }))
} else {
setTouched({ ...touched, idPosition: false })
}
} else if (kategori == 'idUserRole') {
setListData({ ...listData, idUserRole: val })
- if (val === "") {
+ if (val === "" || String(val) == "null") {
setTouched({ ...touched, idUserRole: true })
} else {
setTouched({ ...touched, idUserRole: false })
@@ -210,6 +256,7 @@ export default function CreateMember() {
async function changeGrup(val: any) {
setListPosition([]);
onValidation('idGroup', val)
+ onValidation('idPosition', '')
getAllPosition(val);
}
@@ -269,7 +316,7 @@ export default function CreateMember() {
onChange={(val: any) => { changeGrup(val) }}
error={
touched.idGroup && (
- listData.idGroup == "" ? "Grup Tidak Boleh Kosong" : null
+ listData.idGroup == "" || String(listData.idGroup) == "null" ? "Grup Tidak Boleh Kosong" : null
)
}
/>
@@ -301,7 +348,7 @@ export default function CreateMember() {
value={listData.idPosition == "" ? null : listData.idPosition}
error={
touched.idPosition && (
- listData.idPosition == "" ? "Jabatan Tidak Boleh Kosong" : null
+ listData.idPosition == "" || String(listData.idPosition) == "null" ? "Jabatan Tidak Boleh Kosong" : null
)
}
/>
@@ -331,7 +378,7 @@ export default function CreateMember() {
onChange={(val: any) => { onValidation('idUserRole', val) }}
error={
touched.idUserRole && (
- listData.idUserRole == "" ? "Role Tidak Boleh Kosong" : null
+ listData.idUserRole == "" || String(listData.idUserRole) == "null" ? "Role Tidak Boleh Kosong" : null
)
}
/>
@@ -423,7 +470,7 @@ export default function CreateMember() {
error={
touched.phone && (
listData.phone == "" ? "Nomor Telepon Tidak Boleh Kosong" :
- listData.phone.length < 10 ? "Nomor Telepon harus 10 digit" : null
+ listData.phone.length < 10 ? "Nomor Telepon Tidak Valid" : null
)
}
/>
@@ -449,7 +496,7 @@ export default function CreateMember() {
onChange={(val: any) => { onValidation('gender', val) }}
error={
touched.gender && (
- listData.gender == "" ? "Jenis Kelamin Tidak Boleh Kosong" : null
+ listData.gender == "" || String(listData.gender == "null") ? "Jenis Kelamin Tidak Boleh Kosong" : null
)
}
/>
@@ -471,11 +518,16 @@ export default function CreateMember() {
setModal(false)}
description="Apakah Anda yakin ingin menambahkan data?"
onYes={(val) => {
- onSubmit(val);
+ if (val) {
+ onSubmit(val);
+ } else {
+ setModal(false);
+ }
}}
/>
diff --git a/src/module/user/member/ui/edit_member.tsx b/src/module/user/member/ui/edit_member.tsx
index 9033b7a..1d69a5a 100644
--- a/src/module/user/member/ui/edit_member.tsx
+++ b/src/module/user/member/ui/edit_member.tsx
@@ -1,25 +1,25 @@
'use client'
-import { globalRole, TEMA, WARNA } from "@/module/_global";
+import { globalRole, TEMA } from "@/module/_global";
import LayoutModal from "@/module/_global/layout/layout_modal";
import { funGetAllGroup, IDataGroup } from "@/module/group";
import { funGetAllPosition } from "@/module/position/lib/api_position";
+import { useHookstate } from "@hookstate/core";
import { Avatar, Box, Button, Indicator, rem, Select, Skeleton, Stack, Text, TextInput } from "@mantine/core";
+import { Dropzone } from "@mantine/dropzone";
import { useShallowEffect } from "@mantine/hooks";
+import _ from "lodash";
import { useRouter } from "next/navigation";
import { useRef, useState } from "react";
import toast from "react-hot-toast";
-import { HiUser } from "react-icons/hi2";
-import { IDataPositionMember, IDataROleMember, IEditDataMember, IFormMember } from "../lib/type_member";
-import { funEditMember, funGetOneMember, funGetRoleUser } from "../lib/api_member";
-import _ from "lodash";
-import { Dropzone } from "@mantine/dropzone";
import { FaCamera } from "react-icons/fa6";
-import { useHookstate } from "@hookstate/core";
import { valueRoleUser } from "../../lib/val_user";
+import { funEditMember, funGetOneMember } from "../lib/api_member";
+import { IDataPositionMember, IDataROleMember, IEditDataMember } from "../lib/type_member";
export default function EditMember({ id }: { id: string }) {
const [isModal, setModal] = useState(false)
+ const [loadingKonfirmasi, setLoadingKonfirmasi] = useState(false)
const router = useRouter()
const [listGroup, setListGorup] = useState([])
const [listPosition, setListPosition] = useState([])
@@ -111,26 +111,24 @@ export default function EditMember({ id }: { id: string }) {
async function onSubmit(val: boolean) {
try {
- if (_.isEmpty(data)) {
- return
+ setLoadingKonfirmasi(true)
+ const fd = new FormData()
+ fd.append("file", imgForm)
+ fd.append("data", JSON.stringify(data))
+
+ const res = await funEditMember(id, fd)
+
+ if (res.success) {
+ toast.success(res.message)
+ router.push(`/member?active=true`)
+ } else {
+ toast.error(res.message)
}
- if (val) {
- const fd = new FormData()
- fd.append("file", imgForm)
- fd.append("data", JSON.stringify(data))
-
- const res = await funEditMember(id, fd)
-
- if (res.success) {
- toast.success(res.message)
- router.push(`/member?active=true`)
- } else {
- toast.error(res.message)
- }
- }
-
} catch (error) {
toast.error('Error');
+ } finally {
+ setLoadingKonfirmasi(false)
+ setModal(false)
}
}
@@ -171,21 +169,21 @@ export default function EditMember({ id }: { id: string }) {
}
} else if (kategori == 'gender') {
setData({ ...data, gender: val })
- if (val == "" || val == "null") {
+ if (val == "" || String(val) == "null") {
setTouched({ ...touched, gender: true })
} else {
setTouched({ ...touched, gender: false })
}
} else if (kategori == 'idPosition') {
setData({ ...data, idPosition: val })
- if (val === "") {
+ if (val === "" || String(val) == "null") {
setTouched({ ...touched, idPosition: true })
} else {
setTouched({ ...touched, idPosition: false })
}
} else if (kategori == 'idUserRole') {
setData({ ...data, idUserRole: val })
- if (val === "") {
+ if (val === "" || String(val) == "null") {
setTouched({ ...touched, idUserRole: true })
} else {
setTouched({ ...touched, idUserRole: false })
@@ -267,7 +265,7 @@ export default function EditMember({ id }: { id: string }) {
value={(data?.idPosition == "") ? null : data.idPosition}
error={
touched.idPosition && (
- data.idPosition == "" ? "Jabatan Tidak Boleh Kosong" : null
+ data.idPosition == "" || String(data.idPosition) == "null" ? "Jabatan Tidak Boleh Kosong" : null
)
}
/>
@@ -292,7 +290,7 @@ export default function EditMember({ id }: { id: string }) {
value={data?.idUserRole}
error={
touched.idUserRole && (
- data.idUserRole == "" ? "Role Tidak Boleh Kosong" : null
+ data.idUserRole == "" || String(data.idUserRole) == "null" ? "Role Tidak Boleh Kosong" : null
)
}
/>
@@ -325,7 +323,6 @@ export default function EditMember({ id }: { id: string }) {
}}
onChange={(e) => { onValidation('name', e.target.value) }}
value={data.name}
- onBlur={() => setTouched({ ...touched, name: true })}
error={
touched.name && (
data.name == "" ? "Nama Tidak Boleh Kosong" : null
@@ -366,7 +363,7 @@ export default function EditMember({ id }: { id: string }) {
error={
touched.phone && (
data.phone == "" ? "Nomor Telepon Tidak Boleh Kosong" :
- data.phone.length < 10 ? "Nomor Telepon harus 10 digit" : null
+ data.phone.length < 10 ? "Nomor Telepon Tidak Valid" : null
)
}
/>
@@ -395,7 +392,7 @@ export default function EditMember({ id }: { id: string }) {
value={data.gender}
error={
touched.gender && (
- data.gender == "" ? "Gender Tidak Boleh Kosong" : null
+ data.gender == "" || String(data.gender) == "null" ? "Gender Tidak Boleh Kosong" : null
)
}
/>
@@ -422,12 +419,14 @@ export default function EditMember({ id }: { id: string }) {
}
- setModal(false)}
+ setModal(false)}
description="Apakah Anda yakin ingin mengubah data?"
onYes={(val) => {
- if (val)
+ if (val) {
onSubmit(val)
- setModal(false)
+ } else {
+ setModal(false)
+ }
}
} />