diff --git a/package.json b/package.json index cc017696..b5b33165 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,7 @@ "react": "18.2.0", "react-countdown": "^2.3.5", "react-dom": "18.2.0", + "react-easy-infinite-scroll-hook": "^2.1.4", "react-fast-marquee": "^1.6.4", "react-icons": "^5.0.1", "react-international-phone": "^4.2.6", diff --git a/src/app/dev/colab/detail/grup/[id]/page.tsx b/src/app/dev/colab/detail/grup/[id]/page.tsx index 365a6998..ffc00e30 100644 --- a/src/app/dev/colab/detail/grup/[id]/page.tsx +++ b/src/app/dev/colab/detail/grup/[id]/page.tsx @@ -5,14 +5,16 @@ import _ from "lodash"; export default async function Page({ params }: { params: { id: string } }) { let roomId = params.id; - const userLoginId = await user_getOneUserId() - let listMsg = await colab_getMessageByRoomId(roomId); - const reserveMsg = _.reverse(listMsg) - + const userLoginId = await user_getOneUserId(); + let listMsg = await colab_getMessageByRoomId(roomId, 1); return ( <> - + ); } diff --git a/src/app/dev/colab/detail/main_detail/[id]/page.tsx b/src/app/dev/colab/detail/main_detail/[id]/page.tsx index f9c5f7bd..1c38b796 100644 --- a/src/app/dev/colab/detail/main_detail/[id]/page.tsx +++ b/src/app/dev/colab/detail/main_detail/[id]/page.tsx @@ -1,6 +1,6 @@ import { Colab_MainDetail } from "@/app_modules/colab"; import colab_funCekPartisipasiById from "@/app_modules/colab/fun/get/cek_partisipasi_by_user_id"; -import colab_getListPartisipanById from "@/app_modules/colab/fun/get/get_list_partisipan_by_id"; +import colab_getListPartisipanByColabId from "@/app_modules/colab/fun/get/get_list_partisipan_by_id"; import colab_getOneCollaborationById from "@/app_modules/colab/fun/get/get_one_by_id"; import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token"; @@ -8,7 +8,7 @@ export default async function Page({ params }: { params: { id: string } }) { let colabId = params.id; const userLoginId = await user_getOneUserId(); const dataColab = await colab_getOneCollaborationById(colabId); - const listPartisipan = await colab_getListPartisipanById(colabId); + const listPartisipan = await colab_getListPartisipanByColabId(colabId); const cekPartisipan = await colab_funCekPartisipasiById(colabId); return ( diff --git a/src/app/dev/colab/detail/proyek/partisipasi/[id]/page.tsx b/src/app/dev/colab/detail/proyek/partisipasi/[id]/page.tsx index 0a921039..68b18d99 100644 --- a/src/app/dev/colab/detail/proyek/partisipasi/[id]/page.tsx +++ b/src/app/dev/colab/detail/proyek/partisipasi/[id]/page.tsx @@ -1,11 +1,11 @@ import { Colab_DetailPartisipasiProyek } from "@/app_modules/colab"; -import colab_getListPartisipanById from "@/app_modules/colab/fun/get/get_list_partisipan_by_id"; +import colab_getListPartisipanByColabId from "@/app_modules/colab/fun/get/get_list_partisipan_by_id"; import colab_getOneCollaborationById from "@/app_modules/colab/fun/get/get_one_by_id"; export default async function Page({params}: {params: {id: string}}) { const colabId = params.id const dataColab = await colab_getOneCollaborationById(colabId) - const listPartisipan = await colab_getListPartisipanById(colabId) + const listPartisipan = await colab_getListPartisipanByColabId(colabId) return ( <> diff --git a/src/app/dev/colab/detail/proyek/saya/[id]/page.tsx b/src/app/dev/colab/detail/proyek/saya/[id]/page.tsx index 3e60a92d..2c5d724f 100644 --- a/src/app/dev/colab/detail/proyek/saya/[id]/page.tsx +++ b/src/app/dev/colab/detail/proyek/saya/[id]/page.tsx @@ -1,11 +1,11 @@ import { Colab_DetailProyekSaya } from "@/app_modules/colab"; -import colab_getListPartisipanById from "@/app_modules/colab/fun/get/get_list_partisipan_by_id"; +import colab_getListPartisipanByColabId from "@/app_modules/colab/fun/get/get_list_partisipan_by_id"; import colab_getOneCollaborationById from "@/app_modules/colab/fun/get/get_one_by_id"; export default async function Page({ params }: { params: { id: string } }) { const colabId = params.id; const dataColab = await colab_getOneCollaborationById(colabId); - const listPartisipan = await colab_getListPartisipanById(colabId); + const listPartisipan = await colab_getListPartisipanByColabId(colabId); return ( <> diff --git a/src/app/dev/colab/main/proyek/page.tsx b/src/app/dev/colab/main/proyek/page.tsx index 385d7b35..81e644f7 100644 --- a/src/app/dev/colab/main/proyek/page.tsx +++ b/src/app/dev/colab/main/proyek/page.tsx @@ -1,15 +1,15 @@ import { Colab_Proyek } from "@/app_modules/colab"; -import colab_getListPartisipasiByAuthorId from "@/app_modules/colab/fun/get/get_list_partisipasi_by_author_id"; +import colab_getListPartisipasiProyekByAuthorId from "@/app_modules/colab/fun/get/get_list_partisipasi_proyek_by_author_id"; import colab_getListAllProyekSayaByAuthorId from "@/app_modules/colab/fun/get/get_list_proyek_saya_by_author_id"; export default async function Page() { - const listPartisipasiUser = (await colab_getListPartisipasiByAuthorId()).data; + const listPartisipasiProyek = (await colab_getListPartisipasiProyekByAuthorId()).data; const listProyekSaya = (await colab_getListAllProyekSayaByAuthorId()).data; return ( <> diff --git a/src/app/makuro/_util.ts b/src/app/makuro/_util.ts new file mode 100644 index 00000000..ac32e21f --- /dev/null +++ b/src/app/makuro/_util.ts @@ -0,0 +1,9 @@ +import { v4 as uuidv4 } from "uuid"; + +export const createItems = (length = 100): string[] => + Array.from({ length }).map(() => uuidv4()); + +export const loadMore = async (length = 100): Promise => { + console.log("Loading more items..."); + return new Promise((res) => setTimeout(() => res(createItems(length)), 100)); +}; diff --git a/src/app/makuro/page.tsx b/src/app/makuro/page.tsx index 6c35dff1..1cacb14e 100644 --- a/src/app/makuro/page.tsx +++ b/src/app/makuro/page.tsx @@ -1,101 +1,55 @@ "use client"; - -import { - Box, - Button, - Center, - Paper, - ScrollArea, - SimpleGrid, - Stack, - Text, - TextInput, - Title, -} from "@mantine/core"; -import _ from "lodash"; -import ViewMakuro from "./_server/makuro_view"; -import mqtt_client from "@/util/mqtt_client"; import { useState } from "react"; -import { useAtom } from "jotai"; -import { gs_coba_chat } from "./gs_coba"; +import useInfiniteScroll, { + ScrollDirection, +} from "react-easy-infinite-scroll-hook"; +import { createItems, loadMore } from "./_util"; import { useShallowEffect } from "@mantine/hooks"; -export default function Page() { - const [pesan, setPesan] = useState(""); - const [ini, setIni] = useState(""); +export default function App() { + const [data, setData] = useState([]); + const [isLoading, setIsLoading] = useState(false); useShallowEffect(() => { - mqtt_client.subscribe("apa"); - - mqtt_client.on("message", (data: any, msg: any) => { - console.log( msg.toString()); - setIni(msg.toString()); - }); + setData(createItems()); }, []); + const next = async (direction: ScrollDirection) => { + console.log("next", direction); + try { + setIsLoading(true); + const newData = await loadMore(); + + const d = direction === "up"? [...newData, ...data]: [] + setData(d); + } finally { + setIsLoading(false); + } + }; + + const ref = useInfiniteScroll({ + next, + rowCount: data.length, + hasMore: { up: true }, + }); + return ( - <> - - {ini} - setPesan(val.currentTarget.value)} - /> - - - +
+
+ {data.map((key: any) => ( +
+ {key} +
+ ))} +
+ {isLoading &&
Loading...
} +
); } - -// export default function Page() { -// return ( -// -// -// header -// - -// -// -// {Array.from(new Array(15)).map((v, k) => ( -// Cek halaman {k+1} -// ))} -// - -// -// -// - -// -// footer -// -// -// ); -// } diff --git a/src/app/zCoba/page.tsx b/src/app/zCoba/page.tsx index 7246f4be..4a504557 100644 --- a/src/app/zCoba/page.tsx +++ b/src/app/zCoba/page.tsx @@ -1,51 +1,9 @@ -"use client"; - -import { - Box, - Center, - Group, - LoadingOverlay, - Paper, - Skeleton, - Text, -} from "@mantine/core"; - -export default function ComponentCobaCoba_LoadingPage() { - const listhHuruf = [ - { - huruf: "H", - }, - { - huruf: "I", - }, - { - huruf: "P", - }, - { - huruf: "M", - }, - { - huruf: "I", - }, - ]; - const customLOader = ( -
- - {listhHuruf.map((e, i) => ( -
- - - {e.huruf} - -
- ))} -
-
- ); +import Coba_TestLoading from "@/app_modules/zCoba"; +export default async function Page() { return ( <> - + ); } diff --git a/src/app_modules/colab/component/detail/detail_data.tsx b/src/app_modules/colab/component/detail/detail_data.tsx index ce8d7dab..30158c00 100644 --- a/src/app_modules/colab/component/detail/detail_data.tsx +++ b/src/app_modules/colab/component/detail/detail_data.tsx @@ -59,11 +59,9 @@ export default function ComponentColab_DetailData({ - Keutungan - - - {data?.benefit ? data?.benefit : "-"} + Keuntungan + {data?.benefit ? data?.benefit : "-"} diff --git a/src/app_modules/colab/component/detail/header_author_list_partisipan.tsx b/src/app_modules/colab/component/detail/header_author_list_partisipan.tsx index e203853c..29315a21 100644 --- a/src/app_modules/colab/component/detail/header_author_list_partisipan.tsx +++ b/src/app_modules/colab/component/detail/header_author_list_partisipan.tsx @@ -21,6 +21,7 @@ import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/component_gl import { MODEL_USER } from "@/app_modules/home/model/interface"; import { IconEyeCheck, IconZoomCheck } from "@tabler/icons-react"; import { useDisclosure } from "@mantine/hooks"; +import { IconFileCheck } from "@tabler/icons-react"; export default function ComponentColab_AuthorNameOnListPartisipan({ author, @@ -95,7 +96,7 @@ export default function ComponentColab_AuthorNameOnListPartisipan({ radius={"xl"} variant="transparent" > - + ) : ( "" diff --git a/src/app_modules/colab/component/detail/list_partisipasi_user.tsx b/src/app_modules/colab/component/detail/list_partisipasi_user.tsx index b739e695..ee4a932c 100644 --- a/src/app_modules/colab/component/detail/list_partisipasi_user.tsx +++ b/src/app_modules/colab/component/detail/list_partisipasi_user.tsx @@ -22,7 +22,7 @@ import { import _ from "lodash"; import { useState } from "react"; import colab_funCreatePartisipan from "../../fun/create/fun_create_partisipan_by_user_id"; -import colab_getListPartisipanById from "../../fun/get/get_list_partisipan_by_id"; +import colab_getListPartisipanByColabId from "../../fun/get/get_list_partisipan_by_id"; import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/component_global/notif_global/notifikasi_berhasil"; import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/notif_global/notifikasi_gagal"; import { useDisclosure } from "@mantine/hooks"; @@ -53,7 +53,7 @@ export default function ComponentColab_DetailListPartisipasiUser({ deskripsi ).then(async (res) => { if (res.status === 201) { - await colab_getListPartisipanById(colabId as any).then((val) => { + await colab_getListPartisipanByColabId(colabId as any).then((val) => { setApply(true); close(); setData(val as any); diff --git a/src/app_modules/colab/detail/grup/index.tsx b/src/app_modules/colab/detail/grup/index.tsx index 4df0da7e..a99ed427 100644 --- a/src/app_modules/colab/detail/grup/index.tsx +++ b/src/app_modules/colab/detail/grup/index.tsx @@ -6,8 +6,11 @@ import { Badge, Box, Button, + Center, + Flex, Grid, Group, + Loader, Paper, ScrollArea, Stack, @@ -17,9 +20,13 @@ import { Transition, rem, } from "@mantine/core"; -import { useShallowEffect, useWindowScroll } from "@mantine/hooks"; +import { + useScrollIntoView, + useShallowEffect, + useWindowScroll, +} from "@mantine/hooks"; import { useAtom } from "jotai"; -import { useState } from "react"; +import { useCallback, useState } from "react"; import { gs_colab_pesan } from "../../global_state"; import { IconArrowUp, IconCircle, IconSend } from "@tabler/icons-react"; import colab_funCreateMessageByUserId from "../../fun/create/room/fun_create_message_by_user_id"; @@ -28,6 +35,10 @@ import ComponentColab_IsEmptyData from "../../component/is_empty_data"; import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/notif_global/notifikasi_gagal"; import colab_getMessageByRoomId from "../../fun/get/room_chat/get_message_by_room_id"; import mqtt_client from "@/util/mqtt_client"; +import useInfiniteScroll, { + ScrollDirection, +} from "react-easy-infinite-scroll-hook"; +import ComponentGlobal_V2_LoadingPage from "@/app_modules/component_global/loading_page_v2"; export default function Colab_DetailGrupDiskusi({ roomId, @@ -35,109 +46,167 @@ export default function Colab_DetailGrupDiskusi({ userLoginId, }: { roomId: string; - listMsg: any[]; + listMsg?: any[]; userLoginId: string; }) { - const [pesan, setPesan] = useState(""); - const [obrolan, setObrolan] = useState(listMsg); + const [msg, setMsg] = useState(""); + const [data, setData] = useState(listMsg as any); + const [page, setPage] = useState(1); + const [isLoading, setIsLoading] = useState(false); const [scroll, scrollTo] = useWindowScroll(); + const [isGet, setIsGet] = useState(true); + + const next = async (direction: ScrollDirection) => { + try { + setIsLoading(true); + await new Promise((a) => setTimeout(a, 100)); + + setPage(page + 1); + const newData = await colab_getMessageByRoomId(roomId, page + 1); + + console.log(newData); + + if (_.isEmpty(newData)) { + setIsGet(false); + } else { + setData((prev) => (direction === "up" ? [...newData, ...prev] : [])); + } + } finally { + setIsLoading(false); + } + }; + + const ref = useInfiniteScroll({ + next, + rowCount: data.length, + hasMore: { up: isGet }, + scrollThreshold: 0.1, + initialScroll: { top: 100 }, + // initialScroll: { top : -1 }, + + // onScroll() { + // scrollTo({ y: 100 }); + // }, + }); + + // const setRef = useCallback((node: any) => { + // if (node) ref.current = node._outerRef + // }, [ref]); useShallowEffect(() => { mqtt_client.subscribe(roomId); mqtt_client.on("message", (data: any, msg: any) => { - onList(setObrolan); + onList(setData); }); - }, [setObrolan]); + }, [setData]); - async function onList(setObrolan: any) { - await colab_getMessageByRoomId(roomId).then((val) => - setObrolan(_.reverse(val)) - ); + async function onList(setData: any) { + await colab_getMessageByRoomId(roomId, page).then((val) => setData(val)); } async function onSend() { - await colab_funCreateMessageByUserId(pesan, roomId).then(async (res) => { + await colab_funCreateMessageByUserId(msg, roomId).then(async (res) => { if (res.status === 200) { - mqtt_client.publish(roomId, pesan); - setPesan(""); + mqtt_client.publish(roomId, msg); + setMsg(""); } else { ComponentGlobal_NotifikasiGagal(res.message); } }); } - // if (_.isEmpty(listMsg)) - // return ; - return ( <> - - {/*
{JSON.stringify(listMsg.map((e) => e.createdAt), null,2)}
*/} - - - {_.isEmpty(obrolan) ? ( - - ) : ( - - {obrolan.map((e) => ( - - {e?.User.id === userLoginId ? ( - - - - - {e.User.Profile.name} - - {e.message} - - - {new Intl.DateTimeFormat("id-ID", { - timeStyle: "medium", - }).format(e.createdAt)} - - - - {new Intl.DateTimeFormat("id-ID", { - dateStyle: "medium", - }).format(e.createdAt)} - - - - - - ) : ( - - - - - {e.User.Profile.name} - - {e.message} - - - {new Intl.DateTimeFormat("id-ID", { - timeStyle: "medium", - }).format(e.createdAt)} - - - - {new Intl.DateTimeFormat("id-ID", { - dateStyle: "medium", - }).format(e.createdAt)} - - - - - - )} - - ))} - + + +
+ {isLoading && ( +
+ +
)} - - + {_.isEmpty(data) ? ( + + ) : ( + data.map((e, i) => ( + + {userLoginId === e?.User?.id ? ( + + + + + {e.User.Profile.name} + +
+ + + + {new Intl.DateTimeFormat("id-ID", { + timeStyle: "medium", + }).format(e.createdAt)} + + + + {new Intl.DateTimeFormat("id-ID", { + dateStyle: "medium", + }).format(e.createdAt)} + + + + + + ) : ( + + + + + {e.User.Profile.name} + +
+ + + {new Intl.DateTimeFormat("id-ID", { + timeStyle: "medium", + }).format(e.createdAt)} + + + + {new Intl.DateTimeFormat("id-ID", { + dateStyle: "medium", + }).format(e.createdAt)} + + + + + + )} + + )) + )} + {/* {isLoading && ( +
+ +
+ )} */} +
+
+ {/*
{JSON.stringify(data, null, 2)}
*/} setPesan(val.currentTarget.value)} + value={msg} + onChange={(val) => setMsg(val.currentTarget.value)} /> ); + + // const [pesan, setPesan] = useState(""); + // const [obrolan, setObrolan] = useState(listMsg); + // const [scroll, scrollTo] = useWindowScroll(); + // const [isLoading, setIsLoading] = useState(false); + + // const next = async (direction: ScrollDirection) => { + // try { + // setIsLoading(true); + // await new Promise((a) => setTimeout(a, 500)); + // const newData = await colab_getMessageByRoomId(roomId); + + // setObrolan((prev) => + // direction === "up" ? [...newData, ...prev] : [...prev, ...newData] + // ); + // } finally { + // setIsLoading(false); + // } + // }; + + // const ref = useInfiniteScroll({ + // next, + // rowCount: obrolan.length, + // hasMore: { up: true }, + // }); + + // useShallowEffect(() => { + // mqtt_client.subscribe(roomId); + + // mqtt_client.on("message", (data: any, msg: any) => { + // onList(setObrolan); + // }); + // }, [setObrolan]); + + // async function onList(setObrolan: any) { + // await colab_getMessageByRoomId(roomId).then((val) => setObrolan(val)); + // } + + // async function onSend() { + // await colab_funCreateMessageByUserId(pesan, roomId).then(async (res) => { + // if (res.status === 200) { + // mqtt_client.publish(roomId, pesan); + // scrollIntoView(); + // setPesan(""); + // } else { + // ComponentGlobal_NotifikasiGagal(res.message); + // } + // }); + // } + + // return ( + // <> + // + // {/*
{JSON.stringify(listMsg.map((e) => e.createdAt), null,2)}
*/} + // {/* + // */} + // + // {_.isEmpty(obrolan) ? ( + // + // ) : ( + //
+ // {isLoading ? ( + //
+ // + //
+ // ) : ( + // "" + // )} + // {obrolan.map((e) => ( + // + // {e?.User.id === userLoginId ? ( + // + // + // + // + // {e.User.Profile.name} + // + // {e.message} + // + // + // {new Intl.DateTimeFormat("id-ID", { + // timeStyle: "medium", + // }).format(e.createdAt)} + // + // + // + // {new Intl.DateTimeFormat("id-ID", { + // dateStyle: "medium", + // }).format(e.createdAt)} + // + // + // + // + // + // ) : ( + // + // + // + // + // {e.User.Profile.name} + // + // {e.message} + // + // + // {new Intl.DateTimeFormat("id-ID", { + // timeStyle: "medium", + // }).format(e.createdAt)} + // + // + // + // {new Intl.DateTimeFormat("id-ID", { + // dateStyle: "medium", + // }).format(e.createdAt)} + // + // + // + // + // + // )} + // + // ))} + //
+ // )} + //
+ //
+ + // + // + // + // + //