diff --git a/src/app/(application)/discussion/[id]/add-member/page.tsx b/src/app/(application)/discussion/[id]/add-member/page.tsx
new file mode 100644
index 0000000..7f96823
--- /dev/null
+++ b/src/app/(application)/discussion/[id]/add-member/page.tsx
@@ -0,0 +1,9 @@
+import { AddMemberDiscussionGeneral } from "@/module/discussion_general";
+
+export default function Page() {
+ return (
+ <>
+
+ >
+ )
+}
\ No newline at end of file
diff --git a/src/app/(application)/discussion/[id]/edit/page.tsx b/src/app/(application)/discussion/[id]/edit/page.tsx
new file mode 100644
index 0000000..7164db5
--- /dev/null
+++ b/src/app/(application)/discussion/[id]/edit/page.tsx
@@ -0,0 +1,14 @@
+import { LayoutNavbarNew } from "@/module/_global";
+import { FormEditDiscussionGeneral } from "@/module/discussion_general";
+import { Box } from "@mantine/core";
+
+export default function Page() {
+ return (
+ <>
+
+ >} />
+
+
+ >
+ )
+}
\ No newline at end of file
diff --git a/src/app/api/discussion-general/[id]/comment/route.ts b/src/app/api/discussion-general/[id]/comment/route.ts
new file mode 100644
index 0000000..37edf90
--- /dev/null
+++ b/src/app/api/discussion-general/[id]/comment/route.ts
@@ -0,0 +1,46 @@
+import { prisma } from "@/module/_global";
+import { funGetUserByCookies } from "@/module/auth";
+import { createLogUser } from "@/module/user";
+import { NextResponse } from "next/server";
+
+
+// KIRIM KOMENTAR DISKUSI UMUM
+export async function POST(request: Request, context: { params: { id: string } }) {
+ try {
+ const { id } = context.params
+ const { desc } = (await request.json());
+
+ const user = await funGetUserByCookies()
+ if (user.id == undefined) {
+ return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 });
+ }
+
+ const cek = await prisma.discussion.count({
+ where: {
+ id,
+ isActive: true
+ }
+ })
+
+ if (cek == 0) {
+ return NextResponse.json({ success: false, message: "Gagal menambahkan komentar, data tidak ditemukan" }, { status: 404 });
+ }
+
+
+ const data = await prisma.discussionComment.create({
+ data: {
+ comment: desc,
+ idDiscussion: id,
+ idUser: user.id
+ }
+ })
+
+ // create log user
+ const log = await createLogUser({ act: 'CREATE', desc: 'User menambah komentar pada diskusi umum', table: 'discussionComment', data: data.id })
+ return NextResponse.json({ success: true, message: "Berhasil menambah komentar" }, { status: 200 });
+
+ } catch (error) {
+ console.error(error)
+ return NextResponse.json({ success: false, message: "Gagal menambahkan komentar, coba lagi nanti (error: 500)" })
+ }
+}
\ No newline at end of file
diff --git a/src/app/api/discussion-general/[id]/route.ts b/src/app/api/discussion-general/[id]/route.ts
index 9aacc5e..899097b 100644
--- a/src/app/api/discussion-general/[id]/route.ts
+++ b/src/app/api/discussion-general/[id]/route.ts
@@ -1,9 +1,12 @@
import { prisma } from "@/module/_global";
import { funGetUserByCookies } from "@/module/auth";
+import { createLogUser } from "@/module/user";
import _ from "lodash";
import moment from "moment";
import { NextResponse } from "next/server";
+
+// GET ONE DETAIL DISKUSI UMUM
export async function GET(request: Request, context: { params: { id: string } }) {
try {
let dataFix
@@ -36,6 +39,7 @@ export async function GET(request: Request, context: { params: { id: string } })
select: {
id: true,
title: true,
+ idGroup: true,
desc: true,
status: true,
createdAt: true,
@@ -44,6 +48,7 @@ export async function GET(request: Request, context: { params: { id: string } })
dataFix = {
id: data?.id,
+ idGroup:data?.idGroup,
title: data?.title,
desc: data?.desc,
status: data?.status,
@@ -72,7 +77,7 @@ export async function GET(request: Request, context: { params: { id: string } })
dataFix = data.map((v: any) => ({
..._.omit(v, ["createdAt", "User",]),
- createdAt: moment(v.createdAt).format("ll"),
+ createdAt: moment(v.createdAt).format("lll"),
username: v.User.name,
img: v.User.img
}))
@@ -99,6 +104,20 @@ export async function GET(request: Request, context: { params: { id: string } })
name: v.User.name,
img: v.User.img
}))
+ } else if (kategori == "cek-anggota") {
+ const cek = await prisma.discussionMember.count({
+ where: {
+ idDiscussion: id,
+ isActive: true,
+ idUser: user.id
+ }
+ })
+
+ if (cek > 0) {
+ dataFix = true
+ } else {
+ dataFix = false
+ }
}
@@ -109,4 +128,136 @@ export async function GET(request: Request, context: { params: { id: string } })
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mendapatkan diskusi, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 });
}
+}
+
+
+// OPEN OR CLOSE DISKUSI UMUM
+export async function POST(request: Request, context: { params: { id: string } }) {
+ try {
+ const user = await funGetUserByCookies()
+ if (user.id == undefined) {
+ return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 });
+ }
+ const { id } = context.params
+ const { status } = (await request.json());
+ let newStatus;
+ if (status === 1) {
+ newStatus = 2;
+ } else if (status === 2) {
+ newStatus = 1;
+ } else {
+ return NextResponse.json({ success: false, message: "Invalid status" }, { status: 400 });
+ }
+
+ const data = await prisma.discussion.count({
+ where: {
+ id: id
+ },
+ });
+
+ if (data == 0) {
+ return NextResponse.json({ success: false, message: "Gagal mendapatkan diskusi, data tidak ditemukan" }, { status: 404 });
+ }
+
+ const result = await prisma.discussion.update({
+ where: {
+ id
+ },
+ data: {
+ status: newStatus
+ }
+ });
+
+ // create log user
+ const log = await createLogUser({ act: 'UPDATE', desc: 'User mengupdate status diskusi umum', table: 'discussion', data: id })
+
+ return NextResponse.json({ success: true, message: "Berhasil mengedit diskusi umum" }, { status: 200 });
+
+ } catch (error) {
+ console.error(error);
+ return NextResponse.json({ success: false, message: "Gagal mengedit diskusi umum, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 });
+ }
+}
+
+
+// DELETE DISCUSSION
+export async function DELETE(request: Request, context: { params: { id: string } }) {
+ try {
+ const user = await funGetUserByCookies()
+ if (user.id == undefined) {
+ return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 });
+ }
+ const { id } = context.params
+
+ const cek = await prisma.discussion.count({
+ where: {
+ id: id
+ },
+ });
+
+ if (cek == 0) {
+ return NextResponse.json({ success: false, message: "Gagal menghapus diskusi umum, data tidak ditemukan" }, { status: 404 });
+ }
+
+
+ const data = await prisma.discussion.update({
+ where: {
+ id
+ },
+ data: {
+ isActive: false
+ }
+ });
+
+
+ // create log user
+ const log = await createLogUser({ act: 'DELETE', desc: 'User menghapus data diskusi umum', table: 'disscussion', data: id })
+ return NextResponse.json({ success: true, message: "Berhasil menghapus diskusi umum", user: user.id }, { status: 200 });
+
+
+ } catch (error) {
+ console.error(error);
+ return NextResponse.json({ success: false, message: "Gagal menghapus diskusi umum, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 });
+ }
+}
+
+
+// EDIT DISCUSSION
+export async function PUT(request: Request, context: { params: { id: string } }) {
+ try {
+ const user = await funGetUserByCookies()
+ if (user.id == undefined) {
+ return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 });
+ }
+ const { id } = context.params
+ const { title, desc } = (await request.json());
+
+ const data = await prisma.discussion.count({
+ where: {
+ id: id
+ },
+ });
+
+ if (data == 0) {
+ return NextResponse.json({ success: false, message: "Gagal mengedit diskusi umum, data tidak ditemukan" }, { status: 404 });
+ }
+
+ const update = await prisma.discussion.update({
+ where: {
+ id
+ },
+ data: {
+ desc,
+ title
+ }
+ });
+
+ // create log user
+ const log = await createLogUser({ act: 'UPDATE', desc: 'User mengupdate data diskusi umum', table: 'discussion', data: id })
+ return NextResponse.json({ success: true, message: "Berhasil mengedit diskusi umum" }, { status: 200 });
+
+ } catch (error) {
+ console.error(error);
+ return NextResponse.json({ success: false, message: "Gagal mengedit diskusi umum, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 });
+ }
}
\ No newline at end of file
diff --git a/src/app/api/discussion-general/route.ts b/src/app/api/discussion-general/route.ts
index e9b01ce..5061216 100644
--- a/src/app/api/discussion-general/route.ts
+++ b/src/app/api/discussion-general/route.ts
@@ -4,6 +4,7 @@ import { createLogUser } from "@/module/user";
import _ from "lodash";
import moment from "moment";
import { NextResponse } from "next/server";
+import "moment/locale/id";
@@ -82,9 +83,15 @@ export async function GET(request: Request) {
mode: "insensitive"
},
},
- orderBy: {
- status: 'desc'
- },
+ orderBy: [
+ {
+ status: 'desc'
+ },
+ {
+ createdAt: 'desc'
+ }
+ ],
+
select: {
id: true,
title: true,
diff --git a/src/module/discussion_general/index.ts b/src/module/discussion_general/index.ts
index e612e04..bb5e452 100644
--- a/src/module/discussion_general/index.ts
+++ b/src/module/discussion_general/index.ts
@@ -1,5 +1,7 @@
+import AddMemberDiscussionGeneral from "./ui/add_member";
import FormCreateDiscussionGeneral from "./ui/create_discussion";
import DetailDiscussionGeneral from "./ui/detail_discussion_general";
+import FormEditDiscussionGeneral from "./ui/edit_discussion_general";
import ListDiscussionGeneral from "./ui/list_discussion";
import MemberDiscussionGeneral from "./ui/member_discussion_general";
import NavbarDiscussionGeneral from "./ui/navbar_discussion";
@@ -8,4 +10,6 @@ export { ListDiscussionGeneral }
export { NavbarDiscussionGeneral }
export { FormCreateDiscussionGeneral }
export { DetailDiscussionGeneral }
-export { MemberDiscussionGeneral }
\ No newline at end of file
+export { MemberDiscussionGeneral }
+export { FormEditDiscussionGeneral }
+export { AddMemberDiscussionGeneral }
\ No newline at end of file
diff --git a/src/module/discussion_general/lib/api_discussion_general.ts b/src/module/discussion_general/lib/api_discussion_general.ts
index d9cf15b..1d7a9bd 100644
--- a/src/module/discussion_general/lib/api_discussion_general.ts
+++ b/src/module/discussion_general/lib/api_discussion_general.ts
@@ -20,3 +20,72 @@ export const funGetOneDiscussionGeneral = async (id: string, path: string) => {
const response = await fetch(`/api/discussion-general/${id}${(path) ? path : ''}`, { next: { tags: ['discussion-general'] } });
return await response.json().catch(() => null);
}
+
+export const funCreateComentDiscussionGeneral = async (path: string, data: { desc: string }) => {
+ const response = await fetch(`/api/discussion-general/${path}/comment`, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify(data),
+ });
+ return await response.json().catch(() => null);
+}
+
+
+
+export const funEditStatusDiscussionGeneral = async (path: string, data: { status: number }) => {
+ const response = await fetch(`/api/discussion-general/${path}`, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify(data),
+ });
+ return await response.json().catch(() => null);
+}
+
+
+export const funEditDiscussionGeneral = async (path: string, data: { title: string, desc: string }) => {
+ const response = await fetch(`/api/discussion-general/${path}`, {
+ method: "PUT",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify(data),
+ });
+ return await response.json().catch(() => null);
+}
+
+
+export const funDeleteDiscussionGeneral = async (path: string) => {
+ const response = await fetch(`/api/discussion-general/${path}`, {
+ method: "DELETE",
+ });
+ return await response.json().catch(() => null);
+}
+
+export const funAddMemberDiscussionGeneral = async (path: string, data: { member: IFormMemberDisscussionGeneral[] }) => {
+ const response = await fetch(`/api/discussion-general/${path}/member`, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json"
+ },
+ body: JSON.stringify(data)
+ })
+
+ return await response.json().catch(() => null)
+}
+
+
+export const funDelMemberDiscussionGeneral = async (path: string, data: { idUser: string }) => {
+ const response = await fetch(`/api/discussion-general/${path}/member`, {
+ method: "DELETE",
+ headers: {
+ "Content-Type": "application/json"
+ },
+ body: JSON.stringify(data)
+ })
+
+ return await response.json().catch(() => null)
+}
\ No newline at end of file
diff --git a/src/module/discussion_general/lib/type_discussion_general.ts b/src/module/discussion_general/lib/type_discussion_general.ts
index 94b130d..62be53f 100644
--- a/src/module/discussion_general/lib/type_discussion_general.ts
+++ b/src/module/discussion_general/lib/type_discussion_general.ts
@@ -19,4 +19,4 @@ export interface IFormMemberDisscussionGeneral {
idUser: string
img: string
username: string
-}
\ No newline at end of file
+}
diff --git a/src/module/discussion_general/ui/add_member.tsx b/src/module/discussion_general/ui/add_member.tsx
new file mode 100644
index 0000000..ab2a6b9
--- /dev/null
+++ b/src/module/discussion_general/ui/add_member.tsx
@@ -0,0 +1,293 @@
+"use client"
+import { LayoutNavbarNew, SkeletonList, TEMA } from '@/module/_global';
+import LayoutModal from '@/module/_global/layout/layout_modal';
+import { funGetUserByCookies } from '@/module/auth';
+import { funGetAllmember, TypeUser } from '@/module/user';
+import { useHookstate } from '@hookstate/core';
+import { Carousel } from '@mantine/carousel';
+import { ActionIcon, Avatar, Box, Button, Center, Divider, Flex, Grid, Indicator, rem, Stack, Text, TextInput } from '@mantine/core';
+import { useMediaQuery, useShallowEffect } from '@mantine/hooks';
+import { useParams, useRouter } from 'next/navigation';
+import { useState } from 'react';
+import toast from 'react-hot-toast';
+import { FaCheck } from 'react-icons/fa6';
+import { HiMagnifyingGlass } from 'react-icons/hi2';
+import { IoArrowBackOutline, IoClose } from 'react-icons/io5';
+import { funAddMemberDiscussionGeneral, funGetOneDiscussionGeneral } from '../lib/api_discussion_general';
+import { IFormMemberDisscussionGeneral } from '../lib/type_discussion_general';
+
+
+
+export default function AddMemberDiscussionGeneral() {
+ const router = useRouter()
+ const [selectedFiles, setSelectedFiles] = useState([]);
+ const [dataMember, setDataMember] = useState([])
+ const [memberDb, setMemberDb] = useState([])
+ const [group, setGroup] = useState("")
+ const [isOpen, setOpen] = useState(false)
+ const param = useParams<{ id: string }>()
+ const [loading, setLoading] = useState(true)
+ const [onClickSearch, setOnClickSearch] = useState(false)
+ const tema = useHookstate(TEMA)
+ const isMobile2 = useMediaQuery("(max-width: 438px)")
+ const [loadingModal, setLoadingModal] = useState(false)
+
+ const handleFileClick = (index: number) => {
+ if (selectedFiles.some((i: any) => i.idUser == dataMember[index].id)) {
+ setSelectedFiles(selectedFiles.filter((i: any) => i.idUser != dataMember[index].id))
+ } else {
+ setSelectedFiles([...selectedFiles, { idUser: dataMember[index].id, name: dataMember[index].name, img: dataMember[index].img }])
+ }
+ };
+
+ function handleXMember(id: number) {
+ setSelectedFiles(selectedFiles.filter((i: any) => i.idUser != id))
+ }
+
+
+ async function loadMember(group: string, search: string) {
+ try {
+ setLoading(true)
+ const res = await funGetAllmember('?active=true&group=' + group + '&search=' + search);
+ const user = await funGetUserByCookies();
+
+ if (res.success) {
+ // const dariUserLogin = res.data.filter((i: any) => i.id != user.id)
+ // const fixListUser = dariUserLogin.filter((i: any) => i.idUserRole == 'coadmin' || i.idUserRole == 'user')
+ const fixListUser = res.data.filter((i: any) => i.idUserRole != 'supadmin')
+ setDataMember(fixListUser)
+ } else {
+ toast.error(res.message)
+ }
+ } catch (error) {
+ console.error(error)
+ toast.error("Gagal memuat data, coba lagi nanti")
+ } finally {
+ setLoading(false)
+ }
+
+ }
+
+ async function loadFirst() {
+ const respon = await funGetOneDiscussionGeneral(param.id, '?cat=detail');
+ const respon2 = await funGetOneDiscussionGeneral(param.id, '?cat=anggota');
+ if (respon.success) {
+ setGroup(respon.data.idGroup)
+ setMemberDb(respon2.data)
+ loadMember(respon.data.idGroup, "")
+ } else {
+ toast.error(respon.message);
+ }
+ }
+
+ async function addMember() {
+ try {
+ setLoadingModal(true)
+ const res = await funAddMemberDiscussionGeneral(param.id, { member: selectedFiles })
+ if (res.success) {
+ toast.success(res.message)
+ router.push("/discussion/" + param.id + "/member")
+ } else {
+ toast.error(res.message)
+ }
+ } catch (error) {
+ console.error(error);
+ toast.error("Gagal menambahkan anggota diskusi umum, coba lagi nanti");
+ } finally {
+ setLoadingModal(false)
+ setOpen(false)
+ }
+ }
+
+ function onCheck() {
+ if (selectedFiles.length == 0) {
+ return toast.error("Error! silahkan pilih anggota")
+ }
+ setOpen(true)
+ }
+
+
+ useShallowEffect(() => {
+ loadFirst()
+ }, []);
+
+ const handleSearchClick = () => {
+ setOnClickSearch(true);
+ };
+
+ const handleClose = () => {
+ setOnClickSearch(false);
+ };
+
+ return (
+
+
+
+ }
+ />
+ {onClickSearch
+ ? (
+
+
+
+
+
+
+
+
+ loadMember(group, e.target.value)}
+ />
+
+
+
+ )
+ : null
+ }
+
+ {selectedFiles.length > 0 ? (
+
+ {selectedFiles.map((v: any, i: any) => {
+ return (
+
+ { handleXMember(v.idUser) }}
+ >
+
+ }>
+
+
+
+ {v.name}
+
+
+ )
+ })}
+
+ ) : (
+
+
+ Tidak ada anggota yang dipilih
+
+
+ )}
+
+
+ {loading ?
+ Array(8)
+ .fill(null)
+ .map((_, i) => (
+
+
+
+ ))
+ :
+ (dataMember.length === 0) ?
+
+ Tidak ada anggota
+
+ :
+
+ {dataMember.map((v: any, index: any) => {
+ const isSelected = selectedFiles.some((i: any) => i.idUser == dataMember[index].id)
+ const found = memberDb.some((i: any) => i.idUser == v.id)
+ return (
+ (!found) ? handleFileClick(index) : null}>
+
+
+
+
+
+
+
+ {v.name}
+ {(found) ? "sudah menjadi anggota divisi" : ""}
+
+ {isSelected ? : null}
+
+
+
+
+
+
+
+ )
+ })}
+
+ }
+
+
+
+
+ setOpen(false)}
+ description="Apakah Anda yakin ingin menambahkan anggota diskusi umum?"
+ onYes={(val) => {
+ if (val) {
+ addMember()
+ } else {
+ setOpen(false)
+ }
+ }} />
+
+ );
+}
diff --git a/src/module/discussion_general/ui/detail_discussion_general.tsx b/src/module/discussion_general/ui/detail_discussion_general.tsx
index 651b540..5a64475 100644
--- a/src/module/discussion_general/ui/detail_discussion_general.tsx
+++ b/src/module/discussion_general/ui/detail_discussion_general.tsx
@@ -1,6 +1,5 @@
"use client"
import { globalRole, keyWibu, LayoutDrawer, LayoutNavbarNew, TEMA } from "@/module/_global";
-import { globalIsAdminDivision, globalIsMemberDivision } from "@/module/division_new";
import { useHookstate } from "@hookstate/core";
import { ActionIcon, Avatar, Badge, Box, Center, Divider, Flex, Grid, Group, rem, Skeleton, Spoiler, Text, TextInput } from "@mantine/core";
import { useMediaQuery, useShallowEffect } from "@mantine/hooks";
@@ -9,15 +8,16 @@ import "moment/locale/id";
import { useParams, useRouter } from "next/navigation";
import { useState } from "react";
import toast from "react-hot-toast";
+import { BiSolidCommentDetail } from "react-icons/bi";
import { GrChatOption } from "react-icons/gr";
import { HiMenu } from "react-icons/hi";
import { VscSend } from "react-icons/vsc";
import { useWibuRealtime } from "wibu-realtime";
-import { funGetOneDiscussionGeneral } from "../lib/api_discussion_general";
+import { funCreateComentDiscussionGeneral, funGetOneDiscussionGeneral } from "../lib/api_discussion_general";
import { IComentsDisscussionGeneral, IDetailDiscussionGeneral } from "../lib/type_discussion_general";
import { globalRefreshDiscussionGeneral } from "../lib/val_discussion_general";
import DrawerDetailDiscussionGeneral from "./drawer_detail_discussion_general";
-import { BiSolidCommentDetail } from "react-icons/bi";
+import { funGetUserByCookies } from "@/module/auth";
export default function DetailDiscussionGeneral() {
const [isData, setData] = useState()
@@ -25,15 +25,13 @@ export default function DetailDiscussionGeneral() {
const [isComent, setIsComent] = useState("")
const param = useParams<{ id: string }>()
const [isLoad, setIsLoad] = useState(true)
- const [loadingKomentar, setLoadingKomentar] = useState(false)
+ const [loadingKomentar, setLoadingKomentar] = useState(true)
const refresh = useHookstate(globalRefreshDiscussionGeneral)
const roleLogin = useHookstate(globalRole)
- const [isCreator, setCreator] = useState(false)
- const [isUser, setUser] = useState('')
- const adminLogin = useHookstate(globalIsAdminDivision)
- const memberDivision = useHookstate(globalIsMemberDivision)
+ const [memberDiscussion, setMemberDiscussion] = useState(false)
const tema = useHookstate(TEMA)
const router = useRouter()
+ const [isUser, setUser] = useState('')
const [openDrawer, setOpenDrawer] = useState(false)
const isMobile = useMediaQuery('(max-width: 369px)')
const isMobile2 = useMediaQuery("(max-width: 438px)")
@@ -46,8 +44,12 @@ export default function DetailDiscussionGeneral() {
try {
setIsLoad(loading)
const response = await funGetOneDiscussionGeneral(param.id, "?cat=detail")
+ const cekAnggota = await funGetOneDiscussionGeneral(param.id, "?cat=cek-anggota")
+ const userLogin = await funGetUserByCookies()
if (response.success) {
setData(response.data)
+ setMemberDiscussion(cekAnggota.data)
+ setUser(String(userLogin?.id))
} else {
toast.error(response.message)
}
@@ -63,25 +65,35 @@ export default function DetailDiscussionGeneral() {
getData(true)
}, [refresh.get()])
- // useShallowEffect(() => {
- // if (dataRealTime && dataRealTime.some((i: any) => i.category == 'discussion-detail' && i.id == param.id)) {
- // getData(false)
- // }
+ useShallowEffect(() => {
+ getKomentar(true)
+ }, [])
- // if (dataRealTime && dataRealTime.some((i: any) => i.category == 'discussion-delete' && i.id == param.id && i.user != isUser)) {
- // toast.error("Data telah di hapus, anda akan beralih ke halaman list diskusi")
- // setTimeout(() => {
- // router.push(`/division/${param.id}/discussion`)
- // }, 1000)
- // }
- // }, [dataRealTime])
+
+
+ useShallowEffect(() => {
+ if (dataRealTime && dataRealTime.some((i: any) => i.category == 'discussion-general-detail' && i.id == param.id)) {
+ getData(false)
+ }
+
+ if (dataRealTime && dataRealTime.some((i: any) => i.category == 'discussion-general-comment' && i.id == param.id)) {
+ getKomentar(false)
+ }
+
+ if (dataRealTime && dataRealTime.some((i: any) => i.category == 'discussion-general-delete' && i.id == param.id && i.user != isUser)) {
+ toast.error("Data telah di hapus, anda akan beralih ke halaman list diskusi umum")
+ setTimeout(() => {
+ router.push(`/discussion`)
+ }, 1000)
+ }
+ }, [dataRealTime])
async function getKomentar(loading: boolean) {
try {
setLoadingKomentar(loading)
const response = await funGetOneDiscussionGeneral(param.id, "?cat=komentar")
if (response.success) {
- setData(response.data)
+ setDataKomentar(response.data)
} else {
toast.error(response.message)
}
@@ -92,27 +104,26 @@ export default function DetailDiscussionGeneral() {
}
}
- // const sendComent = async () => {
- // try {
- // if (isComent.trim() == "") {
- // return toast.error("Masukkan Komentar Anda")
- // }
- // const response = await funCreateComent(id, { comment: isComent, idDiscussion: param.detail })
+ const sendComent = async () => {
+ try {
+ if (isComent.trim() == "") {
+ return toast.error("Masukkan Komentar Anda")
+ }
+ const response = await funCreateComentDiscussionGeneral(param.id, { desc: isComent })
- // if (response.success) {
- // setIsComent("")
- // setDataRealtime([{
- // category: "discussion-detail",
- // id: id,
- // }])
- // reloadData()
- // } else {
- // toast.error(response.message)
- // }
- // } catch (error) {
- // console.error(error)
- // }
- // }
+ if (response.success) {
+ setIsComent("")
+ setDataRealtime([{
+ category: "discussion-general-comment",
+ id: param.id,
+ }])
+ } else {
+ toast.error(response.message)
+ }
+ } catch (error) {
+ console.error(error)
+ }
+ }
@@ -122,11 +133,9 @@ export default function DetailDiscussionGeneral() {
setOpenDrawer(true)} bg={tema.get().bgIcon} size="lg" radius="lg" aria-label="Settings">
-
-
- : <>>
+ setOpenDrawer(true)} bg={tema.get().bgIcon} size="lg" radius="lg" aria-label="Settings">
+
+
}
/>
setOpenDrawer(false)}>
@@ -230,7 +239,7 @@ export default function DetailDiscussionGeneral() {
- {isData?.createdAt}
+ {moment(isData?.createdAt).format('ll')}
@@ -258,7 +267,7 @@ export default function DetailDiscussionGeneral() {
>
}
- {isLoad ?
+ {loadingKomentar ?
Array(2)
.fill(0)
.map((_, i) => (
@@ -294,7 +303,7 @@ export default function DetailDiscussionGeneral() {
-
+
@@ -304,7 +313,7 @@ export default function DetailDiscussionGeneral() {
- {moment(v.createdAt).format("ll")}
+ {moment(v.createdAt).format('lll').replace('pukul', '')}
@@ -353,7 +362,7 @@ export default function DetailDiscussionGeneral() {
}}
size="md"
placeholder="Kirim Komentar"
- disabled={(isData?.status === 2 || (!memberDivision.get() && (roleLogin.get() == "user" || roleLogin.get() == "coadmin")))}
+ disabled={(isData?.status === 2 || (!memberDiscussion && (roleLogin.get() == "user" || roleLogin.get() == "coadmin")))}
onChange={(e) => setIsComent(e.target.value)}
value={isComent}
maxLength={300}
@@ -363,8 +372,8 @@ export default function DetailDiscussionGeneral() {
+ onClick={sendComent}
+ variant="subtle" aria-label="submit" disabled={(isData?.status === 2 || (!memberDiscussion && (roleLogin.get() == "user" || roleLogin.get() == "coadmin")))}>
diff --git a/src/module/discussion_general/ui/drawer_detail_discussion_general.tsx b/src/module/discussion_general/ui/drawer_detail_discussion_general.tsx
index d6eada3..c5a656d 100644
--- a/src/module/discussion_general/ui/drawer_detail_discussion_general.tsx
+++ b/src/module/discussion_general/ui/drawer_detail_discussion_general.tsx
@@ -1,4 +1,4 @@
-import { keyWibu, TEMA } from "@/module/_global";
+import { globalRole, keyWibu, TEMA } from "@/module/_global";
import LayoutModal from "@/module/_global/layout/layout_modal";
import { useHookstate } from "@hookstate/core";
import { Box, Flex, SimpleGrid, Stack, Text } from "@mantine/core";
@@ -8,13 +8,16 @@ import { BsTrash3 } from "react-icons/bs";
import { FaCheck, FaPencil, FaUsers } from "react-icons/fa6";
import { MdClose } from "react-icons/md";
import { useWibuRealtime } from "wibu-realtime";
+import { funDeleteDiscussionGeneral, funEditStatusDiscussionGeneral } from "../lib/api_discussion_general";
import { globalRefreshDiscussionGeneral } from "../lib/val_discussion_general";
+import toast from "react-hot-toast";
export default function DrawerDetailDiscussionGeneral({ onSuccess, id, status }: { onSuccess: (val: boolean) => void, id: string, status: number }) {
const [isValModal, setValModal] = useState(false)
const [isValModalStatus, setValModalStatus] = useState(false)
const router = useRouter()
const param = useParams<{ id: string, detail: string }>()
+ const roleLogin = useHookstate(globalRole)
const refresh = useHookstate(globalRefreshDiscussionGeneral)
const tema = useHookstate(TEMA)
const [dataRealTime, setDataRealtime] = useWibuRealtime({
@@ -25,63 +28,63 @@ export default function DrawerDetailDiscussionGeneral({ onSuccess, id, status }:
const [loadingDelete, setLoadingDelete] = useState(false)
- // async function fetchStatusDiscussion(val: boolean) {
- // try {
- // setLoadingUpdate(true)
- // if (val) {
- // const response = await funEditStatusDiscussion(id, { status: status })
- // if (response.success) {
- // toast.success(response.message)
- // refresh.set(!refresh.get())
- // setDataRealtime([{
- // category: "discussion-detail",
- // id: id,
- // }])
- // onSuccess(false)
- // } else {
- // toast.error(response.message)
- // }
- // }
- // } catch (error) {
- // console.error(error);
- // toast.error("Gagal menambahkan diskusi, coba lagi nanti");
- // } finally {
- // setLoadingUpdate(false)
- // setValModalStatus(false)
- // }
- // }
+ async function fetchStatusDiscussion(val: boolean) {
+ try {
+ setLoadingUpdate(true)
+ if (val) {
+ const response = await funEditStatusDiscussionGeneral(id, { status: status })
+ if (response.success) {
+ toast.success(response.message)
+ refresh.set(!refresh.get())
+ setDataRealtime([{
+ category: "discussion-general-detail",
+ id: id,
+ }])
+ onSuccess(false)
+ } else {
+ toast.error(response.message)
+ }
+ }
+ } catch (error) {
+ console.error(error);
+ toast.error("Gagal mengupdate diskusi umum, coba lagi nanti");
+ } finally {
+ setLoadingUpdate(false)
+ setValModalStatus(false)
+ }
+ }
- // async function fetchDeleteDiscussion(val: boolean) {
- // try {
- // if (val) {
- // setLoadingDelete(true)
- // const response = await funDeleteDiscussion(id)
- // if (response.success) {
- // setDataRealtime([
- // {
- // category: "discussion-delete",
- // id: id,
- // user: response.user
- // },
- // {
- // category: "division/" + param.id + "/discussion",
- // }
- // ])
- // toast.success(response.message)
- // onSuccess(false)
- // router.push(`/division/${param.id}/discussion`)
- // } else {
- // toast.error(response.message)
- // }
- // }
- // } catch (error) {
- // console.error(error);
- // toast.error("Gagal hapus diskusi, coba lagi nanti");
- // } finally {
- // setLoadingDelete(false)
- // setValModal(false)
- // }
- // }
+ async function fetchDeleteDiscussion(val: boolean) {
+ try {
+ if (val) {
+ setLoadingDelete(true)
+ const response = await funDeleteDiscussionGeneral(id)
+ if (response.success) {
+ setDataRealtime([
+ {
+ category: "discussion-general-delete",
+ id: id,
+ user: response.user
+ },
+ {
+ category: "discussion",
+ }
+ ])
+ toast.success(response.message)
+ onSuccess(false)
+ router.push(`/discussion`)
+ } else {
+ toast.error(response.message)
+ }
+ }
+ } catch (error) {
+ console.error(error);
+ toast.error("Gagal hapus diskusi umum, coba lagi nanti");
+ } finally {
+ setLoadingDelete(false)
+ setValModal(false)
+ }
+ }
return (
@@ -102,46 +105,53 @@ export default function DrawerDetailDiscussionGeneral({ onSuccess, id, status }:
- window.location.href = `/discussion/${param.id}/update/`} justify={'center'} align={'center'} direction={'column'} >
-
-
-
-
- Edit
-
-
-
- setValModalStatus(true)} >
- {status === 1 ? (
+ {
+ (roleLogin.get() != "user" && roleLogin.get() != "coadmin") ? (
<>
-
+ window.location.href = `/discussion/${param.id}/edit/`} justify={'center'} align={'center'} direction={'column'} >
-
+
+
+
+ Edit
+
+
+
+ setValModalStatus(true)} >
+ {status === 1 ? (
+ <>
+
+
+
+
+ Tutup Diskusi
+
+ >
+ ) : (
+ <>
+
+
+
+
+
+ Buka Diskusi
+
+ >
+ )}
+
+
+ setValModal(true)} justify={'center'} align={'center'} direction={'column'} >
+
+
+
+
+ Hapus
- Tutup Diskusi
>
- ) : (
- <>
-
-
-
-
-
- Buka Diskusi
-
- >
- )}
-
-
- setValModal(true)} justify={'center'} align={'center'} direction={'column'} >
-
-
-
-
- Hapus
-
-
+ )
+ : (<>>)
+ }
@@ -149,14 +159,14 @@ export default function DrawerDetailDiscussionGeneral({ onSuccess, id, status }:
setValModal(false)}
description="Apakah Anda yakin ingin menghapus diskusi ini?"
onYes={(val) => {
- // fetchDeleteDiscussion(val)
+ fetchDeleteDiscussion(val)
}} />
setValModalStatus(false)}
description="Apakah Anda yakin ingin mengubah status diskusi ini?"
onYes={(val) => {
- // fetchStatusDiscussion(val)
+ fetchStatusDiscussion(val)
}} />
)
diff --git a/src/module/discussion_general/ui/edit_discussion_general.tsx b/src/module/discussion_general/ui/edit_discussion_general.tsx
new file mode 100644
index 0000000..4bc1945
--- /dev/null
+++ b/src/module/discussion_general/ui/edit_discussion_general.tsx
@@ -0,0 +1,208 @@
+'use client'
+import { keyWibu, TEMA } from "@/module/_global"
+import LayoutModal from "@/module/_global/layout/layout_modal"
+import { useHookstate } from "@hookstate/core"
+import { Box, Button, rem, Skeleton, 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 { useWibuRealtime } from "wibu-realtime"
+import { funEditDiscussionGeneral, funGetOneDiscussionGeneral } from "../lib/api_discussion_general"
+
+export default function FormEditDiscussionGeneral() {
+ const [isValModal, setValModal] = useState(false)
+ const [loadingModal, setLoadingModal] = useState(false)
+ const router = useRouter()
+ const param = useParams<{ id: string }>()
+ const [isDesc, setDesc] = useState("")
+ const [isTitle, setTitle] = useState("")
+ const [loading, setLoading] = useState(true)
+ const tema = useHookstate(TEMA)
+ const [touched, setTouched] = useState({
+ title: false,
+ desc: false,
+ });
+ const [dataRealTime, setDataRealtime] = useWibuRealtime({
+ WIBU_REALTIME_TOKEN: keyWibu,
+ project: "sdm"
+ })
+
+ async function fetchGetOneDiscussion() {
+ try {
+ setLoading(true)
+ const response = await funGetOneDiscussionGeneral(param.id, '?cat=detail')
+ setDesc(response.data.desc)
+ setTitle(response.data.title)
+ } catch (error) {
+ console.error(error);
+ toast.error("Gagal menampilkan diskusi, coba lagi nanti");
+ } finally {
+ setLoading(false)
+ }
+ }
+
+ async function fetchEditDiscussion() {
+ try {
+ setLoadingModal(true)
+ const response = await funEditDiscussionGeneral(param.id, {
+ title: isTitle,
+ desc: isDesc
+ })
+ if (response.success) {
+ toast.success(response.message)
+ setValModal(false)
+ setDataRealtime([{
+ category: "discussion-general-detail",
+ id: param.id,
+ }])
+ router.push(`/discussion/${param.id}`)
+ } else {
+ toast.error(response.message)
+ }
+
+ } catch (error) {
+ console.error(error);
+ setValModal(false)
+ toast.error("Gagal mengubah diskusi umum, coba lagi nanti");
+ } finally {
+ setValModal(false)
+ setLoadingModal(false)
+ }
+ }
+
+ useShallowEffect(() => {
+ fetchGetOneDiscussion()
+ }, [])
+
+ function onValidation(kategori: string, val: string) {
+ if (kategori == 'title') {
+ setTitle(val)
+ if (val === "") {
+ setTouched({ ...touched, title: true })
+ } else {
+ setTouched({ ...touched, title: false })
+ }
+ } else if (kategori == 'diskusi') {
+ setDesc(val)
+ if (val === "") {
+ setTouched({ ...touched, desc: true })
+ } else {
+ setTouched({ ...touched, desc: false })
+ }
+ }
+ }
+
+
+ function onCheck() {
+ const cek = checkAll()
+ if (!cek)
+ return false
+
+ setValModal(true)
+ }
+
+ function checkAll() {
+ let nilai = true
+ if (isTitle === "") {
+ setTouched(touched => ({ ...touched, title: true }))
+ nilai = false
+ }
+ if (isDesc === "") {
+ setTouched(touched => ({ ...touched, desc: true }))
+ nilai = false
+ }
+ return nilai
+ }
+
+
+
+ return (
+
+
+
+ {loading ?
+ Array(2)
+ .fill(null)
+ .map((_, i) => (
+
+ ))
+ :
+
+ { onValidation('title', e.target.value) }}
+ error={
+ touched.title && (
+ isTitle == "" ? "Judul Tidak Boleh Kosong" : null
+ )
+ }
+ />
+ { onValidation('diskusi', e.target.value) }}
+ error={
+ touched.desc && (
+ isDesc == "" ? "Diskusi Tidak Boleh Kosong" : null
+ )
+ }
+ />
+
+ }
+
+
+
+ {loading ?
+
+ :
+
+ }
+
+
+ setValModal(false)}
+ description="Apakah Anda yakin ingin mengubah data?"
+ onYes={(val) => {
+ if (val) {
+ fetchEditDiscussion()
+ } else {
+ setValModal(false)
+ }
+ }} />
+
+ )
+}
\ No newline at end of file
diff --git a/src/module/discussion_general/ui/member_discussion_general.tsx b/src/module/discussion_general/ui/member_discussion_general.tsx
index ddda736..1613acb 100644
--- a/src/module/discussion_general/ui/member_discussion_general.tsx
+++ b/src/module/discussion_general/ui/member_discussion_general.tsx
@@ -2,37 +2,31 @@
import { globalRole, LayoutDrawer, LayoutNavbarNew, SkeletonList, TEMA } from '@/module/_global';
import LayoutModal from '@/module/_global/layout/layout_modal';
import { useHookstate } from '@hookstate/core';
-import { ActionIcon, Avatar, Box, Divider, Flex, Grid, Group, SimpleGrid, Stack, Text } from '@mantine/core';
+import { ActionIcon, Avatar, Box, Divider, Grid, Group, Text } from '@mantine/core';
import { useMediaQuery, useShallowEffect } from '@mantine/hooks';
import { useParams, useRouter } from 'next/navigation';
import { useState } from 'react';
import toast from 'react-hot-toast';
import { AiOutlineUserAdd } from 'react-icons/ai';
-import { FaPencil, FaToggleOff, FaUserTie } from 'react-icons/fa6';
+import { FaUserTie } from 'react-icons/fa6';
import { IoIosCloseCircle } from 'react-icons/io';
-import { funGetOneDiscussionGeneral } from '../lib/api_discussion_general';
+import { funDelMemberDiscussionGeneral, funGetOneDiscussionGeneral } from '../lib/api_discussion_general';
import { IFormMemberDisscussionGeneral } from '../lib/type_discussion_general';
export default function MemberDiscussionGeneral() {
const router = useRouter()
const [openDrawer, setDrawer] = useState(false)
- const [openDrawerInfo, setDrawerInfo] = useState(false)
- const [valActive, setValActive] = useState(true)
const param = useParams<{ id: string }>()
const [member, setMember] = useState([])
const [loading, setLoading] = useState(true)
- const [valChooseMember, setChooseMember] = useState("")
- const [valChooseMemberStatus, setChooseMemberStatus] = useState(false)
+ const [valChooseMemberId, setChooseMemberId] = useState("")
const [valChooseMemberName, setChooseMemberName] = useState("")
const [isOpenModal, setOpenModal] = useState(false)
- const [isOpenModalStatus, setOpenModalStatus] = useState(false)
const roleLogin = useHookstate(globalRole)
- const [isAdmin, setAdmin] = useState(false)
const isMobile = useMediaQuery('(max-width: 455px)')
const isMobile2 = useMediaQuery("(max-width: 438px)")
const tema = useHookstate(TEMA)
- const [loadingStatus, setLoadingStatus] = useState(false)
const [loadingDelete, setLoadingDelete] = useState(false)
async function getOneData(loading: boolean) {
@@ -57,96 +51,38 @@ export default function MemberDiscussionGeneral() {
}, [param.id])
- async function onClickMember(id: string, status: boolean) {
- setChooseMember(id)
- setChooseMemberStatus(status)
+ async function onClickMember(id: string, name: string) {
+ setChooseMemberId(id)
+ setChooseMemberName(name)
setDrawer(true)
}
- // async function deleteMember() {
- // try {
- // setLoadingDelete(true)
- // const res = await funDeleteMemberDivision(param.id, { id: valChooseMember })
- // if (res.success) {
- // toast.success(res.message)
- // setDrawer(false)
- // getOneData(false)
- // } else {
- // toast.error(res.message)
- // }
- // } catch (error) {
- // console.error(error);
- // toast.error("Gagal mendapatkan divisi, coba lagi nanti");
- // } finally {
- // setLoadingDelete(false)
- // setOpenModal(false)
- // }
- // }
+ async function deleteMember() {
+ try {
+ setLoadingDelete(true)
+ const res = await funDelMemberDiscussionGeneral(param.id, { idUser: valChooseMemberId })
+ if (res.success) {
+ toast.success(res.message)
+ setDrawer(false)
+ getOneData(false)
+ } else {
+ toast.error(res.message)
+ }
+ } catch (error) {
+ console.error(error);
+ toast.error("Gagal mendapatkan divisi, coba lagi nanti");
+ } finally {
+ setLoadingDelete(false)
+ setOpenModal(false)
+ }
+ }
- // async function editStatusAdmin() {
- // try {
- // const res = await funEditStatusAdminDivision(param.id, { id: valChooseMember, isAdmin: valChooseMemberStatus })
- // if (res.success) {
- // toast.success(res.message)
- // getOneData(false)
- // } else {
- // toast.error(res.message)
- // }
- // setDrawer(false)
- // } catch (error) {
- // console.error(error);
- // toast.error("Gagal mendapatkan divisi, coba lagi nanti");
- // }
- // }
-
- // async function editStatusDivisi() {
- // try {
- // setLoadingStatus(true)
- // const res = await funUpdateStatusDivision(param.id, { isActive: valActive })
- // if (res.success) {
- // toast.success(res.message)
- // getOneData(false)
- // } else {
- // toast.error(res.message)
- // }
- // } catch (error) {
- // console.error(error);
- // toast.error("Gagal mendapatkan divisi, coba lagi nanti");
- // } finally {
- // setDrawerInfo(false)
- // setLoadingStatus(false)
- // setOpenModalStatus(false)
- // }
- // }
-
return (
>} />
- {/*
- Deskripsi Divisi
-
- {
- loading ?
- Array(3)
- .fill(null)
- .map((_, i) => (
-
-
-
- ))
- :
- (deskripsi != null && deskripsi != undefined && deskripsi != "") ?
- {deskripsi}
- : Tidak ada deskripsi
- }
-
- */}
{member.length} Anggota
@@ -156,15 +92,17 @@ export default function MemberDiscussionGeneral() {
border: `1px solid ${tema.get().bgTotalKegiatan}`,
}}>
- {loading ?
- <>>
+ {!loading ?
+ roleLogin.get() != "user" && roleLogin.get() != "coadmin" ?
+ router.push('/discussion/' + param.id + '/add-member/')}>
+
+
+
+ Tambah Anggota
+
+ : <>>
:
- router.push('/division/add-member/' + param.id)}>
-
-
-
- Tambah Anggota
-
+ <>>
}
@@ -181,15 +119,10 @@ export default function MemberDiscussionGeneral() {
return (
{
- if ((roleLogin.get() != 'user' && roleLogin.get() != 'coadmin') || isAdmin) {
- // onClickMember(v.id, (v.isAdmin) ? true : false)
- setChooseMemberName(v.name)
- }
- }}
+ onClick={() => { onClickMember(v.idUser, v.name) }}
>
-
+
@@ -212,66 +145,32 @@ export default function MemberDiscussionGeneral() {
setDrawer(false)} title={valChooseMemberName}>
- valActive ? editStatusAdmin() : undefined}
- >
+ { router.push('/member/' + valChooseMemberId) }} >
-
+
- {(valChooseMemberStatus == false) ? "Jadikan admin" : "Memberhentikan sebagai admin"}
-
- valActive ? setOpenModal(true) : undefined}>
-
-
-
- Keluarkan dari divisi
+ Lihat Profil
+ {
+ (roleLogin.get() != "user" && roleLogin.get() != "coadmin") &&
+ setOpenModal(true)}>
+
+
+
+ Keluarkan dari diskusi
+
+ }
setOpenModal(false)}
description="Apakah Anda yakin ingin mengeluarkan anggota?"
onYes={(val) => {
- // if (!val) {
- // setOpenModal(false)
- // } else {
- // deleteMember()
- // }
- }} />
-
- setDrawerInfo(false)} title={"Menu"}>
-
-
-
- router.push('/division/edit/' + param.id)} justify={'center'} align={'center'} direction={'column'} >
-
-
-
-
- Edit Divisi
-
-
- { setOpenModalStatus(true) }} justify={'center'} align={'center'} direction={'column'} >
-
-
-
-
- {valActive ? "Non Aktifkan Divisi" : "Aktifkan Divisi"}
-
-
-
-
-
-
-
- setOpenModalStatus(false)}
- description="Apakah Anda yakin ingin mangubah status aktifasi divisi?"
- onYes={(val) => {
- // if (!val) {
- // setOpenModalStatus(false)
- // } else {
- // editStatusDivisi()
- // }
+ if (!val) {
+ setOpenModal(false)
+ } else {
+ deleteMember()
+ }
}} />
);