- PC: Loader chat
- QC: Auth , Profile, portofolio & user search
## No Issuue
git commit -m
This commit is contained in:
2024-05-16 10:03:34 +08:00
parent c57e495d68
commit 66b9902d97
74 changed files with 1336 additions and 622 deletions

View File

@@ -35,6 +35,7 @@
"@types/node": "20.4.5", "@types/node": "20.4.5",
"@types/react": "18.2.17", "@types/react": "18.2.17",
"@types/react-dom": "18.2.7", "@types/react-dom": "18.2.7",
"@types/react-virtualized": "^9.21.30",
"@types/uuid": "^9.0.4", "@types/uuid": "^9.0.4",
"autoprefixer": "10.4.14", "autoprefixer": "10.4.14",
"bufferutil": "^4.0.8", "bufferutil": "^4.0.8",
@@ -58,11 +59,13 @@
"react-easy-infinite-scroll-hook": "^2.1.4", "react-easy-infinite-scroll-hook": "^2.1.4",
"react-fast-marquee": "^1.6.4", "react-fast-marquee": "^1.6.4",
"react-icons": "^5.0.1", "react-icons": "^5.0.1",
"react-infinite-scroll-component": "^6.1.0",
"react-international-phone": "^4.2.6", "react-international-phone": "^4.2.6",
"react-quill": "^2.0.0", "react-quill": "^2.0.0",
"react-responsive-carousel": "^3.2.23", "react-responsive-carousel": "^3.2.23",
"react-simple-toasts": "^5.10.0", "react-simple-toasts": "^5.10.0",
"react-toastify": "^9.1.3", "react-toastify": "^9.1.3",
"react-virtualized": "^9.22.5",
"socket.io-client": "^4.7.2", "socket.io-client": "^4.7.2",
"tailwindcss": "3.3.3", "tailwindcss": "3.3.3",
"typescript": "5.1.6", "typescript": "5.1.6",

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

@@ -0,0 +1,12 @@
import prisma from "@/app/lib/prisma";
export async function GET(req: Request) {
const page = new URL(req.url).searchParams.get("page");
if (!page) return new Response("page require", { status: 400 });
const res = await prisma.projectCollaboration_Message.findMany({
take: 5,
skip: +page * 5 - 5,
});
return Response.json(res);
}

View File

