# fix
- PC: Loader chat - QC: Auth , Profile, portofolio & user search ## No Issuue git commit -m
@@ -35,6 +35,7 @@
|
||||
"@types/node": "20.4.5",
|
||||
"@types/react": "18.2.17",
|
||||
"@types/react-dom": "18.2.7",
|
||||
"@types/react-virtualized": "^9.21.30",
|
||||
"@types/uuid": "^9.0.4",
|
||||
"autoprefixer": "10.4.14",
|
||||
"bufferutil": "^4.0.8",
|
||||
@@ -58,11 +59,13 @@
|
||||
"react-easy-infinite-scroll-hook": "^2.1.4",
|
||||
"react-fast-marquee": "^1.6.4",
|
||||
"react-icons": "^5.0.1",
|
||||
"react-infinite-scroll-component": "^6.1.0",
|
||||
"react-international-phone": "^4.2.6",
|
||||
"react-quill": "^2.0.0",
|
||||
"react-responsive-carousel": "^3.2.23",
|
||||
"react-simple-toasts": "^5.10.0",
|
||||
"react-toastify": "^9.1.3",
|
||||
"react-virtualized": "^9.22.5",
|
||||
"socket.io-client": "^4.7.2",
|
||||
"tailwindcss": "3.3.3",
|
||||
"typescript": "5.1.6",
|
||||
|
||||
BIN
public/portofolio/logo/01b978fb-40f4-47c1-9431-70981fb17b8b.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
public/portofolio/logo/142118e7-a915-46e6-89f8-92f1d3779e7c.png
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
BIN
public/portofolio/logo/19ccfa45-31c6-4214-a925-4e2747ff278c.png
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
public/portofolio/logo/27f1b4f7-0574-472f-97cf-91aeb038c938.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
public/portofolio/logo/869458f1-44ce-4075-a7c8-4c85f85c4664.png
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
public/portofolio/logo/9a40ec12-176f-4e20-a2e9-685d19a3c350.jpg
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
public/portofolio/logo/ddb0dced-949e-4601-9e35-45dce4a801c6.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
public/portofolio/logo/ed10f0e8-fd5c-4ed8-a59c-6f690ca360cc.jpg
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 5.5 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
|
After Width: | Height: | Size: 7.5 KiB |
|
After Width: | Height: | Size: 7.5 KiB |
BIN
public/profile/foto/2ab67615-039d-4ef2-98ad-f1573eaf9125.jpeg
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
BIN
public/profile/foto/2b25412b-0bcd-4608-aa48-ed0eb34a1dc1.jpeg
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
BIN
public/profile/foto/577ce4f3-ab43-4264-bbf5-2552bc22ae45.jpeg
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
BIN
public/profile/foto/5bb79d2d-c5bc-4886-af9c-90546edcd944.jpeg
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
public/profile/foto/6d96d9c1-c5fd-452a-96ad-ff626918460b.jpeg
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
public/profile/foto/89e12784-3361-4033-9212-ec8758c30032.jpeg
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
BIN
public/profile/foto/9d993366-a1d1-4de6-a54d-c6b6e57c2eb3.jpeg
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
BIN
public/profile/foto/ae45dd05-9851-44bc-9ea8-c305b4b731da.jpeg
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
BIN
public/profile/foto/d9e798e1-be4c-446b-8c82-1cabf8662bc8.jpeg
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
BIN
public/profile/foto/ffdbacbe-131a-4790-b500-9cf256452083.jpeg
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
12
src/app/api/test-scroll/route.ts
Normal 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);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { AdminLayout } from "@/app_modules/admin/main_dashboard";
|
||||
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";
|
||||
|
||||
export default async function Layout({
|
||||
@@ -9,7 +9,7 @@ export default async function Layout({
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const userId = await user_getOneUserId()
|
||||
const dataUser = await user_getOneById(userId)
|
||||
const dataUser = await user_getOneByUserId(userId)
|
||||
const userRole = dataUser?.masterUserRoleId
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import adminColab_getOneRoomChatById from "@/app_modules/admin/colab/fun/get/get_one_room_chat_by_id";
|
||||
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 { user_getOneUserId } from "@/app_modules/fun_global/get_user_token";
|
||||
import _ from "lodash";
|
||||
@@ -7,20 +9,30 @@ import _ from "lodash";
|
||||
export default async function Page({ params }: { params: { id: string } }) {
|
||||
const roomId = params.id;
|
||||
const userLoginId = await user_getOneUserId();
|
||||
const dataRoom = (await adminColab_getOneRoomChatById({ roomId: roomId }))
|
||||
const getData = (await adminColab_getOneRoomChatById({ roomId: roomId }))
|
||||
.data;
|
||||
const selectRoom = _.omit(dataRoom, [
|
||||
const dataRoom = _.omit(getData, [
|
||||
"ProjectCollaboration",
|
||||
"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 (
|
||||
<>
|
||||
{/* <ColabViewChat
|
||||
listMsg={listMsg as any}
|
||||
dataRoom={dataRoom as any}
|
||||
userLoginId={userLoginId}
|
||||
/> */}
|
||||
<Colab_GroupChatView
|
||||
userLoginId={userLoginId}
|
||||
listMsg={listMsg}
|
||||
selectRoom={selectRoom as any}
|
||||
selectRoom={dataRoom as any}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { LayoutForum_Forumku } from "@/app_modules/forum";
|
||||
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";
|
||||
|
||||
export default async function Layout({
|
||||
@@ -11,7 +11,7 @@ export default async function Layout({
|
||||
params: { id: string };
|
||||
}) {
|
||||
const authorId = params.id;
|
||||
const dataAuthor = await user_getOneById(authorId);
|
||||
const dataAuthor = await user_getOneByUserId(authorId);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -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_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_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 { forum_countPostingByAuthorId } from "@/app_modules/forum/fun/count/count_posting_by_author_id";
|
||||
|
||||
export default async function Page({ params }: { params: { id: string } }) {
|
||||
const authorId = params.id;
|
||||
const userLoginId = await user_getOneUserId()
|
||||
const dataAuthor = await user_getOneById(authorId);
|
||||
const dataAuthor = await user_getOneByUserId(authorId);
|
||||
const auhtorSelectedData = _.omit(dataAuthor, [
|
||||
"Profile.email",
|
||||
"Profile.alamat",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { LayoutForum_Main } from "@/app_modules/forum";
|
||||
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";
|
||||
|
||||
export default async function Layout({
|
||||
@@ -9,7 +9,7 @@ export default async function Layout({
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const authorId = await user_getOneUserId();
|
||||
const dataAuthor = await user_getOneById(authorId);
|
||||
const dataAuthor = await user_getOneByUserId(authorId);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token";
|
||||
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";
|
||||
|
||||
export default async function Layout({ children }: { children: any }) {
|
||||
const userId = await user_getOneUserId();
|
||||
const dataUser = await user_getOneById(userId);
|
||||
const dataUser = await user_getOneByUserId(userId);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -3,22 +3,25 @@ import { cookies } from "next/headers";
|
||||
import { unsealData } from "iron-session";
|
||||
import _ from "lodash";
|
||||
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 { RouterAdminDashboard } from "@/app/lib/router_hipmi/router_admin";
|
||||
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() {
|
||||
const userId = await user_getOneUserId();
|
||||
const dataUser = await user_getOneById(userId);
|
||||
const dataUser = await user_getOneByUserId(userId);
|
||||
|
||||
if (dataUser?.active === false) {
|
||||
return redirect(RouterHome.home_user_non_active);
|
||||
}
|
||||
|
||||
|
||||
if (dataUser?.masterUserRoleId === "2" || dataUser?.masterUserRoleId === "3")
|
||||
return redirect(RouterAdminDashboard.splash_admin);
|
||||
|
||||
// if (dataUser?.Profile === null) return <ComponentGlobal_V2_LoadingPage />;
|
||||
|
||||
// await new Promise((a, b) => {
|
||||
// setTimeout(a, 4000);
|
||||
// });
|
||||
|
||||
@@ -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 { 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 { 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());
|
||||
|
||||
export default async function Page({ params }: { params: { id: string } }) {
|
||||
let profileId = params.id;
|
||||
const authorId = await user_getOneUserId();
|
||||
const dataUser = await user_getOneById(authorId)
|
||||
const dataUser = await user_getOneByUserId(authorId)
|
||||
const listPorto = await funGetListPortofolio(profileId);
|
||||
const dataProfile = await Profile_getOneProfileAndUserById(profileId);
|
||||
|
||||
|
||||
@@ -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}/>
|
||||
</>
|
||||
}
|
||||
12
src/app/dev/profile/create/page.tsx
Normal 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} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -2,12 +2,12 @@ import { RouterAdminDashboard } from "@/app/lib/router_hipmi/router_admin";
|
||||
import { RouterHome } from "@/app/lib/router_hipmi/router_home";
|
||||
import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token";
|
||||
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";
|
||||
|
||||
export default async function Page() {
|
||||
const userId = await user_getOneUserId();
|
||||
const dataUser = await user_getOneById(userId);
|
||||
const dataUser = await user_getOneByUserId(userId);
|
||||
|
||||
if (dataUser?.active === true) {
|
||||
return redirect(RouterHome.main_home);
|
||||
|
||||
@@ -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";
|
||||
|
||||
export default async function Page() {
|
||||
const listUser = await UserSearch_getListUser()
|
||||
const listUser = await UserSearch_getListUser({ name: "" });
|
||||
|
||||
return <UserSearch_MainView listUser={listUser as any} />;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ export default function RootStyleRegistry({
|
||||
<body suppressHydrationWarning={true}>
|
||||
<CacheProvider value={cache}>
|
||||
<MantineProvider withGlobalStyles withNormalizeCSS>
|
||||
<Notifications position="top-center" containerWidth="250px" />
|
||||
<Notifications position="top-center" containerWidth={300} />
|
||||
{children}
|
||||
{/* <ToastContainer position="bottom-center" />
|
||||
<AppNotif /> */}
|
||||
|
||||
@@ -2,7 +2,7 @@ export const RouterProfile = {
|
||||
katalog: "/dev/katalog/",
|
||||
|
||||
// create
|
||||
create: "/dev/profile/create/",
|
||||
create: "/dev/profile/create",
|
||||
|
||||
// edit
|
||||
edit: "/dev/profile/edit/",
|
||||
|
||||
@@ -5,34 +5,76 @@ import useInfiniteScroll, {
|
||||
} from "react-easy-infinite-scroll-hook";
|
||||
import { createItems, loadMore } from "./_util";
|
||||
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() {
|
||||
const [data, setData] = useState<any[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
useShallowEffect(() => {
|
||||
setData(createItems());
|
||||
}, []);
|
||||
const ttlData = Array.from({ length: 21 });
|
||||
const [list, setList] = useState<any[]>(ttlData);
|
||||
|
||||
const next = async (direction: ScrollDirection) => {
|
||||
console.log("next", direction);
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const newData = await loadMore();
|
||||
// useShallowEffect(() => {
|
||||
// setData(createItems());
|
||||
// }, []);
|
||||
|
||||
const d = direction === "up" ? [...newData, ...data] : [];
|
||||
setData(d);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
// const next = async (direction: ScrollDirection) => {
|
||||
// console.log("next", direction);
|
||||
// try {
|
||||
// setIsLoading(true);
|
||||
// const newData = await loadMore();
|
||||
|
||||
// const d = direction === "up" ? [...newData, ...data] : [];
|
||||
// setData(d);
|
||||
// } finally {
|
||||
// setIsLoading(false);
|
||||
// }
|
||||
// };
|
||||
|
||||
// const ref = useInfiniteScroll({
|
||||
// next,
|
||||
// rowCount: data.length,
|
||||
// hasMore: { up: true },
|
||||
// });
|
||||
|
||||
const fetchMoreData = () => {
|
||||
setTimeout(() => {
|
||||
setList(list.concat(Array.from({ length: 20 })));
|
||||
}, 100);
|
||||
};
|
||||
|
||||
const ref = useInfiniteScroll({
|
||||
next,
|
||||
rowCount: data.length,
|
||||
hasMore: { up: true },
|
||||
});
|
||||
const style = {
|
||||
height: 30,
|
||||
border: "1px solid green",
|
||||
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 (
|
||||
<Center>
|
||||
@@ -40,7 +82,7 @@ export default function App() {
|
||||
<Center>{isLoading && <Loader />}</Center>
|
||||
|
||||
<div
|
||||
ref={ref as any}
|
||||
// ref={ref as any}
|
||||
className="List"
|
||||
style={{
|
||||
height: 500,
|
||||
|
||||
@@ -181,7 +181,7 @@ function TableMenu({ listGroup }: { listGroup: any }) {
|
||||
<Center>Industri</Center>
|
||||
</th>
|
||||
<th>
|
||||
<Center>Jumlah Partisipan</Center>
|
||||
<Center>Anggota Group</Center>
|
||||
</th>
|
||||
<th>
|
||||
<Center>Aksi</Center>
|
||||
@@ -222,7 +222,7 @@ function TableMenu({ listGroup }: { listGroup: any }) {
|
||||
<ScrollArea h={"100%"}>
|
||||
<Stack>
|
||||
<Center>
|
||||
<Title order={4}>Partisipan</Title>
|
||||
<Title order={4}>Anggota</Title>
|
||||
</Center>
|
||||
<Stack>
|
||||
{detailData?.ProjectCollaboration_AnggotaRoomChat?.map(
|
||||
|
||||
@@ -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 };
|
||||
}
|
||||
|
||||
@@ -35,46 +35,24 @@ export default function Register({ dataOtp }: { dataOtp: any }) {
|
||||
const focusTrapRef = useFocusTrap();
|
||||
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() {
|
||||
const body = {
|
||||
username: _.lowerCase(value),
|
||||
username: value,
|
||||
nomor: nomor,
|
||||
};
|
||||
// console.log(body);
|
||||
|
||||
if (_.values(body.username).includes(""))
|
||||
if (body.username === "")
|
||||
return ComponentGlobal_NotifikasiPeringatan("Lengkapi Username");
|
||||
|
||||
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) => {
|
||||
if (res.status === 200) {
|
||||
@@ -118,6 +96,18 @@ export default function Register({ dataOtp }: { dataOtp: any }) {
|
||||
<TextInput
|
||||
ref={focusTrapRef}
|
||||
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) => {
|
||||
setValue(val.currentTarget.value);
|
||||
}}
|
||||
|
||||
@@ -11,7 +11,7 @@ export default function ComponentColab_NotedBox({
|
||||
<Group>
|
||||
<Text fz={10} fs={"italic"}>
|
||||
<Text span inherit c={"red"}>
|
||||
*{" "}
|
||||
Alasan:{" "}
|
||||
</Text>
|
||||
{informasi}
|
||||
</Text>
|
||||
|
||||
324
src/app_modules/colab/detail/chat/index.tsx
Normal 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>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -4,7 +4,10 @@ import { RouterColab } from "@/app/lib/router_hipmi/router_colab";
|
||||
import {
|
||||
ActionIcon,
|
||||
Box,
|
||||
Button,
|
||||
Card,
|
||||
Center,
|
||||
Code,
|
||||
Grid,
|
||||
Group,
|
||||
Header,
|
||||
@@ -25,7 +28,10 @@ import {
|
||||
import { useRouter } from "next/navigation";
|
||||
import router from "next/router";
|
||||
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 ComponentColab_IsEmptyData from "../../component/is_empty_data";
|
||||
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, {
|
||||
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";
|
||||
|
||||
export default function Colab_GroupChatView({
|
||||
userLoginId,
|
||||
@@ -50,61 +58,43 @@ export default function Colab_GroupChatView({
|
||||
const [loadingBack, setLoadingBack] = useState(false);
|
||||
const [loadingInfo, setLoadingInfo] = useState(false);
|
||||
const [msg, setMsg] = useState("");
|
||||
const [newMessage, setNewMessage] = useState<any>();
|
||||
const [data, setData] = useState<any[]>(listMsg);
|
||||
const [totalPage, setTotalPage] = useState(1);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
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) => {
|
||||
// try {
|
||||
// setIsLoading(true);
|
||||
// await new Promise((a) => setTimeout(a, 500));
|
||||
const newData = await colab_getMessageByRoomId({
|
||||
roomId: selectRoom?.id,
|
||||
page: totalPage + 1,
|
||||
});
|
||||
setTotalPage(totalPage + 1);
|
||||
|
||||
// const newData = await colab_getMessageByRoomId({
|
||||
// roomId: selectRoom?.id,
|
||||
// page: totalPage + 1,
|
||||
// });
|
||||
// setTotalPage(totalPage + 1);
|
||||
// console.log(newData, "loading baru");
|
||||
|
||||
// // 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)) {
|
||||
// setIsGet(false);
|
||||
// } else {
|
||||
// const d =
|
||||
// direction === "down" ? [...data, ...newData] : [...newData, ...data];
|
||||
// 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);
|
||||
});
|
||||
}
|
||||
const ref = useInfiniteScroll({
|
||||
next,
|
||||
rowCount: data.length,
|
||||
hasMore: { up: isGet },
|
||||
scrollThreshold: 0.1,
|
||||
});
|
||||
|
||||
async function onSend() {
|
||||
await colab_funCreateMessageByUserId(msg, selectRoom.id).then(
|
||||
@@ -112,6 +102,22 @@ export default function Colab_GroupChatView({
|
||||
if (res.status === 200) {
|
||||
mqtt_client.publish(selectRoom.id, msg);
|
||||
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 {
|
||||
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 (
|
||||
<>
|
||||
<Box h={"100vh"}>
|
||||
{/* Header */}
|
||||
|
||||
<Box
|
||||
style={{
|
||||
zIndex: 99,
|
||||
@@ -186,7 +223,7 @@ export default function Colab_GroupChatView({
|
||||
<Box h={"80vh"}>
|
||||
<Stack justify="flex-end" h={"100%"}>
|
||||
<div
|
||||
// ref={ref as any}
|
||||
ref={ref as any}
|
||||
style={{
|
||||
overflowY: "auto",
|
||||
}}
|
||||
@@ -203,16 +240,16 @@ export default function Colab_GroupChatView({
|
||||
<Box key={i}>
|
||||
{userLoginId === e?.User?.id ? (
|
||||
<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}>
|
||||
<Text lineClamp={1} fw={"bold"} fz={"xs"}>
|
||||
{e.User.Profile.name}
|
||||
{e?.User?.Profile?.name}
|
||||
</Text>
|
||||
<div
|
||||
dangerouslySetInnerHTML={{ __html: e.message }}
|
||||
dangerouslySetInnerHTML={{ __html: e?.message }}
|
||||
/>
|
||||
|
||||
<Group spacing={"xs"}>
|
||||
{/* <Group spacing={"xs"}>
|
||||
<Text fz={7}>
|
||||
{new Intl.DateTimeFormat("id-ID", {
|
||||
timeStyle: "medium",
|
||||
@@ -224,21 +261,21 @@ export default function Colab_GroupChatView({
|
||||
dateStyle: "medium",
|
||||
}).format(e.createdAt)}
|
||||
</Text>
|
||||
</Group>
|
||||
</Group> */}
|
||||
</Stack>
|
||||
</Paper>
|
||||
</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}>
|
||||
<Text lineClamp={1} fw={"bold"} fz={"xs"}>
|
||||
{e.User.Profile.name}
|
||||
{e?.User?.Profile?.name}
|
||||
</Text>
|
||||
<div
|
||||
dangerouslySetInnerHTML={{ __html: e.message }}
|
||||
dangerouslySetInnerHTML={{ __html: e?.message }}
|
||||
/>
|
||||
<Group spacing={"xs"}>
|
||||
{/* <Group spacing={"xs"}>
|
||||
<Text fz={7}>
|
||||
{new Intl.DateTimeFormat("id-ID", {
|
||||
timeStyle: "medium",
|
||||
@@ -250,7 +287,7 @@ export default function Colab_GroupChatView({
|
||||
dateStyle: "medium",
|
||||
}).format(e.createdAt)}
|
||||
</Text>
|
||||
</Group>
|
||||
</Group> */}
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Group>
|
||||
@@ -281,6 +318,14 @@ export default function Colab_GroupChatView({
|
||||
h={"10vh"}
|
||||
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"}>
|
||||
<Grid align="center">
|
||||
<Grid.Col span={"auto"}>
|
||||
@@ -312,4 +357,35 @@ export default function Colab_GroupChatView({
|
||||
</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>
|
||||
// );
|
||||
}
|
||||
|
||||
@@ -240,173 +240,212 @@ export default function Colab_DetailGrupDiskusi({
|
||||
</>
|
||||
);
|
||||
|
||||
// const [pesan, setPesan] = useState("");
|
||||
// const [obrolan, setObrolan] = useState<any[]>(listMsg);
|
||||
// const [scroll, scrollTo] = useWindowScroll();
|
||||
// const [isLoading, setIsLoading] = useState(false);
|
||||
// "use client";
|
||||
|
||||
// const next = async (direction: ScrollDirection) => {
|
||||
// try {
|
||||
// setIsLoading(true);
|
||||
// await new Promise((a) => setTimeout(a, 500));
|
||||
// const newData = await colab_getMessageByRoomId(roomId);
|
||||
// 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 { 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) =>
|
||||
// direction === "up" ? [...newData, ...prev] : [...prev, ...newData]
|
||||
// );
|
||||
// } finally {
|
||||
// setIsLoading(false);
|
||||
// const list = Array(100).fill(0);
|
||||
// export default function ColabViewChat({
|
||||
// userLoginId,
|
||||
// listMsg,
|
||||
// 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({
|
||||
// next,
|
||||
// rowCount: obrolan.length,
|
||||
// hasMore: { up: true },
|
||||
// });
|
||||
// return (
|
||||
// <>
|
||||
// <Box h={"100vh"}>
|
||||
// {/* Header */}
|
||||
|
||||
// useShallowEffect(() => {
|
||||
// mqtt_client.subscribe(roomId);
|
||||
// <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>
|
||||
|
||||
// mqtt_client.on("message", (data: any, msg: any) => {
|
||||
// onList(setObrolan);
|
||||
// });
|
||||
// }, [setObrolan]);
|
||||
// {/* Main View */}
|
||||
|
||||
// async function onList(setObrolan: any) {
|
||||
// await colab_getMessageByRoomId(roomId).then((val) => setObrolan(val));
|
||||
// }
|
||||
|
||||
// async function onSend() {
|
||||
// await colab_funCreateMessageByUserId(pesan, roomId).then(async (res) => {
|
||||
// if (res.status === 200) {
|
||||
// mqtt_client.publish(roomId, pesan);
|
||||
// scrollIntoView();
|
||||
// setPesan("");
|
||||
// } else {
|
||||
// ComponentGlobal_NotifikasiGagal(res.message);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
// return (
|
||||
// <>
|
||||
// <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}
|
||||
// <Box pos={"static"}>
|
||||
// <Box
|
||||
// style={{
|
||||
// overflowY: "scroll",
|
||||
// height: "80vh",
|
||||
// height: "7vh",
|
||||
// }}
|
||||
// >
|
||||
// {isLoading ? (
|
||||
// <Center>
|
||||
// <Loader color="gray" />
|
||||
// </Center>
|
||||
// ) : (
|
||||
// ""
|
||||
// )}
|
||||
// {obrolan.map((e) => (
|
||||
// <Box key={e.id} pt={"lg"}>
|
||||
// {e?.User.id === userLoginId ? (
|
||||
// <Group position="right" ref={targetRef as any}>
|
||||
// <Paper key={e.id} bg={"blue.2"} p={"sm"}>
|
||||
// <Stack spacing={0}>
|
||||
// <Text lineClamp={1} fw={"bold"} fz={"xs"}>
|
||||
// {e.User.Profile.name}
|
||||
// </Text>
|
||||
// <Text>{e.message}</Text>
|
||||
// <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 position="left">
|
||||
// <Paper key={e.id} bg={"cyan.2"} p={"sm"} mr={"lg"}>
|
||||
// <Stack spacing={0}>
|
||||
// <Text lineClamp={1} fw={"bold"} fz={10}>
|
||||
// {e.User.Profile.name}
|
||||
// </Text>
|
||||
// <Text>{e.message}</Text>
|
||||
// <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>
|
||||
// )}
|
||||
// </Box>
|
||||
// </Box>
|
||||
// />
|
||||
// {/* Chat View */}
|
||||
// <Box h={"83vh"} bg={"blue"}>
|
||||
// <ScrollArea h={"100%"} viewportRef={viewport}>
|
||||
// {ls.map((e, i) => (
|
||||
// <Text key={i}>{`${e + 1 + i++}`}</Text>
|
||||
// ))}
|
||||
// </ScrollArea>
|
||||
// </Box>
|
||||
|
||||
// <Box
|
||||
// style={{
|
||||
// height: "10vh",
|
||||
// }}
|
||||
// />
|
||||
// </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
|
||||
// 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>
|
||||
// </>
|
||||
// );
|
||||
// }
|
||||
|
||||
// <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>
|
||||
// </>
|
||||
// );
|
||||
}
|
||||
|
||||
65
src/app_modules/colab/fun/chat/get_message_by_room_id.ts
Normal 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;
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
"use server";
|
||||
|
||||
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 { revalidatePath } from "next/cache";
|
||||
|
||||
export default async function colab_funCreateMessageByUserId(
|
||||
message: string,
|
||||
@@ -14,8 +16,28 @@ export default async function colab_funCreateMessageByUserId(
|
||||
message: message,
|
||||
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" };
|
||||
return { status: 200, message: "Pesan Berhasil Dikirim" };
|
||||
revalidatePath(RouterColab.group_chat + roomId);
|
||||
|
||||
return { data: msg, status: 200, message: "Pesan Berhasil Dikirim" };
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
"use server";
|
||||
|
||||
import prisma from "@/app/lib/prisma";
|
||||
import { RouterColab } from "@/app/lib/router_hipmi/router_colab";
|
||||
import _ from "lodash";
|
||||
import { revalidatePath } from "next/cache";
|
||||
|
||||
export default async function colab_getMessageByRoomId({
|
||||
roomId,
|
||||
@@ -10,8 +12,9 @@ export default async function colab_getMessageByRoomId({
|
||||
roomId: string;
|
||||
page: number;
|
||||
}) {
|
||||
const lewat = page * 6 - 6;
|
||||
const ambil = 6;
|
||||
const lewat = page * 10 - 10;
|
||||
const ambil = 10;
|
||||
|
||||
const getList = await prisma.projectCollaboration_Message.findMany({
|
||||
orderBy: {
|
||||
createdAt: "desc",
|
||||
@@ -41,8 +44,7 @@ export default async function colab_getMessageByRoomId({
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
const reverse = _.reverse(getList)
|
||||
const reverse = _.reverse(getList);
|
||||
|
||||
return reverse;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -70,3 +70,14 @@ export interface MODEL_COLLABORATION_NOTIFIKSI {
|
||||
note: string;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -35,10 +35,10 @@ export default function AppComponentGlobal_LayoutTamplate({
|
||||
zIndex: 99,
|
||||
}}
|
||||
w={"100%"}
|
||||
bg={"black"}
|
||||
// bg={"black"}
|
||||
pos={"sticky"}
|
||||
top={0}
|
||||
h={50}
|
||||
h={"7vh"}
|
||||
>
|
||||
{header}
|
||||
</Box>
|
||||
@@ -46,29 +46,36 @@ export default function AppComponentGlobal_LayoutTamplate({
|
||||
{/* Children */}
|
||||
<Box p={"sm"} pos={"static"}>
|
||||
<Stack>
|
||||
|
||||
{children}
|
||||
<Box
|
||||
style={{
|
||||
height: "10vh",
|
||||
}}
|
||||
></Box>
|
||||
{footer ? (
|
||||
<Box
|
||||
style={{
|
||||
height: "10vh",
|
||||
}}
|
||||
></Box>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</Stack>
|
||||
</Box>
|
||||
|
||||
{/* Footer */}
|
||||
{footer ? <Box
|
||||
style={{
|
||||
zIndex: 98,
|
||||
}}
|
||||
w={"100%"}
|
||||
bg={"black"}
|
||||
pos={"fixed"}
|
||||
bottom={0}
|
||||
h={"10vh"}
|
||||
>
|
||||
{footer}
|
||||
</Box> : ""}
|
||||
{footer ? (
|
||||
<Box
|
||||
style={{
|
||||
zIndex: 98,
|
||||
}}
|
||||
w={"100%"}
|
||||
bg={"black"}
|
||||
pos={"fixed"}
|
||||
bottom={0}
|
||||
h={"10vh"}
|
||||
>
|
||||
{footer}
|
||||
</Box>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
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({
|
||||
where: {
|
||||
id: userId,
|
||||
|
||||
@@ -41,7 +41,7 @@ export default function HomeLayout({
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const [user, setUser] = useState(dataUser);
|
||||
// const [user, setUser] = useState(dataUser);
|
||||
const [loadingProfil, setLoadingProfile] = useState(false);
|
||||
const [loadingUS, setLoadingUS] = useState(false);
|
||||
const listFooter = [
|
||||
@@ -73,7 +73,7 @@ export default function HomeLayout({
|
||||
align="center"
|
||||
spacing={0}
|
||||
onClick={() => {
|
||||
if (user?.Profile === null) {
|
||||
if (dataUser?.Profile === null) {
|
||||
ComponentGlobal_NotifikasiPeringatan("Lengkapi Profile");
|
||||
} else {
|
||||
setLoadingUS(true);
|
||||
@@ -104,15 +104,17 @@ export default function HomeLayout({
|
||||
spacing={2}
|
||||
onClick={() => {
|
||||
setLoadingProfile(true);
|
||||
if (user?.Profile === null) {
|
||||
router.push(RouterProfile.create + `${user.id}`);
|
||||
if (dataUser?.Profile === null) {
|
||||
router.push(RouterProfile.create + `${dataUser.id}`);
|
||||
} else {
|
||||
router.push(RouterProfile.katalog + `${user.Profile.id}`);
|
||||
router.push(
|
||||
RouterProfile.katalog + `${dataUser.Profile.id}`
|
||||
);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ActionIcon variant={"transparent"}>
|
||||
{user?.Profile === null ? (
|
||||
{dataUser?.Profile === null ? (
|
||||
<IconUserCircle color="white" />
|
||||
) : (
|
||||
<Avatar
|
||||
@@ -125,7 +127,7 @@ export default function HomeLayout({
|
||||
}}
|
||||
src={
|
||||
RouterProfile.api_foto_profile +
|
||||
`${user?.Profile.imagesId}`
|
||||
`${dataUser?.Profile.imagesId}`
|
||||
}
|
||||
/>
|
||||
)}
|
||||
@@ -197,7 +199,7 @@ export default function HomeLayout({
|
||||
align="center"
|
||||
spacing={0}
|
||||
onClick={() => {
|
||||
if (user?.Profile === null) {
|
||||
if (dataUser?.Profile === null) {
|
||||
ComponentGlobal_NotifikasiPeringatan(
|
||||
"Lengkapi Profile"
|
||||
);
|
||||
@@ -231,17 +233,17 @@ export default function HomeLayout({
|
||||
spacing={2}
|
||||
onClick={() => {
|
||||
setLoadingProfile(true);
|
||||
if (user?.Profile === null) {
|
||||
router.push(RouterProfile.create + `${user.id}`);
|
||||
if (dataUser?.Profile === null) {
|
||||
router.push(RouterProfile.create);
|
||||
} else {
|
||||
router.push(
|
||||
RouterProfile.katalog + `${user.Profile.id}`
|
||||
RouterProfile.katalog + `${dataUser.Profile.id}`
|
||||
);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ActionIcon variant={"transparent"}>
|
||||
{user?.Profile === null ? (
|
||||
{dataUser?.Profile === null ? (
|
||||
<IconUserCircle color="white" />
|
||||
) : (
|
||||
<Avatar
|
||||
@@ -254,7 +256,7 @@ export default function HomeLayout({
|
||||
}}
|
||||
src={
|
||||
RouterProfile.api_foto_profile +
|
||||
`${user?.Profile.imagesId}`
|
||||
`${dataUser?.Profile.imagesId}`
|
||||
}
|
||||
/>
|
||||
)}
|
||||
@@ -271,100 +273,4 @@ export default function HomeLayout({
|
||||
</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>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -157,7 +157,9 @@ export default function HomeView({ dataUser }: { dataUser: MODEL_USER }) {
|
||||
>
|
||||
{e.icon}
|
||||
</ActionIcon>
|
||||
<Text c={e.link === "" ? "gray" : "teal"} fz={"sm"}>{e.name}</Text>
|
||||
<Text c={e.link === "" ? "gray" : "teal"} fz={"sm"}>
|
||||
{e.name}
|
||||
</Text>
|
||||
</Flex>
|
||||
</Paper>
|
||||
))}
|
||||
|
||||
2
src/app_modules/katalog/component/regular_expressions.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export var validRegex =
|
||||
/^([a-zA-Z0-9\.!#$%&'*+/=?^_`{|}~-]+)@([a-zA-Z0-9])+.([a-z]+)(.[a-z]+)?$/;
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
import { ProfileView } from "../profile";
|
||||
import { ListPortofolioView } from "../portofolio";
|
||||
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 { MODEL_PORTOFOLIO } from "../portofolio/model/interface";
|
||||
import { MODEL_PROFILE } from "../profile/model/interface";
|
||||
@@ -28,10 +28,9 @@ export default function KatalogView({
|
||||
userLoginId,
|
||||
}: {
|
||||
profile: MODEL_PROFILE;
|
||||
listPorto: LIST_PORTOFOLIO;
|
||||
listPorto: MODEL_PORTOFOLIO;
|
||||
userLoginId: string;
|
||||
}) {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Stack>
|
||||
@@ -41,9 +40,9 @@ export default function KatalogView({
|
||||
profile={profile}
|
||||
userLoginId={userLoginId}
|
||||
/>
|
||||
<Stack my={"lg"} w={"100%"}>
|
||||
{profile?.User.id === userLoginId ? <User_Logout /> : ""}
|
||||
</Stack>
|
||||
<Stack my={"lg"} w={"100%"}>
|
||||
{profile?.User.id === userLoginId ? <User_Logout /> : ""}
|
||||
</Stack>
|
||||
</Stack>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -72,6 +72,7 @@ export default function CreatePortofolio({
|
||||
withAsterisk
|
||||
label="Nama Bisnis"
|
||||
placeholder="Nama bisnis"
|
||||
error={value.namaBisnis.length > 100 ? "Maksimal 100 karakter" : ""}
|
||||
onChange={(val) => {
|
||||
setValue({
|
||||
...value,
|
||||
@@ -98,6 +99,9 @@ export default function CreatePortofolio({
|
||||
withAsterisk
|
||||
label="Alamat Kantor"
|
||||
placeholder="Alamat kantor"
|
||||
error={
|
||||
value.alamatKantor.length > 100 ? "Maksimal 100 karakter" : ""
|
||||
}
|
||||
onChange={(val) => {
|
||||
setValue({
|
||||
...value,
|
||||
@@ -108,7 +112,7 @@ export default function CreatePortofolio({
|
||||
<TextInput
|
||||
withAsterisk
|
||||
label="Nomor Telepon Kantor"
|
||||
placeholder="62 xxx xxx xxx"
|
||||
placeholder="Nomor telepon kantor"
|
||||
type="number"
|
||||
onChange={(val) => {
|
||||
setValue({
|
||||
@@ -124,6 +128,7 @@ export default function CreatePortofolio({
|
||||
withAsterisk
|
||||
label="Deskripsi"
|
||||
placeholder="Deskripsi singkat mengenai usaha"
|
||||
error={value.deskripsi.length > 150 ? "Maksimal 150 karakter" : ""}
|
||||
onChange={(val) => {
|
||||
setValue({
|
||||
...value,
|
||||
@@ -270,7 +275,11 @@ async function onSubmit(
|
||||
if (_.values(porto).includes(""))
|
||||
return ComponentGlobal_NotifikasiPeringatan("Lengkapi Data");
|
||||
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();
|
||||
gambar.append("file", file as any);
|
||||
|
||||
@@ -12,6 +12,7 @@ import { useRouter } from "next/navigation";
|
||||
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_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({
|
||||
dataPorto,
|
||||
@@ -21,15 +22,9 @@ export default function Portofolio_EditDataBisnis({
|
||||
listBidang: MODEL_PORTOFOLIO_BIDANG_BISNIS[];
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const [porto, setPorto] = useState(dataPorto);
|
||||
const [value, setValue] = useState(dataPorto);
|
||||
const [loading, setLoading] = useState(false);
|
||||
// const [value, setPorto] = useState({
|
||||
// namaBisnis: "",
|
||||
// masterBidangBisnisId: "",
|
||||
// alamatKantor: "",
|
||||
// tlpn: "",
|
||||
// deskripsi: "",
|
||||
// });
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* <pre>{JSON.stringify(porto, null, 2)}</pre> */}
|
||||
@@ -37,19 +32,20 @@ export default function Portofolio_EditDataBisnis({
|
||||
<Stack>
|
||||
<TextInput
|
||||
withAsterisk
|
||||
value={porto.namaBisnis}
|
||||
value={value.namaBisnis}
|
||||
label="Nama Bisnis"
|
||||
placeholder="Nama bisnis"
|
||||
error={value.namaBisnis.length > 100 ? "Maksimal 100 karakter" : ""}
|
||||
onChange={(val) => {
|
||||
setPorto({
|
||||
...porto,
|
||||
setValue({
|
||||
...value,
|
||||
namaBisnis: val.target.value,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<Select
|
||||
withAsterisk
|
||||
value={porto.MasterBidangBisnis.id}
|
||||
value={value.MasterBidangBisnis.id}
|
||||
label="Bidang Bisnis"
|
||||
placeholder="Pilih salah satu bidang bisnis"
|
||||
data={listBidang.map((e) => ({
|
||||
@@ -57,8 +53,8 @@ export default function Portofolio_EditDataBisnis({
|
||||
label: e.name,
|
||||
}))}
|
||||
onChange={(val) => {
|
||||
setPorto({
|
||||
...(porto as any),
|
||||
setValue({
|
||||
...(value as any),
|
||||
MasterBidangBisnis: {
|
||||
id: val,
|
||||
},
|
||||
@@ -67,25 +63,28 @@ export default function Portofolio_EditDataBisnis({
|
||||
/>
|
||||
<TextInput
|
||||
withAsterisk
|
||||
value={porto.alamatKantor}
|
||||
value={value.alamatKantor}
|
||||
label="Alamat Kantor"
|
||||
placeholder="Alamat kantor"
|
||||
error={
|
||||
value.alamatKantor.length > 100 ? "Maksimal 100 karakter" : ""
|
||||
}
|
||||
onChange={(val) => {
|
||||
setPorto({
|
||||
...porto,
|
||||
setValue({
|
||||
...value,
|
||||
alamatKantor: val.target.value,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
withAsterisk
|
||||
value={porto.tlpn}
|
||||
value={value.tlpn}
|
||||
label="Nomor Telepon Kantor"
|
||||
placeholder="62 xxx xxx xxx"
|
||||
type="number"
|
||||
onChange={(val) => {
|
||||
setPorto({
|
||||
...porto,
|
||||
setValue({
|
||||
...value,
|
||||
tlpn: val.target.value,
|
||||
});
|
||||
}}
|
||||
@@ -95,12 +94,13 @@ export default function Portofolio_EditDataBisnis({
|
||||
minRows={2}
|
||||
maxRows={5}
|
||||
withAsterisk
|
||||
value={porto.deskripsi}
|
||||
value={value.deskripsi}
|
||||
label="Deskripsi"
|
||||
placeholder="Deskripsi singkat mengenai usaha"
|
||||
error={value.deskripsi.length > 150 ? "Maksimal 150 karakter" : ""}
|
||||
onChange={(val) => {
|
||||
setPorto({
|
||||
...porto,
|
||||
setValue({
|
||||
...value,
|
||||
deskripsi: val.target.value,
|
||||
});
|
||||
}}
|
||||
@@ -111,7 +111,7 @@ export default function Portofolio_EditDataBisnis({
|
||||
loading={loading ? true : false}
|
||||
loaderPosition="center"
|
||||
onClick={() => {
|
||||
onUpdate(router, porto as any, setLoading);
|
||||
onUpdate(router, value as any, setLoading);
|
||||
}}
|
||||
>
|
||||
Update
|
||||
@@ -126,6 +126,13 @@ async function onUpdate(
|
||||
data: MODEL_PORTOFOLIO,
|
||||
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) => {
|
||||
if (res.status === 200) {
|
||||
setLoading(true);
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
Group,
|
||||
Loader,
|
||||
Paper,
|
||||
ScrollArea,
|
||||
SimpleGrid,
|
||||
Stack,
|
||||
Text,
|
||||
@@ -24,32 +25,33 @@ import {
|
||||
IconPencilPlus,
|
||||
} 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 { RouterPortofolio } from "@/app/lib/router_hipmi/router_katalog";
|
||||
import { Warna } from "@/app/lib/warna";
|
||||
import { MODEL_PROFILE } from "../../profile/model/interface";
|
||||
import { MODEL_PORTOFOLIO } from "../model/interface";
|
||||
|
||||
export default function ListPortofolioView({
|
||||
listPorto,
|
||||
profile,
|
||||
userLoginId,
|
||||
}: {
|
||||
listPorto: LIST_PORTOFOLIO[];
|
||||
listPorto: MODEL_PORTOFOLIO[];
|
||||
profile: MODEL_PROFILE;
|
||||
userLoginId: string;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const [porto, setPorto] = useState(listPorto);
|
||||
// const [porto, setPorto] = useState(listPorto);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [loadingPorto, setLoadingPorto] = useState(false);
|
||||
const [idPorto, setIdPorto] = useState("")
|
||||
const [idPorto, setIdPorto] = useState("");
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* <pre>{JSON.stringify(porto, null, 2)}</pre> */}
|
||||
<Paper p={"md"} shadow="lg" withBorder bg={"gray.1"}>
|
||||
<Stack spacing={"lg"}>
|
||||
<Stack spacing={"sm"}>
|
||||
<Group position="apart">
|
||||
<ActionIcon variant="transparent" disabled></ActionIcon>
|
||||
<Title order={4}>Portofolio</Title>
|
||||
@@ -68,55 +70,67 @@ export default function ListPortofolioView({
|
||||
<ActionIcon variant="transparent" disabled></ActionIcon>
|
||||
)}
|
||||
</Group>
|
||||
<Box>
|
||||
{_.isEmpty(porto) ? (
|
||||
<Center>
|
||||
<Text fs={"italic"} fz={"xs"}>
|
||||
- Belum Ada Portofolio -
|
||||
</Text>
|
||||
</Center>
|
||||
) : (
|
||||
<SimpleGrid
|
||||
cols={4}
|
||||
spacing="md"
|
||||
breakpoints={[
|
||||
{ maxWidth: "md", cols: 3, spacing: "md" },
|
||||
{ maxWidth: "sm", cols: 2, spacing: "sm" },
|
||||
{ maxWidth: "xs", cols: 1, spacing: "sm" },
|
||||
]}
|
||||
>
|
||||
{porto.map((e) => (
|
||||
<Paper
|
||||
shadow="md"
|
||||
key={e.id}
|
||||
bg={"gray.5"}
|
||||
radius={"md"}
|
||||
onClick={() => {
|
||||
setIdPorto(e.id)
|
||||
setLoadingPorto(true);
|
||||
router.push(`/dev/portofolio/main/${e.id}/`);
|
||||
}}
|
||||
>
|
||||
<Grid align="center" p={"sm"}>
|
||||
<Grid.Col span={"auto"}>
|
||||
<Text fw={"bold"} lineClamp={1}>
|
||||
{e.namaBisnis}
|
||||
</Text>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={"content"}>
|
||||
<Stack>
|
||||
{idPorto === e.id && loadingPorto ? (
|
||||
<Loader color="gray" size={25}/>
|
||||
) : (
|
||||
<IconCaretRight color="black" size={25} />
|
||||
)}
|
||||
</Stack>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</Paper>
|
||||
))}
|
||||
</SimpleGrid>
|
||||
)}
|
||||
<Box
|
||||
h={
|
||||
_.isEmpty(listPorto)
|
||||
? 50
|
||||
: listPorto.length === 1
|
||||
? 100
|
||||
: listPorto.length === 2
|
||||
? 150
|
||||
: 200
|
||||
}
|
||||
>
|
||||
<ScrollArea h={"100%"} scrollbarSize={10}>
|
||||
{_.isEmpty(listPorto) ? (
|
||||
<Center>
|
||||
<Text fs={"italic"} fz={"xs"} c={"gray"}>
|
||||
- Belum Ada Portofolio -
|
||||
</Text>
|
||||
</Center>
|
||||
) : (
|
||||
<SimpleGrid
|
||||
cols={4}
|
||||
spacing="md"
|
||||
breakpoints={[
|
||||
{ maxWidth: "md", cols: 3, spacing: "md" },
|
||||
{ maxWidth: "sm", cols: 2, spacing: "sm" },
|
||||
{ maxWidth: "xs", cols: 1, spacing: "sm" },
|
||||
]}
|
||||
>
|
||||
{listPorto.map((e, i) => (
|
||||
<Paper
|
||||
shadow="sm"
|
||||
key={i}
|
||||
bg={"gray.5"}
|
||||
radius={"md"}
|
||||
onClick={() => {
|
||||
setIdPorto(e?.id);
|
||||
setLoadingPorto(true);
|
||||
router.push(`/dev/portofolio/main/${e?.id}/`);
|
||||
}}
|
||||
>
|
||||
<Grid align="center" p={"sm"}>
|
||||
<Grid.Col span={"auto"}>
|
||||
<Text fw={"bold"} lineClamp={1}>
|
||||
{e?.namaBisnis}
|
||||
</Text>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={"content"}>
|
||||
<Stack>
|
||||
{idPorto === e?.id && loadingPorto ? (
|
||||
<Loader color="gray" size={25} />
|
||||
) : (
|
||||
<IconCaretRight color="black" size={25} />
|
||||
)}
|
||||
</Stack>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</Paper>
|
||||
))}
|
||||
</SimpleGrid>
|
||||
)}
|
||||
</ScrollArea>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Paper>
|
||||
|
||||
@@ -185,16 +185,20 @@ export default function ViewPortofolio({
|
||||
</Grid>
|
||||
</Stack>
|
||||
</Paper>
|
||||
<Button
|
||||
radius={"xl"}
|
||||
bg={"red"}
|
||||
color="red"
|
||||
onClick={() => {
|
||||
open();
|
||||
}}
|
||||
>
|
||||
<IconTrash />
|
||||
</Button>
|
||||
{userLoginId === dataPorto.Profile.User.id ? (
|
||||
<Button
|
||||
radius={"xl"}
|
||||
bg={"red"}
|
||||
color="red"
|
||||
onClick={() => {
|
||||
open();
|
||||
}}
|
||||
>
|
||||
<IconTrash />
|
||||
</Button>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</Stack>
|
||||
|
||||
<Modal opened={opened} onClose={close} centered withCloseButton={false}>
|
||||
@@ -227,7 +231,7 @@ async function onDelete(
|
||||
) {
|
||||
await Portofolio_funDeletePortofolioById(dataPorto).then((res) => {
|
||||
if (res.status === 200) {
|
||||
setLoadingDel(true)
|
||||
setLoadingDel(true);
|
||||
ComponentGlobal_NotifikasiBerhasil(res.message);
|
||||
router.push(RouterProfile.katalog + `${dataPorto.profileId}`);
|
||||
} else {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { MODEL_USER } from "@/app_modules/home/model/interface";
|
||||
import { MODEL_IMAGES } from "@/app_modules/model_global/interface";
|
||||
import { MODEL_PROFILE } from "../../profile/model/interface";
|
||||
|
||||
export interface MODEL_PORTOFOLIO {
|
||||
id: string;
|
||||
@@ -13,6 +15,7 @@ export interface MODEL_PORTOFOLIO {
|
||||
Logo: MODEL_IMAGES;
|
||||
logoId: string;
|
||||
Portofolio_MediaSosial: MODEL_PORTOFOLIO_MEDSOS
|
||||
Profile: MODEL_PROFILE
|
||||
}
|
||||
|
||||
export interface MODEL_PORTOFOLIO_BIDANG_BISNIS {
|
||||
|
||||
@@ -34,6 +34,7 @@ import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/
|
||||
import { RouterHome } from "@/app/lib/router_hipmi/router_home";
|
||||
import { useForm } from "@mantine/form";
|
||||
import { useTimeout } from "@mantine/hooks";
|
||||
import { validRegex } from "../../component/regular_expressions";
|
||||
|
||||
export default function CreateProfile({ userId }: { userId: any }) {
|
||||
const [filePP, setFilePP] = useState<File | null>(null);
|
||||
@@ -210,7 +211,7 @@ export default function CreateProfile({ userId }: { userId: any }) {
|
||||
label="Email"
|
||||
placeholder="Contoh: User@gmail.com"
|
||||
error={
|
||||
value.email.length > 0 && !value.email.includes("@")
|
||||
value.email.length > 0 && !value.email.match(validRegex)
|
||||
? "Invalid email"
|
||||
: ""
|
||||
}
|
||||
@@ -225,6 +226,7 @@ export default function CreateProfile({ userId }: { userId: any }) {
|
||||
withAsterisk
|
||||
label="Alamat"
|
||||
placeholder="Alamat lengkap"
|
||||
error={value.alamat.length > 100 ? "Max 100 karakter" : ""}
|
||||
onChange={(val) => {
|
||||
setValue({
|
||||
...value,
|
||||
@@ -232,6 +234,7 @@ export default function CreateProfile({ userId }: { userId: any }) {
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
<Select
|
||||
withAsterisk
|
||||
label="Jenis Kelamin"
|
||||
@@ -247,6 +250,7 @@ export default function CreateProfile({ userId }: { userId: any }) {
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
<ButtonAction
|
||||
value={value as any}
|
||||
userId={userId}
|
||||
@@ -283,8 +287,8 @@ function ButtonAction({
|
||||
};
|
||||
if (_.values(body).includes(""))
|
||||
return ComponentGlobal_NotifikasiPeringatan("Lengkapi Data");
|
||||
if (!body.email.includes("@"))
|
||||
return ComponentGlobal_NotifikasiPeringatan("Invalid Email");
|
||||
if (!body.email.match(validRegex)) return null;
|
||||
if (body.alamat.length > 100) return null;
|
||||
|
||||
const gambarPP = new FormData();
|
||||
gambarPP.append("filePP", filePP as any);
|
||||
|
||||
@@ -17,6 +17,8 @@ import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/
|
||||
import { MODEL_PROFILE } from "../model/interface";
|
||||
import { Profile_funEditById } from "../fun/update/fun_edit_profile_by_id";
|
||||
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 }) {
|
||||
const router = useRouter();
|
||||
@@ -29,7 +31,10 @@ export default function EditProfile({ data }: { data: MODEL_PROFILE }) {
|
||||
const body = dataProfile;
|
||||
|
||||
// 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) => {
|
||||
if (res.status === 200) {
|
||||
@@ -100,7 +105,8 @@ export default function EditProfile({ data }: { data: MODEL_PROFILE }) {
|
||||
label="Email"
|
||||
placeholder="email"
|
||||
error={
|
||||
dataProfile?.email?.length > 0 && !dataProfile?.email.includes("@")
|
||||
dataProfile?.email?.length > 0 &&
|
||||
!dataProfile?.email.match(validRegex)
|
||||
? "Invalid email"
|
||||
: ""
|
||||
}
|
||||
@@ -118,6 +124,7 @@ export default function EditProfile({ data }: { data: MODEL_PROFILE }) {
|
||||
label="Alamat"
|
||||
placeholder="alamat"
|
||||
value={dataProfile.alamat}
|
||||
error={dataProfile.alamat.length > 100 ? "Max 100 karakter" : ""}
|
||||
onChange={(val) => {
|
||||
setDataProfile({
|
||||
...dataProfile,
|
||||
|
||||
@@ -5,6 +5,8 @@ import { MODEL_PROFILE } from "../model/interface";
|
||||
import _ from "lodash";
|
||||
import { v4 } from "uuid";
|
||||
import fs from "fs";
|
||||
import { revalidatePath } from "next/cache";
|
||||
import { RouterHome } from "@/app/lib/router_hipmi/router_home";
|
||||
|
||||
export default async function funCreateNewProfile(
|
||||
req: MODEL_PROFILE,
|
||||
@@ -22,6 +24,10 @@ export default async function funCreateNewProfile(
|
||||
if (findEmail) return { status: 400, message: "Email telah digunakan" };
|
||||
|
||||
const gambarProfile: any = gambarPP.get("filePP");
|
||||
|
||||
if (gambarProfile === "null")
|
||||
return { status: 400, message: "Lengkapi Foto Profile" };
|
||||
|
||||
const fileName = gambarProfile.name;
|
||||
const fileExtension = _.lowerCase(gambarProfile.name.split(".").pop());
|
||||
const fRandomName = v4(fileName) + "." + fileExtension;
|
||||
@@ -42,6 +48,9 @@ export default async function funCreateNewProfile(
|
||||
fs.writeFileSync(`./public/profile/foto/${uploadPP.url}`, uploadPP_Folder);
|
||||
|
||||
const gambarBackground: any = gambarBG.get("fileBG");
|
||||
if (gambarBackground === "null")
|
||||
return { status: 400, message: "Lengkapi Foto Background" };
|
||||
|
||||
const fileNameBG = gambarBackground.name;
|
||||
const fileExtensionBG = _.lowerCase(gambarBackground.name.split(".").pop());
|
||||
const fRandomNameBG = v4(fileNameBG) + "." + fileExtensionBG;
|
||||
@@ -65,8 +74,6 @@ export default async function funCreateNewProfile(
|
||||
uploadBG_Folder
|
||||
);
|
||||
|
||||
|
||||
|
||||
const createProfile = await prisma.profile.create({
|
||||
data: {
|
||||
userId: body.userId,
|
||||
@@ -80,6 +87,7 @@ export default async function funCreateNewProfile(
|
||||
});
|
||||
|
||||
if (!createProfile) return { status: 400, message: "Gagal membuat profile" };
|
||||
revalidatePath(RouterHome.main_home);
|
||||
|
||||
return {
|
||||
status: 201,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export interface LIST_PORTOFOLIO {
|
||||
export interface MODEL_PORTOFOLIO_Lama {
|
||||
id: string;
|
||||
namaBisnis: string;
|
||||
alamatKantor: string;
|
||||
|
||||
13
src/app_modules/user_search/component/is_empty_data.tsx
Normal 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>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,11 +1,49 @@
|
||||
"use server";
|
||||
|
||||
import prisma from "@/app/lib/prisma";
|
||||
import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token";
|
||||
|
||||
export async function UserSearch_getListUser() {
|
||||
const data = await prisma.user.findMany({
|
||||
export async function UserSearch_getListUser({ name }: { name: string }) {
|
||||
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: {
|
||||
masterUserRoleId: "1"
|
||||
masterUserRoleId: "1",
|
||||
Profile: {
|
||||
name: {
|
||||
contains: name,
|
||||
mode: "insensitive",
|
||||
},
|
||||
},
|
||||
NOT: {
|
||||
id: userLoginId,
|
||||
},
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
@@ -13,14 +51,9 @@ export async function UserSearch_getListUser() {
|
||||
nomor: true,
|
||||
active: true,
|
||||
masterUserRoleId: true,
|
||||
Profile: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
imagesId: true,
|
||||
},
|
||||
},
|
||||
Profile: true,
|
||||
},
|
||||
});
|
||||
return data;
|
||||
|
||||
return getDataCari;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ export async function UserSearch_searchByName(name: string) {
|
||||
},
|
||||
},
|
||||
},
|
||||
take: 10,
|
||||
select: {
|
||||
id: true,
|
||||
username: true,
|
||||
|
||||
@@ -21,6 +21,10 @@ import { UserSearch_searchByName } from "../fun/search/fun_search_by_name";
|
||||
import { useRouter } from "next/navigation";
|
||||
import ComponentGlobal_MaintenanceInformation from "@/app_modules/component_global/maintenance_information";
|
||||
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({
|
||||
listUser,
|
||||
@@ -28,11 +32,13 @@ export default function UserSearch_MainView({
|
||||
listUser: MODEL_USER[];
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const [user, setUser] = useState(listUser);
|
||||
const [data, setData] = useState(listUser);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
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 (
|
||||
@@ -43,75 +49,83 @@ export default function UserSearch_MainView({
|
||||
// </>
|
||||
// );
|
||||
|
||||
if(loading) return <ComponentGlobal_V2_LoadingPage/>
|
||||
if (loading) return <ComponentGlobal_V2_LoadingPage />;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box>
|
||||
{/* <pre>{JSON.stringify(user, null,2)}</pre>r */}
|
||||
<Stack spacing={"md"}>
|
||||
<TextInput
|
||||
style={{ zIndex: 99 }}
|
||||
pos={"sticky"}
|
||||
top={"6vh"}
|
||||
icon={<IconSearch size={20} />}
|
||||
placeholder="Masukan nama pegguna"
|
||||
onChange={(val) => onSearch(val.target.value)}
|
||||
/>
|
||||
{!user ? (
|
||||
""
|
||||
) : (
|
||||
<Box>
|
||||
{user?.map((e) =>
|
||||
e.Profile === null ? (
|
||||
""
|
||||
) : (
|
||||
<Stack key={e.id} spacing={"xs"} mt={"xs"}>
|
||||
<Grid>
|
||||
<Grid.Col span={2}>
|
||||
<Center h={"100%"}>
|
||||
<Avatar
|
||||
sx={{ borderStyle: "solid", borderWidth: "0.5px" }}
|
||||
radius={"xl"}
|
||||
size={"md"}
|
||||
src={
|
||||
RouterProfile.api_foto_profile +
|
||||
`${e?.Profile?.imagesId}`
|
||||
}
|
||||
/>
|
||||
</Center>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={"auto"}>
|
||||
<Stack spacing={0}>
|
||||
<Text fw={"bold"} lineClamp={1}>
|
||||
{e?.Profile?.name}
|
||||
</Text>
|
||||
<Text fz={"sm"} fs={"italic"}>
|
||||
+{e?.nomor}
|
||||
</Text>
|
||||
</Stack>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={2}>
|
||||
<Center h={"100%"}>
|
||||
<ActionIcon
|
||||
variant="transparent"
|
||||
onClick={() => {
|
||||
setLoading(true);
|
||||
router.push(
|
||||
RouterProfile.katalog + `${e?.Profile?.id}`
|
||||
);
|
||||
}}
|
||||
>
|
||||
<IconChevronRight />
|
||||
</ActionIcon>
|
||||
</Center>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
<Divider />
|
||||
</Stack>
|
||||
)
|
||||
)}
|
||||
</Box>
|
||||
)}
|
||||
<Box>
|
||||
{_.isEmpty(data) ? (
|
||||
<ComponentUserSearch_IsEmptyData text="Tidak ada pengguna" />
|
||||
) : (
|
||||
<Box>
|
||||
{data?.map((e, i) =>
|
||||
e?.Profile === null ? (
|
||||
""
|
||||
) : (
|
||||
<Stack key={i} spacing={"xs"} mt={"xs"}>
|
||||
<Grid>
|
||||
<Grid.Col span={2}>
|
||||
<Center h={"100%"}>
|
||||
<Avatar
|
||||
sx={{
|
||||
borderStyle: "solid",
|
||||
borderWidth: "0.5px",
|
||||
}}
|
||||
radius={"xl"}
|
||||
size={"md"}
|
||||
src={
|
||||
RouterProfile?.api_foto_profile +
|
||||
`${e?.Profile?.imagesId}`
|
||||
}
|
||||
/>
|
||||
</Center>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={"auto"}>
|
||||
<Stack spacing={0}>
|
||||
<Text fw={"bold"} lineClamp={1}>
|
||||
{e?.Profile?.name}
|
||||
</Text>
|
||||
<Text fz={"sm"} fs={"italic"}>
|
||||
+{e?.nomor}
|
||||
</Text>
|
||||
</Stack>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={2}>
|
||||
<Center h={"100%"}>
|
||||
<ActionIcon
|
||||
variant="transparent"
|
||||
onClick={() => {
|
||||
setLoading(true);
|
||||
router.push(
|
||||
RouterProfile.katalog + `${e?.Profile?.id}`
|
||||
);
|
||||
}}
|
||||
>
|
||||
<IconChevronRight />
|
||||
</ActionIcon>
|
||||
</Center>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
<Divider />
|
||||
</Stack>
|
||||
)
|
||||
)}
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
</Stack>
|
||||
</Box>
|
||||
{/* <pre>{JSON.stringify(data, null, 2)}</pre> */}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
48
yarn.lock
@@ -60,6 +60,13 @@
|
||||
dependencies:
|
||||
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":
|
||||
version "7.23.9"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.9.tgz#1dd7b59a9a2b5c87f8b41e52770b5ecbf492e002"
|
||||
@@ -1032,6 +1039,14 @@
|
||||
dependencies:
|
||||
"@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@*":
|
||||
version "18.2.57"
|
||||
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"
|
||||
integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==
|
||||
|
||||
clsx@^1.1.1:
|
||||
clsx@^1.0.4, clsx@^1.1.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12"
|
||||
integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==
|
||||
@@ -1784,7 +1799,7 @@ doctrine@^3.0.0:
|
||||
dependencies:
|
||||
esutils "^2.0.2"
|
||||
|
||||
dom-helpers@^5.0.1:
|
||||
dom-helpers@^5.0.1, dom-helpers@^5.1.3:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902"
|
||||
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"
|
||||
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:
|
||||
version "4.2.6"
|
||||
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"
|
||||
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:
|
||||
version "2.0.0"
|
||||
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"
|
||||
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:
|
||||
version "18.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"
|
||||
@@ -4494,6 +4533,11 @@ thenify-all@^1.0.0:
|
||||
dependencies:
|
||||
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:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-3.0.1.tgz#32f94d84dfa894f786c9a1f290e7a645b6a19abb"
|
||||
|
||||