@@ -1,6 +1,6 @@
import { AdminLayout } from "@/app_modules/admin/main_dashboard"; import { AdminLayout } from "@/app_modules/admin/main_dashboard";
import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token"; import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token";
import { user_getOneById } from "@/app_modules/home/fun/get/get_one_user_by_id"; import { user_getOneByUserId } from "@/app_modules/home/fun/get/get_one_user_by_id";
import React from "react"; import React from "react";
export default async function Layout({ export default async function Layout({
@@ -9,7 +9,7 @@ export default async function Layout({
children: React.ReactNode; children: React.ReactNode;
}) { }) {
const userId = await user_getOneUserId() const userId = await user_getOneUserId()
const dataUser = await user_getOneById(userId) const dataUser = await user_getOneByUserId(userId)
const userRole = dataUser?.masterUserRoleId const userRole = dataUser?.masterUserRoleId
return ( return (

View File

@@ -1,5 +1,7 @@
import adminColab_getOneRoomChatById from "@/app_modules/admin/colab/fun/get/get_one_room_chat_by_id"; import adminColab_getOneRoomChatById from "@/app_modules/admin/colab/fun/get/get_one_room_chat_by_id";
import { Colab_GroupChatView } from "@/app_modules/colab"; import { Colab_GroupChatView } from "@/app_modules/colab";
import ColabViewChat from "@/app_modules/colab/detail/chat";
import colab_V2getListMessageByRoomId from "@/app_modules/colab/fun/chat/get_message_by_room_id";
import colab_getMessageByRoomId from "@/app_modules/colab/fun/get/room_chat/get_message_by_room_id"; import colab_getMessageByRoomId from "@/app_modules/colab/fun/get/room_chat/get_message_by_room_id";
import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token"; import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token";
import _ from "lodash"; import _ from "lodash";
@@ -7,20 +9,30 @@ import _ from "lodash";
export default async function Page({ params }: { params: { id: string } }) { export default async function Page({ params }: { params: { id: string } }) {
const roomId = params.id; const roomId = params.id;
const userLoginId = await user_getOneUserId(); const userLoginId = await user_getOneUserId();
const dataRoom = (await adminColab_getOneRoomChatById({ roomId: roomId })) const getData = (await adminColab_getOneRoomChatById({ roomId: roomId }))
.data; .data;
const selectRoom = _.omit(dataRoom, [ const dataRoom = _.omit(getData, [
"ProjectCollaboration", "ProjectCollaboration",
"ProjectCollaboration_AnggotaRoomChat", "ProjectCollaboration_AnggotaRoomChat",
]); ]);
let listMsg = await colab_getMessageByRoomId({roomId: roomId, page: 1}); let listMsg = await colab_getMessageByRoomId({ roomId: roomId, page: 1 });
// const listMessage = await colab_V2getListMessageByRoomId({
// roomId: roomId,
// page: 1,
// });
return ( return (
<> <>
{/* <ColabViewChat
listMsg={listMsg as any}
dataRoom={dataRoom as any}
userLoginId={userLoginId}
/> */}
<Colab_GroupChatView <Colab_GroupChatView
userLoginId={userLoginId} userLoginId={userLoginId}
listMsg={listMsg} listMsg={listMsg}
selectRoom={selectRoom as any} selectRoom={dataRoom as any}
/> />
</> </>
); );

View File

@@ -1,6 +1,6 @@
import { LayoutForum_Forumku } from "@/app_modules/forum"; import { LayoutForum_Forumku } from "@/app_modules/forum";
import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token"; import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token";
import { user_getOneById } from "@/app_modules/home/fun/get/get_one_user_by_id"; import { user_getOneByUserId } from "@/app_modules/home/fun/get/get_one_user_by_id";
import React from "react"; import React from "react";
export default async function Layout({ export default async function Layout({
@@ -11,7 +11,7 @@ export default async function Layout({
params: { id: string }; params: { id: string };
}) { }) {
const authorId = params.id; const authorId = params.id;
const dataAuthor = await user_getOneById(authorId); const dataAuthor = await user_getOneByUserId(authorId);
return ( return (
<> <>

View File

@@ -2,14 +2,14 @@ import { Forum_Forumku } from "@/app_modules/forum";
import { forum_getListPostingByAuhtorId } from "@/app_modules/forum/fun/get/get_list_posting_by_author_id"; import { forum_getListPostingByAuhtorId } from "@/app_modules/forum/fun/get/get_list_posting_by_author_id";
import { forum_countOneTotalKomentarById } from "@/app_modules/forum/fun/count/count_one_total_komentar_by_id"; import { forum_countOneTotalKomentarById } from "@/app_modules/forum/fun/count/count_one_total_komentar_by_id";
import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token"; import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token";
import { user_getOneById } from "@/app_modules/home/fun/get/get_one_user_by_id"; import { user_getOneByUserId } from "@/app_modules/home/fun/get/get_one_user_by_id";
import _ from "lodash"; import _ from "lodash";
import { forum_countPostingByAuthorId } from "@/app_modules/forum/fun/count/count_posting_by_author_id"; import { forum_countPostingByAuthorId } from "@/app_modules/forum/fun/count/count_posting_by_author_id";
export default async function Page({ params }: { params: { id: string } }) { export default async function Page({ params }: { params: { id: string } }) {
const authorId = params.id; const authorId = params.id;
const userLoginId = await user_getOneUserId() const userLoginId = await user_getOneUserId()
const dataAuthor = await user_getOneById(authorId); const dataAuthor = await user_getOneByUserId(authorId);
const auhtorSelectedData = _.omit(dataAuthor, [ const auhtorSelectedData = _.omit(dataAuthor, [
"Profile.email", "Profile.email",
"Profile.alamat", "Profile.alamat",

View File

@@ -1,6 +1,6 @@
import { LayoutForum_Main } from "@/app_modules/forum"; import { LayoutForum_Main } from "@/app_modules/forum";
import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token"; import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token";
import { user_getOneById } from "@/app_modules/home/fun/get/get_one_user_by_id"; import { user_getOneByUserId } from "@/app_modules/home/fun/get/get_one_user_by_id";
import React from "react"; import React from "react";
export default async function Layout({ export default async function Layout({
@@ -9,7 +9,7 @@ export default async function Layout({
children: React.ReactNode; children: React.ReactNode;
}) { }) {
const authorId = await user_getOneUserId(); const authorId = await user_getOneUserId();
const dataAuthor = await user_getOneById(authorId); const dataAuthor = await user_getOneByUserId(authorId);
return ( return (
<> <>

View File

@@ -1,11 +1,11 @@
import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token"; import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token";
import { HomeLayout } from "@/app_modules/home"; import { HomeLayout } from "@/app_modules/home";
import { user_getOneById } from "@/app_modules/home/fun/get/get_one_user_by_id"; import { user_getOneByUserId } from "@/app_modules/home/fun/get/get_one_user_by_id";
import { redirect } from "next/navigation"; import { redirect } from "next/navigation";
export default async function Layout({ children }: { children: any }) { export default async function Layout({ children }: { children: any }) {
const userId = await user_getOneUserId(); const userId = await user_getOneUserId();
const dataUser = await user_getOneById(userId); const dataUser = await user_getOneByUserId(userId);
return ( return (
<> <>

View File

@@ -3,22 +3,25 @@ import { cookies } from "next/headers";
import { unsealData } from "iron-session"; import { unsealData } from "iron-session";
import _ from "lodash"; import _ from "lodash";
import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token"; import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token";
import { user_getOneById } from "@/app_modules/home/fun/get/get_one_user_by_id"; import { user_getOneByUserId } from "@/app_modules/home/fun/get/get_one_user_by_id";
import { redirect } from "next/navigation"; import { redirect } from "next/navigation";
import { RouterAdminDashboard } from "@/app/lib/router_hipmi/router_admin"; import { RouterAdminDashboard } from "@/app/lib/router_hipmi/router_admin";
import { RouterHome } from "@/app/lib/router_hipmi/router_home"; import { RouterHome } from "@/app/lib/router_hipmi/router_home";
import ComponentGlobal_V2_LoadingPage from "@/app_modules/component_global/loading_page_v2";
export default async function Page() { export default async function Page() {
const userId = await user_getOneUserId(); const userId = await user_getOneUserId();
const dataUser = await user_getOneById(userId); const dataUser = await user_getOneByUserId(userId);
if (dataUser?.active === false) { if (dataUser?.active === false) {
return redirect(RouterHome.home_user_non_active); return redirect(RouterHome.home_user_non_active);
} }
if (dataUser?.masterUserRoleId === "2" || dataUser?.masterUserRoleId === "3") if (dataUser?.masterUserRoleId === "2" || dataUser?.masterUserRoleId === "3")
return redirect(RouterAdminDashboard.splash_admin); return redirect(RouterAdminDashboard.splash_admin);
// if (dataUser?.Profile === null) return <ComponentGlobal_V2_LoadingPage />;
// await new Promise((a, b) => { // await new Promise((a, b) => {
// setTimeout(a, 4000); // setTimeout(a, 4000);
// }); // });

View File

@@ -12,13 +12,13 @@ import { funGetListPortofolio } from "@/app_modules/katalog/portofolio/fun/get/g
import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token"; import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token";
import { Profile_getOneById } from "@/app_modules/katalog/profile/fun/get/get_one_profile"; import { Profile_getOneById } from "@/app_modules/katalog/profile/fun/get/get_one_profile";
import { Profile_getOneProfileAndUserById } from "@/app_modules/katalog/profile/fun/get/get_one_user_profile"; import { Profile_getOneProfileAndUserById } from "@/app_modules/katalog/profile/fun/get/get_one_user_profile";
import { user_getOneById } from "@/app_modules/home/fun/get/get_one_user_by_id"; import { user_getOneByUserId } from "@/app_modules/home/fun/get/get_one_user_by_id";
const config = yaml.parse(fs.readFileSync("config.yaml").toString()); const config = yaml.parse(fs.readFileSync("config.yaml").toString());
export default async function Page({ params }: { params: { id: string } }) { export default async function Page({ params }: { params: { id: string } }) {
let profileId = params.id; let profileId = params.id;
const authorId = await user_getOneUserId(); const authorId = await user_getOneUserId();
const dataUser = await user_getOneById(authorId) const dataUser = await user_getOneByUserId(authorId)
const listPorto = await funGetListPortofolio(profileId); const listPorto = await funGetListPortofolio(profileId);
const dataProfile = await Profile_getOneProfileAndUserById(profileId); const dataProfile = await Profile_getOneProfileAndUserById(profileId);

View File

@@ -1,10 +0,0 @@
import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token";
import { CreateProfile } from "@/app_modules/katalog/profile";
export default async function Page({params}: {params: {id: string}}) {
const userId = await user_getOneUserId()
return <>
<CreateProfile userId={userId}/>
</>
}

View File

@@ -0,0 +1,12 @@
import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token";
import { CreateProfile } from "@/app_modules/katalog/profile";
export default async function Page() {
const userId = await user_getOneUserId();
return (
<>
<CreateProfile userId={userId} />
</>
);
}

View File

@@ -2,12 +2,12 @@ import { RouterAdminDashboard } from "@/app/lib/router_hipmi/router_admin";
import { RouterHome } from "@/app/lib/router_hipmi/router_home"; import { RouterHome } from "@/app/lib/router_hipmi/router_home";
import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token"; import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token";
import { Home_UserNonActive } from "@/app_modules/home"; import { Home_UserNonActive } from "@/app_modules/home";
import { user_getOneById } from "@/app_modules/home/fun/get/get_one_user_by_id"; import { user_getOneByUserId } from "@/app_modules/home/fun/get/get_one_user_by_id";
import { redirect } from "next/navigation"; import { redirect } from "next/navigation";
export default async function Page() { export default async function Page() {
const userId = await user_getOneUserId(); const userId = await user_getOneUserId();
const dataUser = await user_getOneById(userId); const dataUser = await user_getOneByUserId(userId);
if (dataUser?.active === true) { if (dataUser?.active === true) {
return redirect(RouterHome.main_home); return redirect(RouterHome.main_home);

View File

@@ -2,7 +2,7 @@ import { UserSearch_MainView } from "@/app_modules/user_search";
import { UserSearch_getListUser } from "@/app_modules/user_search/fun/get/get_list_user"; import { UserSearch_getListUser } from "@/app_modules/user_search/fun/get/get_list_user";
export default async function Page() { export default async function Page() {
const listUser = await UserSearch_getListUser() const listUser = await UserSearch_getListUser({ name: "" });
return <UserSearch_MainView listUser={listUser as any} />; return <UserSearch_MainView listUser={listUser as any} />;
} }

View File

@@ -33,7 +33,7 @@ export default function RootStyleRegistry({
<body suppressHydrationWarning={true}> <body suppressHydrationWarning={true}>
<CacheProvider value={cache}> <CacheProvider value={cache}>
<MantineProvider withGlobalStyles withNormalizeCSS> <MantineProvider withGlobalStyles withNormalizeCSS>
<Notifications position="top-center" containerWidth="250px" /> <Notifications position="top-center" containerWidth={300} />
{children} {children}
{/* <ToastContainer position="bottom-center" /> {/* <ToastContainer position="bottom-center" />
<AppNotif /> */} <AppNotif /> */}

View File

@@ -2,7 +2,7 @@ export const RouterProfile = {
katalog: "/dev/katalog/", katalog: "/dev/katalog/",
// create // create
create: "/dev/profile/create/", create: "/dev/profile/create",
// edit // edit
edit: "/dev/profile/edit/", edit: "/dev/profile/edit/",

View File

@@ -5,34 +5,76 @@ import useInfiniteScroll, {
} from "react-easy-infinite-scroll-hook"; } from "react-easy-infinite-scroll-hook";
import { createItems, loadMore } from "./_util"; import { createItems, loadMore } from "./_util";
import { useShallowEffect } from "@mantine/hooks"; import { useShallowEffect } from "@mantine/hooks";
import { Center, Loader } from "@mantine/core"; import { Center, Loader, Text } from "@mantine/core";
// Beda Package
import InfiniteScroll from "react-infinite-scroll-component";
export default function App() { export default function App() {
const [data, setData] = useState<any[]>([]); const [data, setData] = useState<any[]>([]);
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
useShallowEffect(() => { const ttlData = Array.from({ length: 21 });
setData(createItems()); const [list, setList] = useState<any[]>(ttlData);
}, []);
const next = async (direction: ScrollDirection) => { // useShallowEffect(() => {
console.log("next", direction); // setData(createItems());
try { // }, []);
setIsLoading(true);
const newData = await loadMore();
const d = direction === "up" ? [...newData, ...data] : []; // const next = async (direction: ScrollDirection) => {
setData(d); // console.log("next", direction);
} finally { // try {
setIsLoading(false); // 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 },
// });
const fetchMoreData = () => {
setTimeout(() => {
setList(list.concat(Array.from({ length: 20 })));
}, 100);
}; };
const ref = useInfiniteScroll({ const style = {
next, height: 30,
rowCount: data.length, border: "1px solid green",
hasMore: { up: true }, margin: 6,
}); padding: 8,
};
return (
<>
<div id="scrollableDiv" style={{ height: "100vh", overflow: "auto" }}>
<InfiniteScroll
dataLength={list.length}
next={fetchMoreData}
hasMore={true}
loader={
<center>
<h4>Loading...</h4>
</center>
}
scrollableTarget="scrollableDiv"
>
{list.map((i, index) => (
<div style={style} key={index}>
div - #{index}
</div>
))}
</InfiniteScroll>
</div>
</>
);
return ( return (
<Center> <Center>
@@ -40,7 +82,7 @@ export default function App() {
<Center>{isLoading && <Loader />}</Center> <Center>{isLoading && <Loader />}</Center>
<div <div
ref={ref as any} // ref={ref as any}
className="List" className="List"
style={{ style={{
height: 500, height: 500,

View File

@@ -181,7 +181,7 @@ function TableMenu({ listGroup }: { listGroup: any }) {
<Center>Industri</Center> <Center>Industri</Center>
</th> </th>
<th> <th>
<Center>Jumlah Partisipan</Center> <Center>Anggota Group</Center>
</th> </th>
<th> <th>
<Center>Aksi</Center> <Center>Aksi</Center>
@@ -222,7 +222,7 @@ function TableMenu({ listGroup }: { listGroup: any }) {
<ScrollArea h={"100%"}> <ScrollArea h={"100%"}>
<Stack> <Stack>
<Center> <Center>
<Title order={4}>Partisipan</Title> <Title order={4}>Anggota</Title>
</Center> </Center>
<Stack> <Stack>
{detailData?.ProjectCollaboration_AnggotaRoomChat?.map( {detailData?.ProjectCollaboration_AnggotaRoomChat?.map(

View File

@@ -45,5 +45,5 @@ export async function auth_funValidasi(nomor: string) {
return { status: 200, message: "Nomor Terverivikasi", role: cek.masterUserRoleId }; return { status: 200, message: "Nomor Terverifikasi", role: cek.masterUserRoleId };
} }

View File

@@ -35,46 +35,24 @@ export default function Register({ dataOtp }: { dataOtp: any }) {
const focusTrapRef = useFocusTrap(); const focusTrapRef = useFocusTrap();
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
// const onRegister = async () => {
// myConsole(value);
// const body = {
// username: _.lowerCase(value),
// nomor: nomor,
// };
// if (!body) return toast("Lengkapi username");
// if (body.username.length < 5) return toast("Username minimal 5 karakter");
// await fetch(ApiHipmi.register, {
// method: "POST",
// headers: {
// "Content-Type": "application/json",
// },
// body: JSON.stringify(body),
// })
// .then((res) => res.json())
// .then((val) => {
// myConsole(val);
// if (val.status == 201) {
// toast("Pendaftaran Berhasil");
// return route.push("/dev/home");
// } else {
// return toast(val.message);
// }
// });
// };
async function onRegistarsi() { async function onRegistarsi() {
const body = { const body = {
username: _.lowerCase(value), username: value,
nomor: nomor, nomor: nomor,
}; };
// console.log(body);
if (_.values(body.username).includes("")) if (body.username === "")
return ComponentGlobal_NotifikasiPeringatan("Lengkapi Username"); return ComponentGlobal_NotifikasiPeringatan("Lengkapi Username");
if (body.username.length < 5) if (body.username.length < 5)
return ComponentGlobal_NotifikasiPeringatan("Username minimal 5 krakter"); return ComponentGlobal_NotifikasiPeringatan("Username tidak sesuai");
if (_.values(body.username).includes(" "))
return ComponentGlobal_NotifikasiPeringatan(
"Username tidak sesuai",
3000
);
await Auth_funRegister(body).then(async (res) => { await Auth_funRegister(body).then(async (res) => {
if (res.status === 200) { if (res.status === 200) {
@@ -118,6 +96,18 @@ export default function Register({ dataOtp }: { dataOtp: any }) {
<TextInput <TextInput
ref={focusTrapRef} ref={focusTrapRef}
placeholder="Masukan Username" placeholder="Masukan Username"
error={
value.length > 0 && value.length < 5 ? (
<Text>Minimal 5 karakter</Text>
) : _.values(value).includes(" ") ? (
<Stack spacing={0}>
<Text>- Tidak boleh ada space</Text>
<Text>- Sambungkan huruf meggunakan karakter _</Text>
</Stack>
) : (
""
)
}
onChange={(val) => { onChange={(val) => {
setValue(val.currentTarget.value); setValue(val.currentTarget.value);
}} }}

View File

@@ -11,7 +11,7 @@ export default function ComponentColab_NotedBox({
<Group> <Group>
<Text fz={10} fs={"italic"}> <Text fz={10} fs={"italic"}>
<Text span inherit c={"red"}> <Text span inherit c={"red"}>
*{" "} Alasan:{" "}
</Text> </Text>
{informasi} {informasi}
</Text> </Text>

View File

@@ -0,0 +1,324 @@
"use client";
import { RouterColab } from "@/app/lib/router_hipmi/router_colab";
import {
ActionIcon,
Box,
Button,
Card,
Center,
Code,
Grid,
Group,
Header,
Loader,
Paper,
ScrollArea,
Stack,
Text,
Textarea,
Title,
} from "@mantine/core";
import {
IconChevronLeft,
IconCircle,
IconInfoSquareRounded,
IconSend,
} from "@tabler/icons-react";
import { useRouter } from "next/navigation";
import router from "next/router";
import React, { useRef, useState } from "react";
import {
MODEL_COLLABORATION_MESSAGE,
MODEL_COLLABORATION_ROOM_CHAT,
} from "../../model/interface";
import _ from "lodash";
import ComponentColab_IsEmptyData from "../../component/is_empty_data";
import colab_getMessageByRoomId from "../../fun/get/room_chat/get_message_by_room_id";
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/notif_global/notifikasi_gagal";
import colab_funCreateMessageByUserId from "../../fun/create/room/fun_create_message_by_user_id";
import { useShallowEffect } from "@mantine/hooks";
import mqtt_client from "@/util/mqtt_client";
import useInfiniteScroll, {
ScrollDirection,
ScrollDirectionBooleanState,
} from "react-easy-infinite-scroll-hook";
import toast from "react-simple-toasts";
import colab_getOneMessageById from "../../fun/get/room_chat/get_one_message_by_id";
import { List } from "react-virtualized";
const list = Array(100).fill(0);
export default function ColabViewChat({
userLoginId,
listMsg,
dataRoom,
}: {
userLoginId: string;
listMsg: MODEL_COLLABORATION_MESSAGE[];
dataRoom?: MODEL_COLLABORATION_ROOM_CHAT | any;
}) {
// Tamplate app layout
const router = useRouter();
const [loadingBack, setLoadingBack] = useState(false);
const [loadingInfo, setLoadingInfo] = useState(false);
// State message
const [msg, setMsg] = useState("");
const [data, setData] = useState(listMsg);
// State infinite scroll
const [isLoading, setIsLoading] = useState(false);
const [totalPage, setTotalPage] = useState(1);
const [hasMore, setHasMore] = useState<ScrollDirectionBooleanState>({
up: true,
down: false,
});
// Kirim pesan
async function onSend() {
await colab_funCreateMessageByUserId(msg, dataRoom.id).then(async (res) => {
if (res.status === 200) {
const newData = await colab_getMessageByRoomId({
roomId: dataRoom?.id,
page: 1,
});
setData(newData as any);
setHasMore({ up: true });
setMsg("");
} else {
ComponentGlobal_NotifikasiGagal(res.message);
}
});
}
const next = async (direction: ScrollDirection) => {
try {
setIsLoading(true);
await new Promise((a) => setTimeout(a, 500));
const newData = await colab_getMessageByRoomId({
roomId: dataRoom?.id,
page: totalPage + 1,
});
setTotalPage(totalPage + 1);
// console.log(newData, "loading baru");
if (_.isEmpty(newData)) {
setHasMore({ up: false });
} else {
const d: any =
direction === "down" ? [...data, ...newData] : [...newData, ...data];
setData(d);
}
} finally {
setIsLoading(false);
}
};
const ref: any = useInfiniteScroll({
next,
rowCount: data.length,
hasMore,
scrollThreshold: 0.1,
});
return (
<>
<Box h={"100vh"}>
{/* Header */}
<Box
style={{
zIndex: 99,
}}
w={"100%"}
pos={"fixed"}
top={0}
h={"7vh"}
>
<Stack bg={"gray.2"} h={"100%"} justify="center" px={"sm"}>
<Grid grow gutter={"lg"}>
<Grid.Col span={2}>
<ActionIcon
loading={loadingBack ? true : false}
variant="transparent"
radius={"xl"}
onClick={() => {
setLoadingBack(true);
router.back();
}}
>
<IconChevronLeft />
</ActionIcon>
</Grid.Col>
<Grid.Col span={8}>
<Center>
<Title order={5} lineClamp={1}>
{dataRoom?.name}
</Title>
</Center>
</Grid.Col>
<Grid.Col span={2}>
<Group position="right">
<ActionIcon
loading={loadingInfo ? true : false}
variant="transparent"
radius={"xl"}
onClick={() => {
setLoadingInfo(true);
router.push(RouterColab.info_grup + dataRoom?.id);
}}
>
<IconInfoSquareRounded />
</ActionIcon>
</Group>
</Grid.Col>
</Grid>
</Stack>
</Box>
{/* Main View */}
<Box pos={"static"}>
<Box
style={{
height: "7vh",
display: "flex",
flexDirection: "column-reverse",
}}
/>
{/* Chat View */}
<Box h={"82vh"} px={"xs"}>
<Stack justify="flex-end" h={"100%"}>
<div
ref={ref as any}
style={{
overflowY: "auto",
}}
>
{isLoading && (
<Center>
<Loader size={20} color="gray" />
</Center>
)}
{_.isEmpty(data) ? (
<ComponentColab_IsEmptyData text="Belum ada pesan" />
) : (
data.map((e, i) => (
<Box key={i}>
{userLoginId === e?.User?.id ? (
<Group position="right">
<Paper key={e?.id} bg={"blue.2"} p={"sm"} mt={"sm"}>
<Stack spacing={0}>
<Text lineClamp={1} fw={"bold"} fz={"xs"}>
{e?.User?.Profile?.name}
</Text>
<div
dangerouslySetInnerHTML={{ __html: e?.message }}
/>
{/* <Group spacing={"xs"}>
<Text fz={7}>
{new Intl.DateTimeFormat("id-ID", {
timeStyle: "medium",
}).format(e.createdAt)}
</Text>
<IconCircle size={3} />
<Text fz={7}>
{new Intl.DateTimeFormat("id-ID", {
dateStyle: "medium",
}).format(e.createdAt)}
</Text>
</Group> */}
</Stack>
</Paper>
</Group>
) : (
<Group>
<Paper key={e?.id} bg={"cyan.2"} p={"sm"} mt={"sm"}>
<Stack spacing={0}>
<Text lineClamp={1} fw={"bold"} fz={"xs"}>
{e?.User?.Profile?.name}
</Text>
<div
dangerouslySetInnerHTML={{ __html: e?.message }}
/>
{/* <Group spacing={"xs"}>
<Text fz={7}>
{new Intl.DateTimeFormat("id-ID", {
timeStyle: "medium",
}).format(e.createdAt)}
</Text>
<IconCircle size={3} />
<Text fz={7}>
{new Intl.DateTimeFormat("id-ID", {
dateStyle: "medium",
}).format(e.createdAt)}
</Text>
</Group> */}
</Stack>
</Paper>
</Group>
)}
</Box>
))
)}
</div>
</Stack>
</Box>
<Box
style={{
height: "11vh",
}}
/>
</Box>
{/* Footer */}
<Box
style={{
zIndex: 98,
}}
w={"100%"}
pos={"fixed"}
bottom={0}
h={"10vh"}
bg={"gray.2"}
>
<Stack justify="center" h={"100%"} px={"sm"}>
<Grid align="center">
<Grid.Col span={"auto"}>
<Textarea
value={msg}
minRows={1}
radius={"md"}
placeholder="Ketik pesan anda..."
onChange={(val) => {
setMsg(val.currentTarget.value);
}}
/>
</Grid.Col>
<Grid.Col span={"content"}>
<ActionIcon
disabled={msg ? false : true}
variant="filled"
bg={"cyan"}
radius={"xl"}
size={"xl"}
onClick={() => {
onSend();
}}
>
<IconSend size={20} />
</ActionIcon>
</Grid.Col>
</Grid>
</Stack>
</Box>
</Box>
</>
);
}

View File

@@ -4,7 +4,10 @@ import { RouterColab } from "@/app/lib/router_hipmi/router_colab";
import { import {
ActionIcon, ActionIcon,
Box, Box,
Button,
Card,
Center, Center,
Code,
Grid, Grid,
Group, Group,
Header, Header,
@@ -25,7 +28,10 @@ import {
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import router from "next/router"; import router from "next/router";
import { useRef, useState } from "react"; import { useRef, useState } from "react";
import { MODEL_COLLABORATION_ROOM_CHAT } from "../../model/interface"; import {
MODEL_COLLABORATION_MESSAGE,
MODEL_COLLABORATION_ROOM_CHAT,
} from "../../model/interface";
import _ from "lodash"; import _ from "lodash";
import ComponentColab_IsEmptyData from "../../component/is_empty_data"; import ComponentColab_IsEmptyData from "../../component/is_empty_data";
import colab_getMessageByRoomId from "../../fun/get/room_chat/get_message_by_room_id"; import colab_getMessageByRoomId from "../../fun/get/room_chat/get_message_by_room_id";
@@ -36,6 +42,8 @@ import mqtt_client from "@/util/mqtt_client";
import useInfiniteScroll, { import useInfiniteScroll, {
ScrollDirection, ScrollDirection,
} from "react-easy-infinite-scroll-hook"; } from "react-easy-infinite-scroll-hook";
import toast from "react-simple-toasts";
import colab_getOneMessageById from "../../fun/get/room_chat/get_one_message_by_id";
export default function Colab_GroupChatView({ export default function Colab_GroupChatView({
userLoginId, userLoginId,
@@ -50,61 +58,43 @@ export default function Colab_GroupChatView({
const [loadingBack, setLoadingBack] = useState(false); const [loadingBack, setLoadingBack] = useState(false);
const [loadingInfo, setLoadingInfo] = useState(false); const [loadingInfo, setLoadingInfo] = useState(false);
const [msg, setMsg] = useState(""); const [msg, setMsg] = useState("");
const [newMessage, setNewMessage] = useState<any>();
const [data, setData] = useState<any[]>(listMsg); const [data, setData] = useState<any[]>(listMsg);
const [totalPage, setTotalPage] = useState(1); const [totalPage, setTotalPage] = useState(1);
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [isGet, setIsGet] = useState(true); const [isGet, setIsGet] = useState(true);
const viewport = useRef<HTMLDivElement>(null); const next = async (direction: ScrollDirection) => {
try {
setIsLoading(true);
await new Promise((a) => setTimeout(a, 500));
// const next = async (direction: ScrollDirection) => { const newData = await colab_getMessageByRoomId({
// try { roomId: selectRoom?.id,
// setIsLoading(true); page: totalPage + 1,
// await new Promise((a) => setTimeout(a, 500)); });
setTotalPage(totalPage + 1);
// const newData = await colab_getMessageByRoomId({ // console.log(newData, "loading baru");
// roomId: selectRoom?.id,
// page: totalPage + 1,
// });
// setTotalPage(totalPage + 1);
// // console.log(newData, "loading baru"); if (_.isEmpty(newData)) {
setIsGet(false);
} else {
const d =
direction === "down" ? [...data, ...newData] : [...newData, ...data];
setData(d);
}
} finally {
setIsLoading(false);
}
};
// if (_.isEmpty(newData)) { const ref = useInfiniteScroll({
// setIsGet(false); next,
// } else { rowCount: data.length,
// const d = hasMore: { up: isGet },
// direction === "down" ? [...data, ...newData] : [...newData, ...data]; scrollThreshold: 0.1,
// setData(d); });
// }
// } finally {
// setIsLoading(false);
// }
// };
// const ref = useInfiniteScroll({
// next,
// rowCount: data.length,
// hasMore: { up: isGet },
// });
useShallowEffect(() => {
mqtt_client.subscribe(selectRoom.id);
mqtt_client.on("message", () => {
onList(setData);
});
}, [setData]);
async function onList(setData: any) {
await colab_getMessageByRoomId({
roomId: selectRoom?.id,
page: 1,
}).then((val) => {
setData(val);
setTotalPage(totalPage);
});
}
async function onSend() { async function onSend() {
await colab_funCreateMessageByUserId(msg, selectRoom.id).then( await colab_funCreateMessageByUserId(msg, selectRoom.id).then(
@@ -112,6 +102,22 @@ export default function Colab_GroupChatView({
if (res.status === 200) { if (res.status === 200) {
mqtt_client.publish(selectRoom.id, msg); mqtt_client.publish(selectRoom.id, msg);
setMsg(""); setMsg("");
// const d = JSON.parse(JSON.stringify(res.data));
// setData([...data, ...[d]]);
await colab_getOneMessageById({
messageId: res.data?.id as any,
}).then((res) => {
// setNewMessage(res);
// console.log(res);
// const d = JSON.parse(JSON.stringify(res));
// setData([...data, ...[d]]);
mqtt_client.on("message", (a,b) => {
setData([...data, ...[res]])
})
});
} else { } else {
ComponentGlobal_NotifikasiGagal(res.message); ComponentGlobal_NotifikasiGagal(res.message);
} }
@@ -119,10 +125,41 @@ export default function Colab_GroupChatView({
); );
} }
useShallowEffect(() => {
mqtt_client.subscribe(selectRoom.id);
// mqtt_client.on("message", (a, b) => {
// // loadDataNew(b.toString());
// // onList(b);
// onList2(newMessage);
// });
}, []);
async function onList2(dt: any) {
console.log(dt);
setData([...data, ...[dt]]);
}
// const loadDataNew = (dt: any) => {
// setData([JSON.parse(dt),...data]);
// };
async function onList(b: any) {
await colab_getMessageByRoomId({
roomId: selectRoom?.id,
page: 1,
}).then((val) => {
const d = JSON.parse(JSON.stringify(val[5]));
setData([...data, ...[d]]);
// setTotalPage(totalPage);
});
}
return ( return (
<> <>
<Box h={"100vh"}> <Box h={"100vh"}>
{/* Header */} {/* Header */}
<Box <Box
style={{ style={{
zIndex: 99, zIndex: 99,
@@ -186,7 +223,7 @@ export default function Colab_GroupChatView({
<Box h={"80vh"}> <Box h={"80vh"}>
<Stack justify="flex-end" h={"100%"}> <Stack justify="flex-end" h={"100%"}>
<div <div
// ref={ref as any} ref={ref as any}
style={{ style={{
overflowY: "auto", overflowY: "auto",
}} }}
@@ -203,16 +240,16 @@ export default function Colab_GroupChatView({
<Box key={i}> <Box key={i}>
{userLoginId === e?.User?.id ? ( {userLoginId === e?.User?.id ? (
<Group position="right"> <Group position="right">
<Paper key={e.id} bg={"blue.2"} p={"sm"} mt={"sm"}> <Paper key={e?.id} bg={"blue.2"} p={"sm"} mt={"sm"}>
<Stack spacing={0}> <Stack spacing={0}>
<Text lineClamp={1} fw={"bold"} fz={"xs"}> <Text lineClamp={1} fw={"bold"} fz={"xs"}>
{e.User.Profile.name} {e?.User?.Profile?.name}
</Text> </Text>
<div <div
dangerouslySetInnerHTML={{ __html: e.message }} dangerouslySetInnerHTML={{ __html: e?.message }}
/> />
<Group spacing={"xs"}> {/* <Group spacing={"xs"}>
<Text fz={7}> <Text fz={7}>
{new Intl.DateTimeFormat("id-ID", { {new Intl.DateTimeFormat("id-ID", {
timeStyle: "medium", timeStyle: "medium",
@@ -224,21 +261,21 @@ export default function Colab_GroupChatView({
dateStyle: "medium", dateStyle: "medium",
}).format(e.createdAt)} }).format(e.createdAt)}
</Text> </Text>
</Group> </Group> */}
</Stack> </Stack>
</Paper> </Paper>
</Group> </Group>
) : ( ) : (
<Group> <Group>
<Paper key={e.id} bg={"cyan.2"} p={"sm"} mt={"sm"}> <Paper key={e?.id} bg={"cyan.2"} p={"sm"} mt={"sm"}>
<Stack spacing={0}> <Stack spacing={0}>
<Text lineClamp={1} fw={"bold"} fz={"xs"}> <Text lineClamp={1} fw={"bold"} fz={"xs"}>
{e.User.Profile.name} {e?.User?.Profile?.name}
</Text> </Text>
<div <div
dangerouslySetInnerHTML={{ __html: e.message }} dangerouslySetInnerHTML={{ __html: e?.message }}
/> />
<Group spacing={"xs"}> {/* <Group spacing={"xs"}>
<Text fz={7}> <Text fz={7}>
{new Intl.DateTimeFormat("id-ID", { {new Intl.DateTimeFormat("id-ID", {
timeStyle: "medium", timeStyle: "medium",
@@ -250,7 +287,7 @@ export default function Colab_GroupChatView({
dateStyle: "medium", dateStyle: "medium",
}).format(e.createdAt)} }).format(e.createdAt)}
</Text> </Text>
</Group> </Group> */}
</Stack> </Stack>
</Paper> </Paper>
</Group> </Group>
@@ -281,6 +318,14 @@ export default function Colab_GroupChatView({
h={"10vh"} h={"10vh"}
bg={"gray.2"} bg={"gray.2"}
> >
{/* <Button
onClick={() => {
const d: { [key: string]: any } = _.clone(data[0]);
setData([...data, d]);
}}
>
KIzRIM PESAN
</Button> */}
<Stack justify="center" h={"100%"} px={"sm"}> <Stack justify="center" h={"100%"} px={"sm"}>
<Grid align="center"> <Grid align="center">
<Grid.Col span={"auto"}> <Grid.Col span={"auto"}>
@@ -312,4 +357,35 @@ export default function Colab_GroupChatView({
</Box> </Box>
</> </>
); );
// return (
// <Stack bg={"dark"}>
// <Button
// onClick={() => {
// const dd = _.clone(data[0]);
// dd.message = "apa kabar";
// console.log(dd);
// mqtt_client.publish(selectRoom.id, JSON.stringify(dd));
// }}
// >
// kirim pesan
// </Button>
// <div
// ref={ref as any}
// style={{
// overflowY: "auto",
// }}
// >
// {data.map((v, k) => (
// <Stack key={k}>
// <Card withBorder shadow="md" mt={"md"}>
// <Code>
// <pre>{JSON.stringify(v, null, 2)}</pre>
// </Code>
// </Card>
// </Stack>
// ))}
// </div>
// </Stack>
// );
} }

View File

@@ -240,173 +240,212 @@ export default function Colab_DetailGrupDiskusi({
</> </>
); );
// const [pesan, setPesan] = useState(""); // "use client";
// const [obrolan, setObrolan] = useState<any[]>(listMsg);
// const [scroll, scrollTo] = useWindowScroll();
// const [isLoading, setIsLoading] = useState(false);
// const next = async (direction: ScrollDirection) => { // import { RouterColab } from "@/app/lib/router_hipmi/router_colab";
// try { // import {
// setIsLoading(true); // ActionIcon,
// await new Promise((a) => setTimeout(a, 500)); // Box,
// const newData = await colab_getMessageByRoomId(roomId); // Button,
// Card,
// Center,
// Code,
// Grid,
// Group,
// Header,
// Loader,
// Paper,
// ScrollArea,
// Stack,
// Text,
// Textarea,
// Title,
// } from "@mantine/core";
// import {
// IconChevronLeft,
// IconCircle,
// IconInfoSquareRounded,
// IconSend,
// } from "@tabler/icons-react";
// import { useRouter } from "next/navigation";
// import router from "next/router";
// import { useRef, useState } from "react";
// import {
// MODEL_COLLABORATION_MESSAGE,
// MODEL_COLLABORATION_ROOM_CHAT,
// } from "../../model/interface";
// import _ from "lodash";
// import ComponentColab_IsEmptyData from "../../component/is_empty_data";
// import colab_getMessageByRoomId from "../../fun/get/room_chat/get_message_by_room_id";
// import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/notif_global/notifikasi_gagal";
// import colab_funCreateMessageByUserId from "../../fun/create/room/fun_create_message_by_user_id";
// import { useShallowEffect } from "@mantine/hooks";
// import mqtt_client from "@/util/mqtt_client";
// import useInfiniteScroll, {
// ScrollDirection,
// } from "react-easy-infinite-scroll-hook";
// import toast from "react-simple-toasts";
// import colab_getOneMessageById from "../../fun/get/room_chat/get_one_message_by_id";
// setObrolan((prev) => // const list = Array(100).fill(0);
// direction === "up" ? [...newData, ...prev] : [...prev, ...newData] // export default function ColabViewChat({
// ); // userLoginId,
// } finally { // listMsg,
// setIsLoading(false); // dataRoom,
// }: {
// userLoginId: string;
// listMsg: any;
// dataRoom?: MODEL_COLLABORATION_ROOM_CHAT;
// }) {
// // Tamplate app layout
// const router = useRouter();
// const [loadingBack, setLoadingBack] = useState(false);
// const [loadingInfo, setLoadingInfo] = useState(false);
// // State message
// const [msg, setMsg] = useState("");
// const [data, setData] = useState(listMsg);
// const [ls, setLs] = useState(list);
// const viewport = useRef<HTMLDivElement>(null);
// const scrollBottom = () => {
// viewport.current?.scrollTo({
// top: viewport.current.scrollHeight,
// behavior: "smooth",
// });
// };
// // Kirim pesan
// async function onSend() {
// setMsg("");
// setLs([...[msg], ...ls]);
// scrollBottom();
// } // }
// };
// const ref = useInfiniteScroll({ // return (
// next, // <>
// rowCount: obrolan.length, // <Box h={"100vh"}>
// hasMore: { up: true }, // {/* Header */}
// });
// useShallowEffect(() => { // <Box
// mqtt_client.subscribe(roomId); // style={{
// zIndex: 99,
// }}
// w={"100%"}
// pos={"fixed"}
// top={0}
// h={"7vh"}
// >
// <Stack bg={"gray.2"} h={"100%"} justify="center" px={"sm"}>
// <Grid grow gutter={"lg"}>
// <Grid.Col span={2}>
// <ActionIcon
// loading={loadingBack ? true : false}
// variant="transparent"
// radius={"xl"}
// onClick={() => {
// setLoadingBack(true);
// router.back();
// }}
// >
// <IconChevronLeft />
// </ActionIcon>
// </Grid.Col>
// <Grid.Col span={8}>
// <Center>
// <Title order={5} lineClamp={1}>
// {dataRoom?.name}
// </Title>
// </Center>
// </Grid.Col>
// <Grid.Col span={2}>
// <Group position="right">
// <ActionIcon
// loading={loadingInfo ? true : false}
// variant="transparent"
// radius={"xl"}
// onClick={() => {
// setLoadingInfo(true);
// router.push(RouterColab.info_grup + dataRoom?.id);
// }}
// >
// <IconInfoSquareRounded />
// </ActionIcon>
// </Group>
// </Grid.Col>
// </Grid>
// </Stack>
// </Box>
// mqtt_client.on("message", (data: any, msg: any) => { // {/* Main View */}
// onList(setObrolan);
// });
// }, [setObrolan]);
// async function onList(setObrolan: any) { // <Box pos={"static"}>
// await colab_getMessageByRoomId(roomId).then((val) => setObrolan(val)); // <Box
// }
// 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 (
// <>
// <Box h={"79vh"}>
// {/* <pre>{JSON.stringify(listMsg.map((e) => e.createdAt), null,2)}</pre> */}
// {/* <ScrollArea h={"79vh"} scrollbarSize={2}>
// </ScrollArea> */}
// <Box>
// {_.isEmpty(obrolan) ? (
// <ComponentColab_IsEmptyData text="Belum Ada Pesan" />
// ) : (
// <div
// ref={ref as any}
// style={{ // style={{
// overflowY: "scroll", // height: "7vh",
// height: "80vh",
// }} // }}
// > // />
// {isLoading ? ( // {/* Chat View */}
// <Center> // <Box h={"83vh"} bg={"blue"}>
// <Loader color="gray" /> // <ScrollArea h={"100%"} viewportRef={viewport}>
// </Center> // {ls.map((e, i) => (
// ) : ( // <Text key={i}>{`${e + 1 + i++}`}</Text>
// "" // ))}
// )} // </ScrollArea>
// {obrolan.map((e) => ( // </Box>
// <Box key={e.id} pt={"lg"}>
// {e?.User.id === userLoginId ? ( // <Box
// <Group position="right" ref={targetRef as any}> // style={{
// <Paper key={e.id} bg={"blue.2"} p={"sm"}> // height: "10vh",
// <Stack spacing={0}> // }}
// <Text lineClamp={1} fw={"bold"} fz={"xs"}> // />
// {e.User.Profile.name} // </Box>
// </Text>
// <Text>{e.message}</Text> // {/* Footer */}
// <Group spacing={"xs"}> // <Box
// <Text fz={7}> // style={{
// {new Intl.DateTimeFormat("id-ID", { // zIndex: 98,
// timeStyle: "medium", // }}
// }).format(e.createdAt)} // w={"100%"}
// </Text> // pos={"fixed"}
// <IconCircle size={3} /> // bottom={0}
// <Text fz={7}> // h={"10vh"}
// {new Intl.DateTimeFormat("id-ID", { // bg={"gray.2"}
// dateStyle: "medium", // >
// }).format(e.createdAt)} // <Stack justify="center" h={"100%"} px={"sm"}>
// </Text> // <Grid align="center">
// </Group> // <Grid.Col span={"auto"}>
// </Stack> // <Textarea
// </Paper> // minRows={1}
// </Group> // radius={"md"}
// ) : ( // placeholder="Ketik pesan anda..."
// <Group position="left"> // onChange={(val) => {
// <Paper key={e.id} bg={"cyan.2"} p={"sm"} mr={"lg"}> // setMsg(val.currentTarget.value);
// <Stack spacing={0}> // }}
// <Text lineClamp={1} fw={"bold"} fz={10}> // />
// {e.User.Profile.name} // </Grid.Col>
// </Text> // <Grid.Col span={"content"}>
// <Text>{e.message}</Text> // <ActionIcon
// <Group spacing={"xs"}> // disabled={msg ? false : true}
// <Text fz={7}> // variant="filled"
// {new Intl.DateTimeFormat("id-ID", { // bg={"cyan"}
// timeStyle: "medium", // radius={"xl"}
// }).format(e.createdAt)} // size={"xl"}
// </Text> // onClick={() => {
// <IconCircle size={3} /> // onSend();
// <Text fz={7}> // }}
// {new Intl.DateTimeFormat("id-ID", { // >
// dateStyle: "medium", // <IconSend size={20} />
// }).format(e.createdAt)} // </ActionIcon>
// </Text> // </Grid.Col>
// </Group> // </Grid>
// </Stack> // </Stack>
// </Paper> // </Box>
// </Group> // </Box>
// )} // </>
// </Box> // );
// ))} // }
// </div>
// )}
// </Box>
// </Box>
// <Affix
// bg={"gray.2"}
// h={"10vh"}
// position={{ bottom: rem(0) }}
// w={"100%"}
// zIndex={99}
// p={"xs"}
// >
// <Stack justify="center" h={"100%"} px={"sm"}>
// <Grid align="center">
// <Grid.Col span={"auto"}>
// <Textarea
// minRows={1}
// radius={"md"}
// placeholder="Ketik pesan anda..."
// value={pesan}
// onChange={(val) => setPesan(val.currentTarget.value)}
// />
// </Grid.Col>
// <Grid.Col span={"content"}>
// <ActionIcon
// disabled={pesan === "" ? true : false}
// variant="filled"
// bg={"cyan"}
// radius={"xl"}
// size={"xl"}
// onClick={() => {
// onSend();
// }}
// >
// <IconSend size={20} />
// </ActionIcon>
// </Grid.Col>
// </Grid>
// </Stack>
// </Affix>
// </>
// );
} }

View File

@@ -0,0 +1,65 @@
"use server";
import prisma from "@/app/lib/prisma";
import _, { ceil } from "lodash";
export default async function colab_V2getListMessageByRoomId({
roomId,
page,
}: {
roomId: string;
page: number;
}) {
// console.log(page);
const lewat = page * 6 - 6;
const ambil = 6;
const awal = await prisma.projectCollaboration_Message.count({
where: {
isActive: true,
User: {
active: true,
},
},
});
const getData = await prisma.projectCollaboration_Message.findMany({
skip: lewat,
take: ambil,
orderBy: {
createdAt: "desc",
},
where: {
isActive: true,
User: {
active: true,
},
},
select: {
id: true,
createdAt: true,
isActive: true,
message: true,
isFile: true,
User: {
select: {
id: true,
Profile: {
select: {
name: true,
},
},
},
},
userId: true,
},
});
const allData = {
data: _.reverse(getData),
nPage: ceil(awal / ambil),
};
return allData;
}

View File

@@ -1,7 +1,9 @@
"use server"; "use server";
import prisma from "@/app/lib/prisma"; import prisma from "@/app/lib/prisma";
import { RouterColab } from "@/app/lib/router_hipmi/router_colab";
import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token"; import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token";
import { revalidatePath } from "next/cache";
export default async function colab_funCreateMessageByUserId( export default async function colab_funCreateMessageByUserId(
message: string, message: string,
@@ -14,8 +16,28 @@ export default async function colab_funCreateMessageByUserId(
message: message, message: message,
projectCollaboration_RoomChatId: roomId, projectCollaboration_RoomChatId: roomId,
}, },
select: {
id: true,
createdAt: true,
isActive: true,
message: true,
isFile: true,
User: {
select: {
id: true,
Profile: {
select: {
id: true,
name: true,
},
},
},
},
},
}); });
if (!msg) return { status: 400, message: "Pesan Gagal Dikirim" }; if (!msg) return { status: 400, message: "Pesan Gagal Dikirim" };
return { status: 200, message: "Pesan Berhasil Dikirim" }; revalidatePath(RouterColab.group_chat + roomId);
return { data: msg, status: 200, message: "Pesan Berhasil Dikirim" };
} }

View File

@@ -1,7 +1,9 @@
"use server"; "use server";
import prisma from "@/app/lib/prisma"; import prisma from "@/app/lib/prisma";
import { RouterColab } from "@/app/lib/router_hipmi/router_colab";
import _ from "lodash"; import _ from "lodash";
import { revalidatePath } from "next/cache";
export default async function colab_getMessageByRoomId({ export default async function colab_getMessageByRoomId({
roomId, roomId,
@@ -10,8 +12,9 @@ export default async function colab_getMessageByRoomId({
roomId: string; roomId: string;
page: number; page: number;
}) { }) {
const lewat = page * 6 - 6; const lewat = page * 10 - 10;
const ambil = 6; const ambil = 10;
const getList = await prisma.projectCollaboration_Message.findMany({ const getList = await prisma.projectCollaboration_Message.findMany({
orderBy: { orderBy: {
createdAt: "desc", createdAt: "desc",
@@ -41,8 +44,7 @@ export default async function colab_getMessageByRoomId({
}, },
}); });
const reverse = _.reverse(getList);
const reverse = _.reverse(getList)
return reverse; return reverse;
} }

View File

@@ -0,0 +1,36 @@
"use server";
import prisma from "@/app/lib/prisma";
export default async function colab_getOneMessageById({
messageId,
}: {
messageId: string;
}) {
// console.log(messageId);
const getOne = await prisma.projectCollaboration_Message.findFirst({
where: {
id: messageId,
},
select: {
id: true,
createdAt: true,
isActive: true,
message: true,
isFile: true,
User: {
select: {
id: true,
Profile: {
select: {
id: true,
name: true,
},
},
},
},
},
});
return getOne;
}

View File

@@ -70,3 +70,14 @@ export interface MODEL_COLLABORATION_NOTIFIKSI {
note: string; note: string;
ProjectCollaboration: MODEL_COLLABORATION; ProjectCollaboration: MODEL_COLLABORATION;
} }
export interface MODEL_COLLABORATION_MESSAGE {
id: string;
isActive: boolean;
createdAt: Date;
updatedAt: Date;
userId: string;
message: string;
isFile: boolean;
User: MODEL_USER;
}

View File

@@ -35,10 +35,10 @@ export default function AppComponentGlobal_LayoutTamplate({
zIndex: 99, zIndex: 99,
}} }}
w={"100%"} w={"100%"}
bg={"black"} // bg={"black"}
pos={"sticky"} pos={"sticky"}
top={0} top={0}
h={50} h={"7vh"}
> >
{header} {header}
</Box> </Box>
@@ -46,29 +46,36 @@ export default function AppComponentGlobal_LayoutTamplate({
{/* Children */} {/* Children */}
<Box p={"sm"} pos={"static"}> <Box p={"sm"} pos={"static"}>
<Stack> <Stack>
{children} {children}
<Box {footer ? (
style={{ <Box
height: "10vh", style={{
}} height: "10vh",
></Box> }}
></Box>
) : (
""
)}
</Stack> </Stack>
</Box> </Box>
{/* Footer */} {/* Footer */}
{footer ? <Box {footer ? (
style={{ <Box
zIndex: 98, style={{
}} zIndex: 98,
w={"100%"} }}
bg={"black"} w={"100%"}
pos={"fixed"} bg={"black"}
bottom={0} pos={"fixed"}
h={"10vh"} bottom={0}
> h={"10vh"}
{footer} >
</Box> : ""} {footer}
</Box>
) : (
""
)}
</Box> </Box>
</> </>
); );

View File

@@ -2,7 +2,7 @@
import prisma from "@/app/lib/prisma"; import prisma from "@/app/lib/prisma";
export async function user_getOneById(userId: string) { export async function user_getOneByUserId(userId: string) {
const data = await prisma.user.findFirst({ const data = await prisma.user.findFirst({
where: { where: {
id: userId, id: userId,

View File

@@ -41,7 +41,7 @@ export default function HomeLayout({
children: React.ReactNode; children: React.ReactNode;
}) { }) {
const router = useRouter(); const router = useRouter();
const [user, setUser] = useState(dataUser); // const [user, setUser] = useState(dataUser);
const [loadingProfil, setLoadingProfile] = useState(false); const [loadingProfil, setLoadingProfile] = useState(false);
const [loadingUS, setLoadingUS] = useState(false); const [loadingUS, setLoadingUS] = useState(false);
const listFooter = [ const listFooter = [
@@ -73,7 +73,7 @@ export default function HomeLayout({
align="center" align="center"
spacing={0} spacing={0}
onClick={() => { onClick={() => {
if (user?.Profile === null) { if (dataUser?.Profile === null) {
ComponentGlobal_NotifikasiPeringatan("Lengkapi Profile"); ComponentGlobal_NotifikasiPeringatan("Lengkapi Profile");
} else { } else {
setLoadingUS(true); setLoadingUS(true);
@@ -104,15 +104,17 @@ export default function HomeLayout({
spacing={2} spacing={2}
onClick={() => { onClick={() => {
setLoadingProfile(true); setLoadingProfile(true);
if (user?.Profile === null) { if (dataUser?.Profile === null) {
router.push(RouterProfile.create + `${user.id}`); router.push(RouterProfile.create + `${dataUser.id}`);
} else { } else {
router.push(RouterProfile.katalog + `${user.Profile.id}`); router.push(
RouterProfile.katalog + `${dataUser.Profile.id}`
);
} }
}} }}
> >
<ActionIcon variant={"transparent"}> <ActionIcon variant={"transparent"}>
{user?.Profile === null ? ( {dataUser?.Profile === null ? (
<IconUserCircle color="white" /> <IconUserCircle color="white" />
) : ( ) : (
<Avatar <Avatar
@@ -125,7 +127,7 @@ export default function HomeLayout({
}} }}
src={ src={
RouterProfile.api_foto_profile + RouterProfile.api_foto_profile +
`${user?.Profile.imagesId}` `${dataUser?.Profile.imagesId}`
} }
/> />
)} )}
@@ -197,7 +199,7 @@ export default function HomeLayout({
align="center" align="center"
spacing={0} spacing={0}
onClick={() => { onClick={() => {
if (user?.Profile === null) { if (dataUser?.Profile === null) {
ComponentGlobal_NotifikasiPeringatan( ComponentGlobal_NotifikasiPeringatan(
"Lengkapi Profile" "Lengkapi Profile"
); );
@@ -231,17 +233,17 @@ export default function HomeLayout({
spacing={2} spacing={2}
onClick={() => { onClick={() => {
setLoadingProfile(true); setLoadingProfile(true);
if (user?.Profile === null) { if (dataUser?.Profile === null) {
router.push(RouterProfile.create + `${user.id}`); router.push(RouterProfile.create);
} else { } else {
router.push( router.push(
RouterProfile.katalog + `${user.Profile.id}` RouterProfile.katalog + `${dataUser.Profile.id}`
); );
} }
}} }}
> >
<ActionIcon variant={"transparent"}> <ActionIcon variant={"transparent"}>
{user?.Profile === null ? ( {dataUser?.Profile === null ? (
<IconUserCircle color="white" /> <IconUserCircle color="white" />
) : ( ) : (
<Avatar <Avatar
@@ -254,7 +256,7 @@ export default function HomeLayout({
}} }}
src={ src={
RouterProfile.api_foto_profile + RouterProfile.api_foto_profile +
`${user?.Profile.imagesId}` `${dataUser?.Profile.imagesId}`
} }
/> />
)} )}
@@ -271,100 +273,4 @@ export default function HomeLayout({
</Box> </Box>
</> </>
); );
return (
<>
<AppShell
header={
<Header height={50} bg={"dark"}>
<Group position="center" align="center" h={50} p={"sm"}>
<Text color="white" fw={"bold"}>
HIPMI
</Text>
{/* <Logout/> */}
</Group>
</Header>
}
footer={
<Footer height={70} bg={"dark"}>
<Grid p={"xs"} bg={"blue"}>
<Grid.Col
bg={"red"}
span={"auto"}
onClick={() => {
if (user?.Profile === null) {
ComponentGlobal_NotifikasiPeringatan("Lengkapi Profile");
} else {
setLoadingUS(true);
// router.push(RouterProfile.katalog + `${user.Profile.id}`);
router.push(RouterUserSearch.main);
}
}}
>
{loadingUS ? (
<Center>
<Loader />
</Center>
) : (
<Stack align="center" spacing={0}>
<ActionIcon variant={"transparent"}>
<IconUserSearch color="white" />
</ActionIcon>
<Text fz={"xs"} c={"white"}>
Temukan pengguna
</Text>
</Stack>
)}
</Grid.Col>
<Grid.Col
bg={"cyan"}
span={"auto"}
onClick={() => {
setLoadingProfile(true);
if (user?.Profile === null) {
router.push(RouterProfile.create + `${user.id}`);
} else {
router.push(RouterProfile.katalog + `${user.Profile.id}`);
}
}}
>
{loadingProfil ? (
<Center>
<Loader />
</Center>
) : (
<Stack align="center" spacing={2}>
<ActionIcon variant={"transparent"}>
{user?.Profile === null ? (
<IconUserCircle color="white" />
) : (
<Avatar
radius={"xl"}
size={30}
sx={{
borderStyle: "solid",
borderWidth: "0.5px",
borderColor: "white",
}}
src={
RouterProfile.api_foto_profile +
`${user?.Profile.imagesId}`
}
/>
)}
</ActionIcon>
<Text fz={"xs"} c={"white"}>
Profile
</Text>
</Stack>
)}
</Grid.Col>
</Grid>
</Footer>
}
>
{children}
</AppShell>
</>
);
} }

View File

@@ -157,7 +157,9 @@ export default function HomeView({ dataUser }: { dataUser: MODEL_USER }) {
> >
{e.icon} {e.icon}
</ActionIcon> </ActionIcon>
<Text c={e.link === "" ? "gray" : "teal"} fz={"sm"}>{e.name}</Text> <Text c={e.link === "" ? "gray" : "teal"} fz={"sm"}>
{e.name}
</Text>
</Flex> </Flex>
</Paper> </Paper>
))} ))}

View File

@@ -0,0 +1,2 @@
export var validRegex =
/^([a-zA-Z0-9\.!#$%&'*+/=?^_`{|}~-]+)@([a-zA-Z0-9])+.([a-z]+)(.[a-z]+)?$/;

View File

@@ -17,7 +17,7 @@ import {
import { ProfileView } from "../profile"; import { ProfileView } from "../profile";
import { ListPortofolioView } from "../portofolio"; import { ListPortofolioView } from "../portofolio";
import { MODEL_PROFILE_OLD } from "@/app_modules/home/model/user_profile"; import { MODEL_PROFILE_OLD } from "@/app_modules/home/model/user_profile";
import { LIST_PORTOFOLIO } from "@/app_modules/model_global/portofolio"; import { MODEL_PORTOFOLIO_Lama } from "@/app_modules/model_global/portofolio";
import User_Logout from "@/app_modules/auth/logout/view"; import User_Logout from "@/app_modules/auth/logout/view";
import { MODEL_PORTOFOLIO } from "../portofolio/model/interface"; import { MODEL_PORTOFOLIO } from "../portofolio/model/interface";
import { MODEL_PROFILE } from "../profile/model/interface"; import { MODEL_PROFILE } from "../profile/model/interface";
@@ -28,10 +28,9 @@ export default function KatalogView({
userLoginId, userLoginId,
}: { }: {
profile: MODEL_PROFILE; profile: MODEL_PROFILE;
listPorto: LIST_PORTOFOLIO; listPorto: MODEL_PORTOFOLIO;
userLoginId: string; userLoginId: string;
}) { }) {
return ( return (
<> <>
<Stack> <Stack>
@@ -41,9 +40,9 @@ export default function KatalogView({
profile={profile} profile={profile}
userLoginId={userLoginId} userLoginId={userLoginId}
/> />
<Stack my={"lg"} w={"100%"}> <Stack my={"lg"} w={"100%"}>
{profile?.User.id === userLoginId ? <User_Logout /> : ""} {profile?.User.id === userLoginId ? <User_Logout /> : ""}
</Stack> </Stack>
</Stack> </Stack>
</> </>
); );

View File

@@ -72,6 +72,7 @@ export default function CreatePortofolio({
withAsterisk withAsterisk
label="Nama Bisnis" label="Nama Bisnis"
placeholder="Nama bisnis" placeholder="Nama bisnis"
error={value.namaBisnis.length > 100 ? "Maksimal 100 karakter" : ""}
onChange={(val) => { onChange={(val) => {
setValue({ setValue({
...value, ...value,
@@ -98,6 +99,9 @@ export default function CreatePortofolio({
withAsterisk withAsterisk
label="Alamat Kantor" label="Alamat Kantor"
placeholder="Alamat kantor" placeholder="Alamat kantor"
error={
value.alamatKantor.length > 100 ? "Maksimal 100 karakter" : ""
}
onChange={(val) => { onChange={(val) => {
setValue({ setValue({
...value, ...value,
@@ -108,7 +112,7 @@ export default function CreatePortofolio({
<TextInput <TextInput
withAsterisk withAsterisk
label="Nomor Telepon Kantor" label="Nomor Telepon Kantor"
placeholder="62 xxx xxx xxx" placeholder="Nomor telepon kantor"
type="number" type="number"
onChange={(val) => { onChange={(val) => {
setValue({ setValue({
@@ -124,6 +128,7 @@ export default function CreatePortofolio({
withAsterisk withAsterisk
label="Deskripsi" label="Deskripsi"
placeholder="Deskripsi singkat mengenai usaha" placeholder="Deskripsi singkat mengenai usaha"
error={value.deskripsi.length > 150 ? "Maksimal 150 karakter" : ""}
onChange={(val) => { onChange={(val) => {
setValue({ setValue({
...value, ...value,
@@ -270,7 +275,11 @@ async function onSubmit(
if (_.values(porto).includes("")) if (_.values(porto).includes(""))
return ComponentGlobal_NotifikasiPeringatan("Lengkapi Data"); return ComponentGlobal_NotifikasiPeringatan("Lengkapi Data");
if (!file) if (!file)
return ComponentGlobal_NotifikasiPeringatan("Lengkapi logo binnis"); return ComponentGlobal_NotifikasiPeringatan("Lengkapi logo bisnis");
if (porto.namaBisnis.length > 100) return null;
if (porto.alamatKantor.length > 100) return null;
if (porto.deskripsi.length > 150) return null;
const gambar = new FormData(); const gambar = new FormData();
gambar.append("file", file as any); gambar.append("file", file as any);

View File

@@ -12,6 +12,7 @@ import { useRouter } from "next/navigation";
import { Portofolio_funEditDataBisnis } from "../../fun/edit/fun_edit_data_bisnis_by_id"; import { Portofolio_funEditDataBisnis } from "../../fun/edit/fun_edit_data_bisnis_by_id";
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/component_global/notif_global/notifikasi_berhasil"; 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 { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/notif_global/notifikasi_gagal";
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/component_global/notif_global/notifikasi_peringatan";
export default function Portofolio_EditDataBisnis({ export default function Portofolio_EditDataBisnis({
dataPorto, dataPorto,
@@ -21,15 +22,9 @@ export default function Portofolio_EditDataBisnis({
listBidang: MODEL_PORTOFOLIO_BIDANG_BISNIS[]; listBidang: MODEL_PORTOFOLIO_BIDANG_BISNIS[];
}) { }) {
const router = useRouter(); const router = useRouter();
const [porto, setPorto] = useState(dataPorto); const [value, setValue] = useState(dataPorto);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
// const [value, setPorto] = useState({
// namaBisnis: "",
// masterBidangBisnisId: "",
// alamatKantor: "",
// tlpn: "",
// deskripsi: "",
// });
return ( return (
<> <>
{/* <pre>{JSON.stringify(porto, null, 2)}</pre> */} {/* <pre>{JSON.stringify(porto, null, 2)}</pre> */}
@@ -37,19 +32,20 @@ export default function Portofolio_EditDataBisnis({
<Stack> <Stack>
<TextInput <TextInput
withAsterisk withAsterisk
value={porto.namaBisnis} value={value.namaBisnis}
label="Nama Bisnis" label="Nama Bisnis"
placeholder="Nama bisnis" placeholder="Nama bisnis"
error={value.namaBisnis.length > 100 ? "Maksimal 100 karakter" : ""}
onChange={(val) => { onChange={(val) => {
setPorto({ setValue({
...porto, ...value,
namaBisnis: val.target.value, namaBisnis: val.target.value,
}); });
}} }}
/> />
<Select <Select
withAsterisk withAsterisk
value={porto.MasterBidangBisnis.id} value={value.MasterBidangBisnis.id}
label="Bidang Bisnis" label="Bidang Bisnis"
placeholder="Pilih salah satu bidang bisnis" placeholder="Pilih salah satu bidang bisnis"
data={listBidang.map((e) => ({ data={listBidang.map((e) => ({
@@ -57,8 +53,8 @@ export default function Portofolio_EditDataBisnis({
label: e.name, label: e.name,
}))} }))}
onChange={(val) => { onChange={(val) => {
setPorto({ setValue({
...(porto as any), ...(value as any),
MasterBidangBisnis: { MasterBidangBisnis: {
id: val, id: val,
}, },
@@ -67,25 +63,28 @@ export default function Portofolio_EditDataBisnis({
/> />
<TextInput <TextInput
withAsterisk withAsterisk
value={porto.alamatKantor} value={value.alamatKantor}
label="Alamat Kantor" label="Alamat Kantor"
placeholder="Alamat kantor" placeholder="Alamat kantor"
error={
value.alamatKantor.length > 100 ? "Maksimal 100 karakter" : ""
}
onChange={(val) => { onChange={(val) => {
setPorto({ setValue({
...porto, ...value,
alamatKantor: val.target.value, alamatKantor: val.target.value,
}); });
}} }}
/> />
<TextInput <TextInput
withAsterisk withAsterisk
value={porto.tlpn} value={value.tlpn}
label="Nomor Telepon Kantor" label="Nomor Telepon Kantor"
placeholder="62 xxx xxx xxx" placeholder="62 xxx xxx xxx"
type="number" type="number"
onChange={(val) => { onChange={(val) => {
setPorto({ setValue({
...porto, ...value,
tlpn: val.target.value, tlpn: val.target.value,
}); });
}} }}
@@ -95,12 +94,13 @@ export default function Portofolio_EditDataBisnis({
minRows={2} minRows={2}
maxRows={5} maxRows={5}
withAsterisk withAsterisk
value={porto.deskripsi} value={value.deskripsi}
label="Deskripsi" label="Deskripsi"
placeholder="Deskripsi singkat mengenai usaha" placeholder="Deskripsi singkat mengenai usaha"
error={value.deskripsi.length > 150 ? "Maksimal 150 karakter" : ""}
onChange={(val) => { onChange={(val) => {
setPorto({ setValue({
...porto, ...value,
deskripsi: val.target.value, deskripsi: val.target.value,
}); });
}} }}
@@ -111,7 +111,7 @@ export default function Portofolio_EditDataBisnis({
loading={loading ? true : false} loading={loading ? true : false}
loaderPosition="center" loaderPosition="center"
onClick={() => { onClick={() => {
onUpdate(router, porto as any, setLoading); onUpdate(router, value as any, setLoading);
}} }}
> >
Update Update
@@ -126,6 +126,13 @@ async function onUpdate(
data: MODEL_PORTOFOLIO, data: MODEL_PORTOFOLIO,
setLoading: any setLoading: any
) { ) {
if (_.values(data).includes(""))
return ComponentGlobal_NotifikasiPeringatan("Lengkapi Data");
if (data.namaBisnis.length > 100) return null;
if (data.alamatKantor.length > 100) return null;
if (data.deskripsi.length > 150) return null;
await Portofolio_funEditDataBisnis(data).then((res) => { await Portofolio_funEditDataBisnis(data).then((res) => {
if (res.status === 200) { if (res.status === 200) {
setLoading(true); setLoading(true);

View File

@@ -7,6 +7,7 @@ import {
Group, Group,
Loader, Loader,
Paper, Paper,
ScrollArea,
SimpleGrid, SimpleGrid,
Stack, Stack,
Text, Text,
@@ -24,32 +25,33 @@ import {
IconPencilPlus, IconPencilPlus,
} from "@tabler/icons-react"; } from "@tabler/icons-react";
import { LIST_PORTOFOLIO } from "@/app_modules/model_global/portofolio"; import { MODEL_PORTOFOLIO_Lama } from "@/app_modules/model_global/portofolio";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { RouterPortofolio } from "@/app/lib/router_hipmi/router_katalog"; import { RouterPortofolio } from "@/app/lib/router_hipmi/router_katalog";
import { Warna } from "@/app/lib/warna"; import { Warna } from "@/app/lib/warna";
import { MODEL_PROFILE } from "../../profile/model/interface"; import { MODEL_PROFILE } from "../../profile/model/interface";
import { MODEL_PORTOFOLIO } from "../model/interface";
export default function ListPortofolioView({ export default function ListPortofolioView({
listPorto, listPorto,
profile, profile,
userLoginId, userLoginId,
}: { }: {
listPorto: LIST_PORTOFOLIO[]; listPorto: MODEL_PORTOFOLIO[];
profile: MODEL_PROFILE; profile: MODEL_PROFILE;
userLoginId: string; userLoginId: string;
}) { }) {
const router = useRouter(); const router = useRouter();
const [porto, setPorto] = useState(listPorto); // const [porto, setPorto] = useState(listPorto);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [loadingPorto, setLoadingPorto] = useState(false); const [loadingPorto, setLoadingPorto] = useState(false);
const [idPorto, setIdPorto] = useState("") const [idPorto, setIdPorto] = useState("");
return ( return (
<> <>
{/* <pre>{JSON.stringify(porto, null, 2)}</pre> */} {/* <pre>{JSON.stringify(porto, null, 2)}</pre> */}
<Paper p={"md"} shadow="lg" withBorder bg={"gray.1"}> <Paper p={"md"} shadow="lg" withBorder bg={"gray.1"}>
<Stack spacing={"lg"}> <Stack spacing={"sm"}>
<Group position="apart"> <Group position="apart">
<ActionIcon variant="transparent" disabled></ActionIcon> <ActionIcon variant="transparent" disabled></ActionIcon>
<Title order={4}>Portofolio</Title> <Title order={4}>Portofolio</Title>
@@ -68,55 +70,67 @@ export default function ListPortofolioView({
<ActionIcon variant="transparent" disabled></ActionIcon> <ActionIcon variant="transparent" disabled></ActionIcon>
)} )}
</Group> </Group>
<Box> <Box
{_.isEmpty(porto) ? ( h={
<Center> _.isEmpty(listPorto)
<Text fs={"italic"} fz={"xs"}> ? 50
- Belum Ada Portofolio - : listPorto.length === 1
</Text> ? 100
</Center> : listPorto.length === 2
) : ( ? 150
<SimpleGrid : 200
cols={4} }
spacing="md" >
breakpoints={[ <ScrollArea h={"100%"} scrollbarSize={10}>
{ maxWidth: "md", cols: 3, spacing: "md" }, {_.isEmpty(listPorto) ? (
{ maxWidth: "sm", cols: 2, spacing: "sm" }, <Center>
{ maxWidth: "xs", cols: 1, spacing: "sm" }, <Text fs={"italic"} fz={"xs"} c={"gray"}>
]} - Belum Ada Portofolio -
> </Text>
{porto.map((e) => ( </Center>
<Paper ) : (
shadow="md" <SimpleGrid
key={e.id} cols={4}
bg={"gray.5"} spacing="md"
radius={"md"} breakpoints={[
onClick={() => { { maxWidth: "md", cols: 3, spacing: "md" },
setIdPorto(e.id) { maxWidth: "sm", cols: 2, spacing: "sm" },
setLoadingPorto(true); { maxWidth: "xs", cols: 1, spacing: "sm" },
router.push(`/dev/portofolio/main/${e.id}/`); ]}
}} >
> {listPorto.map((e, i) => (
<Grid align="center" p={"sm"}> <Paper
<Grid.Col span={"auto"}> shadow="sm"
<Text fw={"bold"} lineClamp={1}> key={i}
{e.namaBisnis} bg={"gray.5"}
</Text> radius={"md"}
</Grid.Col> onClick={() => {
<Grid.Col span={"content"}> setIdPorto(e?.id);
<Stack> setLoadingPorto(true);
{idPorto === e.id && loadingPorto ? ( router.push(`/dev/portofolio/main/${e?.id}/`);
<Loader color="gray" size={25}/> }}
) : ( >
<IconCaretRight color="black" size={25} /> <Grid align="center" p={"sm"}>
)} <Grid.Col span={"auto"}>
</Stack> <Text fw={"bold"} lineClamp={1}>
</Grid.Col> {e?.namaBisnis}
</Grid> </Text>
</Paper> </Grid.Col>
))} <Grid.Col span={"content"}>
</SimpleGrid> <Stack>
)} {idPorto === e?.id && loadingPorto ? (
<Loader color="gray" size={25} />
) : (
<IconCaretRight color="black" size={25} />
)}
</Stack>
</Grid.Col>
</Grid>
</Paper>
))}
</SimpleGrid>
)}
</ScrollArea>
</Box> </Box>
</Stack> </Stack>
</Paper> </Paper>

View File

@@ -185,16 +185,20 @@ export default function ViewPortofolio({
</Grid> </Grid>
</Stack> </Stack>
</Paper> </Paper>
<Button {userLoginId === dataPorto.Profile.User.id ? (
radius={"xl"} <Button
bg={"red"} radius={"xl"}
color="red" bg={"red"}
onClick={() => { color="red"
open(); onClick={() => {
}} open();
> }}
<IconTrash /> >
</Button> <IconTrash />
</Button>
) : (
""
)}
</Stack> </Stack>
<Modal opened={opened} onClose={close} centered withCloseButton={false}> <Modal opened={opened} onClose={close} centered withCloseButton={false}>
@@ -227,7 +231,7 @@ async function onDelete(
) { ) {
await Portofolio_funDeletePortofolioById(dataPorto).then((res) => { await Portofolio_funDeletePortofolioById(dataPorto).then((res) => {
if (res.status === 200) { if (res.status === 200) {
setLoadingDel(true) setLoadingDel(true);
ComponentGlobal_NotifikasiBerhasil(res.message); ComponentGlobal_NotifikasiBerhasil(res.message);
router.push(RouterProfile.katalog + `${dataPorto.profileId}`); router.push(RouterProfile.katalog + `${dataPorto.profileId}`);
} else { } else {

View File

@@ -1,4 +1,6 @@
import { MODEL_USER } from "@/app_modules/home/model/interface";
import { MODEL_IMAGES } from "@/app_modules/model_global/interface"; import { MODEL_IMAGES } from "@/app_modules/model_global/interface";
import { MODEL_PROFILE } from "../../profile/model/interface";
export interface MODEL_PORTOFOLIO { export interface MODEL_PORTOFOLIO {
id: string; id: string;
@@ -13,6 +15,7 @@ export interface MODEL_PORTOFOLIO {
Logo: MODEL_IMAGES; Logo: MODEL_IMAGES;
logoId: string; logoId: string;
Portofolio_MediaSosial: MODEL_PORTOFOLIO_MEDSOS Portofolio_MediaSosial: MODEL_PORTOFOLIO_MEDSOS
Profile: MODEL_PROFILE
} }
export interface MODEL_PORTOFOLIO_BIDANG_BISNIS { export interface MODEL_PORTOFOLIO_BIDANG_BISNIS {

View File

@@ -34,6 +34,7 @@ import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/
import { RouterHome } from "@/app/lib/router_hipmi/router_home"; import { RouterHome } from "@/app/lib/router_hipmi/router_home";
import { useForm } from "@mantine/form"; import { useForm } from "@mantine/form";
import { useTimeout } from "@mantine/hooks"; import { useTimeout } from "@mantine/hooks";
import { validRegex } from "../../component/regular_expressions";
export default function CreateProfile({ userId }: { userId: any }) { export default function CreateProfile({ userId }: { userId: any }) {
const [filePP, setFilePP] = useState<File | null>(null); const [filePP, setFilePP] = useState<File | null>(null);
@@ -210,7 +211,7 @@ export default function CreateProfile({ userId }: { userId: any }) {
label="Email" label="Email"
placeholder="Contoh: User@gmail.com" placeholder="Contoh: User@gmail.com"
error={ error={
value.email.length > 0 && !value.email.includes("@") value.email.length > 0 && !value.email.match(validRegex)
? "Invalid email" ? "Invalid email"
: "" : ""
} }
@@ -225,6 +226,7 @@ export default function CreateProfile({ userId }: { userId: any }) {
withAsterisk withAsterisk
label="Alamat" label="Alamat"
placeholder="Alamat lengkap" placeholder="Alamat lengkap"
error={value.alamat.length > 100 ? "Max 100 karakter" : ""}
onChange={(val) => { onChange={(val) => {
setValue({ setValue({
...value, ...value,
@@ -232,6 +234,7 @@ export default function CreateProfile({ userId }: { userId: any }) {
}); });
}} }}
/> />
<Select <Select
withAsterisk withAsterisk
label="Jenis Kelamin" label="Jenis Kelamin"
@@ -247,6 +250,7 @@ export default function CreateProfile({ userId }: { userId: any }) {
}); });
}} }}
/> />
<ButtonAction <ButtonAction
value={value as any} value={value as any}
userId={userId} userId={userId}
@@ -283,8 +287,8 @@ function ButtonAction({
}; };
if (_.values(body).includes("")) if (_.values(body).includes(""))
return ComponentGlobal_NotifikasiPeringatan("Lengkapi Data"); return ComponentGlobal_NotifikasiPeringatan("Lengkapi Data");
if (!body.email.includes("@")) if (!body.email.match(validRegex)) return null;
return ComponentGlobal_NotifikasiPeringatan("Invalid Email"); if (body.alamat.length > 100) return null;
const gambarPP = new FormData(); const gambarPP = new FormData();
gambarPP.append("filePP", filePP as any); gambarPP.append("filePP", filePP as any);

View File

@@ -17,6 +17,8 @@ import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/
import { MODEL_PROFILE } from "../model/interface"; import { MODEL_PROFILE } from "../model/interface";
import { Profile_funEditById } from "../fun/update/fun_edit_profile_by_id"; import { Profile_funEditById } from "../fun/update/fun_edit_profile_by_id";
import { RouterProfile } from "@/app/lib/router_hipmi/router_katalog"; import { RouterProfile } from "@/app/lib/router_hipmi/router_katalog";
import { validRegex } from "../../component/regular_expressions";
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/component_global/notif_global/notifikasi_peringatan";
export default function EditProfile({ data }: { data: MODEL_PROFILE }) { export default function EditProfile({ data }: { data: MODEL_PROFILE }) {
const router = useRouter(); const router = useRouter();
@@ -29,7 +31,10 @@ export default function EditProfile({ data }: { data: MODEL_PROFILE }) {
const body = dataProfile; const body = dataProfile;
// console.log(body) // console.log(body)
if (_.values(body).includes("")) return toast("Lengkapi data"); if (_.values(body).includes(""))
return ComponentGlobal_NotifikasiPeringatan("Lengkapi data");
if (!body.email.match(validRegex)) return null;
if (body.alamat.length > 100) return null;
await Profile_funEditById(body).then((res) => { await Profile_funEditById(body).then((res) => {
if (res.status === 200) { if (res.status === 200) {
@@ -100,7 +105,8 @@ export default function EditProfile({ data }: { data: MODEL_PROFILE }) {
label="Email" label="Email"
placeholder="email" placeholder="email"
error={ error={
dataProfile?.email?.length > 0 && !dataProfile?.email.includes("@") dataProfile?.email?.length > 0 &&
!dataProfile?.email.match(validRegex)
? "Invalid email" ? "Invalid email"
: "" : ""
} }
@@ -118,6 +124,7 @@ export default function EditProfile({ data }: { data: MODEL_PROFILE }) {
label="Alamat" label="Alamat"
placeholder="alamat" placeholder="alamat"
value={dataProfile.alamat} value={dataProfile.alamat}
error={dataProfile.alamat.length > 100 ? "Max 100 karakter" : ""}
onChange={(val) => { onChange={(val) => {
setDataProfile({ setDataProfile({
...dataProfile, ...dataProfile,

View File

@@ -5,6 +5,8 @@ import { MODEL_PROFILE } from "../model/interface";
import _ from "lodash"; import _ from "lodash";
import { v4 } from "uuid"; import { v4 } from "uuid";
import fs from "fs"; import fs from "fs";
import { revalidatePath } from "next/cache";
import { RouterHome } from "@/app/lib/router_hipmi/router_home";
export default async function funCreateNewProfile( export default async function funCreateNewProfile(
req: MODEL_PROFILE, req: MODEL_PROFILE,
@@ -22,6 +24,10 @@ export default async function funCreateNewProfile(
if (findEmail) return { status: 400, message: "Email telah digunakan" }; if (findEmail) return { status: 400, message: "Email telah digunakan" };
const gambarProfile: any = gambarPP.get("filePP"); const gambarProfile: any = gambarPP.get("filePP");
if (gambarProfile === "null")
return { status: 400, message: "Lengkapi Foto Profile" };
const fileName = gambarProfile.name; const fileName = gambarProfile.name;
const fileExtension = _.lowerCase(gambarProfile.name.split(".").pop()); const fileExtension = _.lowerCase(gambarProfile.name.split(".").pop());
const fRandomName = v4(fileName) + "." + fileExtension; const fRandomName = v4(fileName) + "." + fileExtension;
@@ -42,6 +48,9 @@ export default async function funCreateNewProfile(
fs.writeFileSync(`./public/profile/foto/${uploadPP.url}`, uploadPP_Folder); fs.writeFileSync(`./public/profile/foto/${uploadPP.url}`, uploadPP_Folder);
const gambarBackground: any = gambarBG.get("fileBG"); const gambarBackground: any = gambarBG.get("fileBG");
if (gambarBackground === "null")
return { status: 400, message: "Lengkapi Foto Background" };
const fileNameBG = gambarBackground.name; const fileNameBG = gambarBackground.name;
const fileExtensionBG = _.lowerCase(gambarBackground.name.split(".").pop()); const fileExtensionBG = _.lowerCase(gambarBackground.name.split(".").pop());
const fRandomNameBG = v4(fileNameBG) + "." + fileExtensionBG; const fRandomNameBG = v4(fileNameBG) + "." + fileExtensionBG;
@@ -65,8 +74,6 @@ export default async function funCreateNewProfile(
uploadBG_Folder uploadBG_Folder
); );
const createProfile = await prisma.profile.create({ const createProfile = await prisma.profile.create({
data: { data: {
userId: body.userId, userId: body.userId,
@@ -80,6 +87,7 @@ export default async function funCreateNewProfile(
}); });
if (!createProfile) return { status: 400, message: "Gagal membuat profile" }; if (!createProfile) return { status: 400, message: "Gagal membuat profile" };
revalidatePath(RouterHome.main_home);
return { return {
status: 201, status: 201,

View File

@@ -1,4 +1,4 @@
export interface LIST_PORTOFOLIO { export interface MODEL_PORTOFOLIO_Lama {
id: string; id: string;
namaBisnis: string; namaBisnis: string;
alamatKantor: string; alamatKantor: string;

View File

@@ -0,0 +1,13 @@
"use client";
import { Center } from "@mantine/core";
export default function ComponentUserSearch_IsEmptyData({ text }: { text: string }) {
return (
<>
<Center h={"50vh"} fz={"sm"} c="gray" fw={"bold"} style={{ zIndex: 1 }}>
{text}
</Center>
</>
);
}

View File

@@ -1,11 +1,49 @@
"use server"; "use server";
import prisma from "@/app/lib/prisma"; import prisma from "@/app/lib/prisma";
import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token";
export async function UserSearch_getListUser() { export async function UserSearch_getListUser({ name }: { name: string }) {
const data = await prisma.user.findMany({ const userLoginId = await user_getOneUserId();
if (name === "") {
const data = await prisma.user.findMany({
where: {
masterUserRoleId: "1",
NOT: {
id: userLoginId,
},
},
select: {
id: true,
username: true,
nomor: true,
active: true,
masterUserRoleId: true,
Profile: {
select: {
id: true,
name: true,
imagesId: true,
},
},
},
});
return data;
}
const getDataCari = await prisma.user.findMany({
where: { where: {
masterUserRoleId: "1" masterUserRoleId: "1",
Profile: {
name: {
contains: name,
mode: "insensitive",
},
},
NOT: {
id: userLoginId,
},
}, },
select: { select: {
id: true, id: true,
@@ -13,14 +51,9 @@ export async function UserSearch_getListUser() {
nomor: true, nomor: true,
active: true, active: true,
masterUserRoleId: true, masterUserRoleId: true,
Profile: { Profile: true,
select: {
id: true,
name: true,
imagesId: true,
},
},
}, },
}); });
return data;
return getDataCari;
} }

View File

@@ -14,7 +14,6 @@ export async function UserSearch_searchByName(name: string) {
}, },
}, },
}, },
take: 10,
select: { select: {
id: true, id: true,
username: true, username: true,

View File

@@ -21,6 +21,10 @@ import { UserSearch_searchByName } from "../fun/search/fun_search_by_name";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import ComponentGlobal_MaintenanceInformation from "@/app_modules/component_global/maintenance_information"; import ComponentGlobal_MaintenanceInformation from "@/app_modules/component_global/maintenance_information";
import ComponentGlobal_V2_LoadingPage from "@/app_modules/component_global/loading_page_v2"; import ComponentGlobal_V2_LoadingPage from "@/app_modules/component_global/loading_page_v2";
import { data } from "autoprefixer";
import { UserSearch_getListUser } from "../fun/get/get_list_user";
import _ from "lodash";
import ComponentUserSearch_IsEmptyData from "../component/is_empty_data";
export default function UserSearch_MainView({ export default function UserSearch_MainView({
listUser, listUser,
@@ -28,11 +32,13 @@ export default function UserSearch_MainView({
listUser: MODEL_USER[]; listUser: MODEL_USER[];
}) { }) {
const router = useRouter(); const router = useRouter();
const [user, setUser] = useState(listUser); const [data, setData] = useState(listUser);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
async function onSearch(name: string) { async function onSearch(name: string) {
await UserSearch_searchByName(name).then((res) => setUser(res as any)); await UserSearch_getListUser({ name: name }).then((res) =>
setData(res as any)
);
} }
// return ( // return (
@@ -43,75 +49,83 @@ export default function UserSearch_MainView({
// </> // </>
// ); // );
if(loading) return <ComponentGlobal_V2_LoadingPage/> if (loading) return <ComponentGlobal_V2_LoadingPage />;
return ( return (
<> <>
<Box> <Box>
{/* <pre>{JSON.stringify(user, null,2)}</pre>r */}
<Stack spacing={"md"}> <Stack spacing={"md"}>
<TextInput <TextInput
style={{ zIndex: 99 }}
pos={"sticky"}
top={"6vh"}
icon={<IconSearch size={20} />} icon={<IconSearch size={20} />}
placeholder="Masukan nama pegguna" placeholder="Masukan nama pegguna"
onChange={(val) => onSearch(val.target.value)} onChange={(val) => onSearch(val.target.value)}
/> />
{!user ? ( <Box>
"" {_.isEmpty(data) ? (
) : ( <ComponentUserSearch_IsEmptyData text="Tidak ada pengguna" />
<Box> ) : (
{user?.map((e) => <Box>
e.Profile === null ? ( {data?.map((e, i) =>
"" e?.Profile === null ? (
) : ( ""
<Stack key={e.id} spacing={"xs"} mt={"xs"}> ) : (
<Grid> <Stack key={i} spacing={"xs"} mt={"xs"}>
<Grid.Col span={2}> <Grid>
<Center h={"100%"}> <Grid.Col span={2}>
<Avatar <Center h={"100%"}>
sx={{ borderStyle: "solid", borderWidth: "0.5px" }} <Avatar
radius={"xl"} sx={{
size={"md"} borderStyle: "solid",
src={ borderWidth: "0.5px",
RouterProfile.api_foto_profile + }}
`${e?.Profile?.imagesId}` radius={"xl"}
} size={"md"}
/> src={
</Center> RouterProfile?.api_foto_profile +
</Grid.Col> `${e?.Profile?.imagesId}`
<Grid.Col span={"auto"}> }
<Stack spacing={0}> />
<Text fw={"bold"} lineClamp={1}> </Center>
{e?.Profile?.name} </Grid.Col>
</Text> <Grid.Col span={"auto"}>
<Text fz={"sm"} fs={"italic"}> <Stack spacing={0}>
+{e?.nomor} <Text fw={"bold"} lineClamp={1}>
</Text> {e?.Profile?.name}
</Stack> </Text>
</Grid.Col> <Text fz={"sm"} fs={"italic"}>
<Grid.Col span={2}> +{e?.nomor}
<Center h={"100%"}> </Text>
<ActionIcon </Stack>
variant="transparent" </Grid.Col>
onClick={() => { <Grid.Col span={2}>
setLoading(true); <Center h={"100%"}>
router.push( <ActionIcon
RouterProfile.katalog + `${e?.Profile?.id}` variant="transparent"
); onClick={() => {
}} setLoading(true);
> router.push(
<IconChevronRight /> RouterProfile.katalog + `${e?.Profile?.id}`
</ActionIcon> );
</Center> }}
</Grid.Col> >
</Grid> <IconChevronRight />
<Divider /> </ActionIcon>
</Stack> </Center>
) </Grid.Col>
)} </Grid>
</Box> <Divider />
)} </Stack>
)
)}
</Box>
)}
</Box>
</Stack> </Stack>
</Box> </Box>
{/* <pre>{JSON.stringify(data, null, 2)}</pre> */}
</> </>
); );
} }

View File

@@ -60,6 +60,13 @@
dependencies: dependencies:
regenerator-runtime "^0.14.0" regenerator-runtime "^0.14.0"
"@babel/runtime@^7.7.2":
version "7.24.5"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.5.tgz#230946857c053a36ccc66e1dd03b17dd0c4ed02c"
integrity sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==
dependencies:
regenerator-runtime "^0.14.0"
"@babel/types@^7.22.15": "@babel/types@^7.22.15":
version "7.23.9" version "7.23.9"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.9.tgz#1dd7b59a9a2b5c87f8b41e52770b5ecbf492e002" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.9.tgz#1dd7b59a9a2b5c87f8b41e52770b5ecbf492e002"
@@ -1032,6 +1039,14 @@
dependencies: dependencies:
"@types/react" "*" "@types/react" "*"
"@types/react-virtualized@^9.21.30":
version "9.21.30"
resolved "https://registry.yarnpkg.com/@types/react-virtualized/-/react-virtualized-9.21.30.tgz#ba39821bcb2487512a8a2cdd9fbdb5e6fc87fedb"
integrity sha512-4l2TFLQ8BCjNDQlvH85tU6gctuZoEdgYzENQyZHpgTHU7hoLzYgPSOALMAeA58LOWua8AzC6wBivPj1lfl6JgQ==
dependencies:
"@types/prop-types" "*"
"@types/react" "*"
"@types/react@*": "@types/react@*":
version "18.2.57" version "18.2.57"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.57.tgz#147b516d8bdb2900219acbfc6f939bdeecca7691" resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.57.tgz#147b516d8bdb2900219acbfc6f939bdeecca7691"
@@ -1565,7 +1580,7 @@ clsx@1.1.1:
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188" resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188"
integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA== integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==
clsx@^1.1.1: clsx@^1.0.4, clsx@^1.1.1:
version "1.2.1" version "1.2.1"
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12" resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12"
integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==
@@ -1784,7 +1799,7 @@ doctrine@^3.0.0:
dependencies: dependencies:
esutils "^2.0.2" esutils "^2.0.2"
dom-helpers@^5.0.1: dom-helpers@^5.0.1, dom-helpers@^5.1.3:
version "5.2.1" version "5.2.1"
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902" resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902"
integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA== integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==
@@ -3884,6 +3899,13 @@ react-icons@^5.0.1:
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-5.0.1.tgz#1694e11bfa2a2888cab47dcc30154ce90485feee" resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-5.0.1.tgz#1694e11bfa2a2888cab47dcc30154ce90485feee"
integrity sha512-WqLZJ4bLzlhmsvme6iFdgO8gfZP17rfjYEJ2m9RsZjZ+cc4k1hTzknEz63YS1MeT50kVzoa1Nz36f4BEx+Wigw== integrity sha512-WqLZJ4bLzlhmsvme6iFdgO8gfZP17rfjYEJ2m9RsZjZ+cc4k1hTzknEz63YS1MeT50kVzoa1Nz36f4BEx+Wigw==
react-infinite-scroll-component@^6.1.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/react-infinite-scroll-component/-/react-infinite-scroll-component-6.1.0.tgz#7e511e7aa0f728ac3e51f64a38a6079ac522407f"
integrity sha512-SQu5nCqy8DxQWpnUVLx7V7b7LcA37aM7tvoWjTLZp1dk6EJibM5/4EJKzOnl07/BsM1Y40sKLuqjCwwH/xV0TQ==
dependencies:
throttle-debounce "^2.1.0"
react-international-phone@^4.2.6: react-international-phone@^4.2.6:
version "4.2.6" version "4.2.6"
resolved "https://registry.yarnpkg.com/react-international-phone/-/react-international-phone-4.2.6.tgz#a92518b66b44015f5e32c96b646e0355056ae809" resolved "https://registry.yarnpkg.com/react-international-phone/-/react-international-phone-4.2.6.tgz#a92518b66b44015f5e32c96b646e0355056ae809"
@@ -3894,6 +3916,11 @@ react-is@^16.13.1, react-is@^16.7.0:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
react-lifecycles-compat@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
react-property@2.0.0: react-property@2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/react-property/-/react-property-2.0.0.tgz#2156ba9d85fa4741faf1918b38efc1eae3c6a136" resolved "https://registry.yarnpkg.com/react-property/-/react-property-2.0.0.tgz#2156ba9d85fa4741faf1918b38efc1eae3c6a136"
@@ -3976,6 +4003,18 @@ react-transition-group@4.4.2:
loose-envify "^1.4.0" loose-envify "^1.4.0"
prop-types "^15.6.2" prop-types "^15.6.2"
react-virtualized@^9.22.5:
version "9.22.5"
resolved "https://registry.yarnpkg.com/react-virtualized/-/react-virtualized-9.22.5.tgz#bfb96fed519de378b50d8c0064b92994b3b91620"
integrity sha512-YqQMRzlVANBv1L/7r63OHa2b0ZsAaDp1UhVNEdUaXI8A5u6hTpA5NYtUueLH2rFuY/27mTGIBl7ZhqFKzw18YQ==
dependencies:
"@babel/runtime" "^7.7.2"
clsx "^1.0.4"
dom-helpers "^5.1.3"
loose-envify "^1.4.0"
prop-types "^15.7.2"
react-lifecycles-compat "^3.0.4"
react@18.2.0: react@18.2.0:
version "18.2.0" version "18.2.0"
resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"
@@ -4494,6 +4533,11 @@ thenify-all@^1.0.0:
dependencies: dependencies:
any-promise "^1.0.0" any-promise "^1.0.0"
throttle-debounce@^2.1.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-2.3.0.tgz#fd31865e66502071e411817e241465b3e9c372e2"
integrity sha512-H7oLPV0P7+jgvrk+6mwwwBDmxTaxnu9HMXmloNLXwnNO0ZxZ31Orah2n8lU1eMPvsaowP2CX+USCgyovXfdOFQ==
throttle-debounce@^3.0.1: throttle-debounce@^3.0.1:
version "3.0.1" version "3.0.1"
resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-3.0.1.tgz#32f94d84dfa894f786c9a1f290e7a645b6a19abb" resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-3.0.1.tgz#32f94d84dfa894f786c9a1f290e7a645b6a19abb"