Merge pull request #326 from bipproduction/amalia/05-nov-24

Amalia/05 nov 24
This commit is contained in:
Amalia
2024-11-05 16:46:35 +08:00
committed by GitHub
7 changed files with 108 additions and 88 deletions

View File

@@ -125,6 +125,11 @@ export async function GET(request: Request) {
updatedAt: true updatedAt: true
} }
} }
},
orderBy: {
DivisionDocumentFolderFile: {
createdAt: 'desc'
}
} }
}) })
@@ -169,7 +174,7 @@ export async function GET(request: Request) {
updatedAt: true updatedAt: true
}, },
orderBy: { orderBy: {
name: 'asc' createdAt: 'desc'
} }
}) })
@@ -185,7 +190,7 @@ export async function GET(request: Request) {
allData.push(...formatDataShare) allData.push(...formatDataShare)
} }
const formatData = _.orderBy(allData, ['category', 'name'], ['desc', 'asc']); const formatData = _.orderBy(allData, ['category', 'createdAt'], ['desc', 'asc']);
let pathNow = path let pathNow = path
let jalur = [] let jalur = []

View File

@@ -1,8 +1,4 @@
import { pwd_key_config } from "@/module/_global";
import { funDetectCookies, ViewLogin } from "@/module/auth"; import { funDetectCookies, ViewLogin } from "@/module/auth";
import { unsealData } from "iron-session";
import _ from "lodash";
import { cookies } from "next/headers";
import { redirect } from "next/navigation"; import { redirect } from "next/navigation";
export default async function Home() { export default async function Home() {

View File

@@ -1,28 +1,14 @@
"use client" "use client"
import { LayoutLogin, WARNA } from "@/module/_global"; import { LayoutLogin, WARNA } from "@/module/_global";
import { import { Box, Button, Stack, Text, TextInput } from "@mantine/core";
Box, import { useFocusTrap } from "@mantine/hooks";
Button, import { useState } from "react";
Checkbox,
Image,
rem,
Stack,
Text,
TextInput,
Title,
} from "@mantine/core";
import { useRouter } from "next/navigation";
import React, { useState } from "react";
import toast from "react-hot-toast"; import toast from "react-hot-toast";
import ViewVerification from "../../varification/view/view_verification"; import ViewVerification from "../../varification/view/view_verification";
import { useFocusTrap } from "@mantine/hooks";
function ViewLogin() { function ViewLogin() {
const focusTrapRef = useFocusTrap() const focusTrapRef = useFocusTrap()
const router = useRouter() const textInfo = "Kami akan mengirimkan kode verifikasi melalui WhatsApp untuk mengonfirmasi nomor Anda.";
const textInfo =
"Kami akan mengirimkan kode verifikasi melalui WhatsApp untuk mengonfirmasi nomor Anda.";
const [isPhone, setPhone] = useState("") const [isPhone, setPhone] = useState("")
const [isOTP, setOTP] = useState<any>(null) const [isOTP, setOTP] = useState<any>(null)
const [isValPhone, setValPhone] = useState<any>(null) const [isValPhone, setValPhone] = useState<any>(null)
@@ -37,46 +23,50 @@ function ViewLogin() {
if (isPhone.toString().length <= 11) if (isPhone.toString().length <= 11)
return toast.error('Nomor telepon tidak valid') return toast.error('Nomor telepon tidak valid')
const cek = await fetch('/api/auth/login', { try {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ phone: isPhone })
})
const cekLogin = await cek.json()
if (cekLogin.success) {
const code = Math.floor(Math.random() * 1000) + 1000
setLoading(true) setLoading(true)
try { const cek = await fetch('/api/auth/login', {
const res = await fetch(`https://wa.wibudev.com/code?nom=${cekLogin.phone}&text=*DARMASABA*%0A%0A method: 'POST',
JANGAN BERIKAN KODE RAHASIA ini kepada siapa pun TERMASUK PIHAK DARMASABA. Masukkan otentikasi: *${encodeURIComponent(code)}*`).then( headers: {
async (res) => { 'Content-Type': 'application/json'
if (res.status == 200) { },
setValPhone(cekLogin.phone) body: JSON.stringify({ phone: isPhone })
setOTP(code) })
setUser(cekLogin.id) const cekLogin = await cek.json()
setVerif(true) if (cekLogin.success) {
setLoading(false) const code = Math.floor(Math.random() * 1000) + 1000
toast.success('Kode verifikasi telah dikirim') try {
} else { const res = await fetch(`https://wa.wibudev.com/code?nom=${cekLogin.phone}&text=*DARMASABA*%0A%0A
console.error(res.status) JANGAN BERIKAN KODE RAHASIA ini kepada siapa pun TERMASUK PIHAK DARMASABA. Masukkan otentikasi: *${encodeURIComponent(code)}*`).then(
toast.error('Internal Server Error') async (res) => {
setLoading(false) if (res.status == 200) {
setValPhone(cekLogin.phone)
setOTP(code)
setUser(cekLogin.id)
setVerif(true)
toast.success('Kode verifikasi telah dikirim')
} else {
console.error(res.status)
toast.error('Internal Server Error')
}
} }
} )
) } catch (error) {
} catch (error) { console.error(error)
console.error(error) toast.error('Internal Server Error')
toast.error('Internal Server Error') }
}finally{ } else {
setLoading(false) return toast.error(cekLogin.message)
} }
} else { } catch (error) {
return toast.error(cekLogin.message) console.error(error)
toast.error('Internal Server Error')
} finally {
setLoading(false)
} }
} }
if (isVerif) return <ViewVerification otp={isOTP} phone={isValPhone} user={isUser} /> if (isVerif) return <ViewVerification otp={isOTP} phone={isValPhone} user={isUser} />

View File

@@ -8,11 +8,11 @@ import toast from "react-hot-toast";
import { FcFolder } from "react-icons/fc"; import { FcFolder } from "react-icons/fc";
import { GoChevronRight } from "react-icons/go"; import { GoChevronRight } from "react-icons/go";
import { MdFolder } from "react-icons/md"; import { MdFolder } from "react-icons/md";
import { useWibuRealtime } from "wibu-realtime";
import { funCreateFolder, funGetAllDocument } from "../lib/api_document"; import { funCreateFolder, funGetAllDocument } from "../lib/api_document";
import { IDataDocument, IFormDetailMoreItem, IJalurItem, } from "../lib/type_document"; import { IDataDocument, IFormDetailMoreItem, IJalurItem, } from "../lib/type_document";
import { useWibuRealtime } from "wibu-realtime";
export default function DrawerCutDocuments({ category, onChoosePath, data, }: { category: string; data: IFormDetailMoreItem[]; onChoosePath: (val: string) => void; }) { export default function DrawerCutDocuments({ category, loadingAction, onChoosePath, data, }: { category: string; loadingAction: boolean; data: IFormDetailMoreItem[]; onChoosePath: (val: string) => void; }) {
const [opened, setOpened] = useState(false); const [opened, setOpened] = useState(false);
const param = useParams<{ id: string }>(); const param = useParams<{ id: string }>();
const [path, setPath] = useState("home"); const [path, setPath] = useState("home");
@@ -100,6 +100,7 @@ export default function DrawerCutDocuments({ category, onChoosePath, data, }: {
</Grid.Col> </Grid.Col>
<Grid.Col span={6}> <Grid.Col span={6}>
<Button <Button
loading={loadingAction}
variant="filled" variant="filled"
fullWidth fullWidth
color={tema.get().utama} color={tema.get().utama}

View File

@@ -24,6 +24,7 @@ export default function DrawerMenuDocumentDivision() {
const openRef = useRef<() => void>(null) const openRef = useRef<() => void>(null)
const tema = useHookstate(TEMA) const tema = useHookstate(TEMA)
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const [loadingCreate, setLoadingCreate] = useState(false)
const [dataRealTime, setDataRealtime] = useWibuRealtime({ const [dataRealTime, setDataRealtime] = useWibuRealtime({
WIBU_REALTIME_TOKEN: keyWibu, WIBU_REALTIME_TOKEN: keyWibu,
project: "sdm" project: "sdm"
@@ -36,6 +37,7 @@ export default function DrawerMenuDocumentDivision() {
async function onCreateFolder() { async function onCreateFolder() {
try { try {
setLoadingCreate(true)
const res = await funCreateFolder(bodyFolder) const res = await funCreateFolder(bodyFolder)
if (!res.success) { if (!res.success) {
toast.error(res.message) toast.error(res.message)
@@ -48,11 +50,13 @@ export default function DrawerMenuDocumentDivision() {
} catch (error) { } catch (error) {
console.error(error); console.error(error);
toast.error("Gagal membuat folder baru, coba lagi nanti"); toast.error("Gagal membuat folder baru, coba lagi nanti");
} finally {
setLoadingCreate(false)
refresh.set(true)
setOpenModal(false)
setOpenDrawerDocument(false)
} }
refresh.set(true)
setOpenModal(false)
setOpenDrawerDocument(false)
} }
async function onUploadFile(data: any) { async function onUploadFile(data: any) {
@@ -204,7 +208,7 @@ export default function DrawerMenuDocumentDivision() {
<Button variant="subtle" fullWidth color='#969494' onClick={() => setOpenModal(false)}>Batalkan</Button> <Button variant="subtle" fullWidth color='#969494' onClick={() => setOpenModal(false)}>Batalkan</Button>
</Grid.Col> </Grid.Col>
<Grid.Col span={6}> <Grid.Col span={6}>
<Button variant="subtle" fullWidth color={tema.get().utama} onClick={() => onCreateFolder()}>Membuat</Button> <Button loading={loadingCreate} variant="subtle" fullWidth color={tema.get().utama} onClick={() => onCreateFolder()}>Membuat</Button>
</Grid.Col> </Grid.Col>
</Grid> </Grid>
</Box> </Box>

View File

@@ -2,15 +2,15 @@ import { keyWibu, LayoutDrawer, TEMA } from "@/module/_global";
import { useHookstate } from "@hookstate/core"; import { useHookstate } from "@hookstate/core";
import { Box, Flex, SimpleGrid, Stack, Text } from "@mantine/core"; import { Box, Flex, SimpleGrid, Stack, Text } from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks"; import { useShallowEffect } from "@mantine/hooks";
import { useParams } from "next/navigation"; import { useParams, useSearchParams } from "next/navigation";
import { useState } from "react"; import { useState } from "react";
import toast from "react-hot-toast"; import toast from "react-hot-toast";
import { LuFolders, LuFolderSymlink } from "react-icons/lu"; import { LuFolders, LuFolderSymlink } from "react-icons/lu";
import { useWibuRealtime } from "wibu-realtime";
import { funCopyDocument, funMoveDocument } from "../lib/api_document"; import { funCopyDocument, funMoveDocument } from "../lib/api_document";
import { IDataDocument } from "../lib/type_document"; import { IDataDocument } from "../lib/type_document";
import { globalRefreshDocument } from "../lib/val_document"; import { globalRefreshDocument } from "../lib/val_document";
import DrawerCutDocuments from "./drawer_cut_documents"; import DrawerCutDocuments from "./drawer_cut_documents";
import { useWibuRealtime } from "wibu-realtime";
export default function DrawerMore({ data }: { data: IDataDocument[] }) { export default function DrawerMore({ data }: { data: IDataDocument[] }) {
const [isCut, setIsCut] = useState(false) const [isCut, setIsCut] = useState(false)
@@ -19,20 +19,31 @@ export default function DrawerMore({ data }: { data: IDataDocument[] }) {
const param = useParams<{ id: string }>() const param = useParams<{ id: string }>()
const [forbidCopy, setForbidCopy] = useState(true) const [forbidCopy, setForbidCopy] = useState(true)
const tema = useHookstate(TEMA) const tema = useHookstate(TEMA)
const [loadingMove, setLoadingMove] = useState(false)
const [loadingCopy, setLoadingCopy] = useState(false)
const [dataRealTime, setDataRealtime] = useWibuRealtime({ const [dataRealTime, setDataRealtime] = useWibuRealtime({
WIBU_REALTIME_TOKEN: keyWibu, WIBU_REALTIME_TOKEN: keyWibu,
project: "sdm" project: "sdm"
}) })
const searchParams = useSearchParams()
const pathAwal = searchParams.get('path')
async function onMoveItem(path: string) { async function onMoveItem(path: string) {
try { try {
setLoadingMove(true)
const res = await funMoveDocument({ path, dataItem: data }) const res = await funMoveDocument({ path, dataItem: data })
if (res.success) { if (res.success) {
setDataRealtime([{ setDataRealtime([
category: "division-document", {
id: path, category: "division-document",
}]) id: path,
},
{
category: "division-document",
id: pathAwal,
}
])
toast.success(res.message) toast.success(res.message)
refresh.set(true) refresh.set(true)
} else { } else {
@@ -41,13 +52,16 @@ export default function DrawerMore({ data }: { data: IDataDocument[] }) {
} catch (error) { } catch (error) {
console.error(error) console.error(error)
toast.error("Gagal memindahkan item, coba lagi nanti") toast.error("Gagal memindahkan item, coba lagi nanti")
} finally {
setLoadingMove(false)
setIsCut(false)
} }
setIsCut(false)
} }
async function onCopyItem(path: string) { async function onCopyItem(path: string) {
try { try {
setLoadingCopy(true)
const res = await funCopyDocument({ idDivision: param.id, path, dataItem: data }) const res = await funCopyDocument({ idDivision: param.id, path, dataItem: data })
if (res.success) { if (res.success) {
setDataRealtime([{ setDataRealtime([{
@@ -62,8 +76,10 @@ export default function DrawerMore({ data }: { data: IDataDocument[] }) {
} catch (error) { } catch (error) {
console.error(error) console.error(error)
toast.error("Gagal memindahkan item, coba lagi nanti") toast.error("Gagal memindahkan item, coba lagi nanti")
} finally {
setLoadingCopy(false)
setIsCopy(false)
} }
setIsCopy(false)
} }
@@ -108,11 +124,11 @@ export default function DrawerMore({ data }: { data: IDataDocument[] }) {
<LayoutDrawer opened={isCut} onClose={() => setIsCut(false)} title={'Pilih Lokasi Pemindahan'} size="lg"> <LayoutDrawer opened={isCut} onClose={() => setIsCut(false)} title={'Pilih Lokasi Pemindahan'} size="lg">
<DrawerCutDocuments data={data} onChoosePath={(val) => { onMoveItem(val) }} category="move" /> <DrawerCutDocuments data={data} loadingAction={loadingMove} onChoosePath={(val) => { onMoveItem(val) }} category="move" />
</LayoutDrawer> </LayoutDrawer>
<LayoutDrawer opened={isCopy} onClose={() => setIsCopy(false)} title={'Pilih Lokasi Salin'} size="lg"> <LayoutDrawer opened={isCopy} onClose={() => setIsCopy(false)} title={'Pilih Lokasi Salin'} size="lg">
<DrawerCutDocuments data={data} onChoosePath={(val) => { onCopyItem(val) }} category="copy" /> <DrawerCutDocuments data={data} loadingAction={loadingCopy} onChoosePath={(val) => { onCopyItem(val) }} category="copy" />
</LayoutDrawer> </LayoutDrawer>
</Box> </Box>
); );

View File

@@ -18,13 +18,13 @@ import { HiMenu } from "react-icons/hi";
import { LuShare2 } from "react-icons/lu"; import { LuShare2 } from "react-icons/lu";
import { MdClose, MdOutlineMoreHoriz } from "react-icons/md"; import { MdClose, MdOutlineMoreHoriz } from "react-icons/md";
import { RiListCheck } from "react-icons/ri"; import { RiListCheck } from "react-icons/ri";
import { useWibuRealtime } from "wibu-realtime";
import { funDeleteDocument, funGetAllDocument, funRenameDocument, } from "../lib/api_document"; import { funDeleteDocument, funGetAllDocument, funRenameDocument, } from "../lib/api_document";
import { IDataDocument, IJalurItem } from "../lib/type_document"; import { IDataDocument, IJalurItem } from "../lib/type_document";
import { globalRefreshDocument } from "../lib/val_document"; import { globalRefreshDocument } from "../lib/val_document";
import DrawerMenuDocumentDivision from "./drawer_menu_document_division"; import DrawerMenuDocumentDivision from "./drawer_menu_document_division";
import DrawerMore from "./drawer_more"; import DrawerMore from "./drawer_more";
import DrawerShareDocument from "./drawer_share_document"; import DrawerShareDocument from "./drawer_share_document";
import { useWibuRealtime } from "wibu-realtime";
export default function NavbarDocumentDivision() { export default function NavbarDocumentDivision() {
const router = useRouter(); const router = useRouter();
@@ -52,6 +52,8 @@ export default function NavbarDocumentDivision() {
const isMobile2 = useMediaQuery("(max-width: 496px)"); const isMobile2 = useMediaQuery("(max-width: 496px)");
const tema = useHookstate(TEMA); const tema = useHookstate(TEMA);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [loadingRename, setLoadingRename] = useState(false);
const [loadingDelete, setLoadingDelete] = useState(false);
const [dataRealTime, setDataRealtime] = useWibuRealtime({ const [dataRealTime, setDataRealtime] = useWibuRealtime({
WIBU_REALTIME_TOKEN: keyWibu, WIBU_REALTIME_TOKEN: keyWibu,
project: "sdm" project: "sdm"
@@ -138,8 +140,9 @@ export default function NavbarDocumentDivision() {
}; };
async function onConfirmDelete(val: boolean) { async function onConfirmDelete(val: boolean) {
if (val) { try {
try { if (val) {
setLoadingDelete(true)
const respon = await funDeleteDocument(selectedFiles); const respon = await funDeleteDocument(selectedFiles);
if (respon.success) { if (respon.success) {
getOneData(false); getOneData(false);
@@ -150,19 +153,20 @@ export default function NavbarDocumentDivision() {
} else { } else {
toast.error(respon.message); toast.error(respon.message);
} }
} catch (error) { handleBatal();
console.error(error);
toast.error("Gagal menghapus item, coba lagi nanti");
} }
} catch (error) {
handleBatal(); console.error(error);
toast.error("Gagal menghapus item, coba lagi nanti");
} finally {
setLoadingDelete(false)
setIsDelete(false);
} }
setIsDelete(false);
} }
async function onRenameSubmit() { async function onRenameSubmit() {
try { try {
setLoadingRename(true);
const res = await funRenameDocument(bodyRename); const res = await funRenameDocument(bodyRename);
if (res.success) { if (res.success) {
setDataRealtime([{ setDataRealtime([{
@@ -176,11 +180,13 @@ export default function NavbarDocumentDivision() {
} catch (error) { } catch (error) {
console.error(error); console.error(error);
toast.error("Gagal mengganti nama item, coba lagi nanti"); toast.error("Gagal mengganti nama item, coba lagi nanti");
} finally {
setLoadingRename(false)
setSelectedFiles([]);
setDariSelectAll(false);
setRename(false);
} }
setSelectedFiles([]);
setDariSelectAll(false);
setRename(false);
} }
useShallowEffect(() => { useShallowEffect(() => {
@@ -802,6 +808,7 @@ export default function NavbarDocumentDivision() {
{/* MODAL KONFIRMASI DELETE */} {/* MODAL KONFIRMASI DELETE */}
<LayoutModal <LayoutModal
loading={loadingDelete}
opened={isDelete} opened={isDelete}
onClose={() => setIsDelete(false)} onClose={() => setIsDelete(false)}
description="Apakah Anda yakin ingin menghapus item?" description="Apakah Anda yakin ingin menghapus item?"
@@ -861,6 +868,7 @@ export default function NavbarDocumentDivision() {
</Grid.Col> </Grid.Col>
<Grid.Col span={6}> <Grid.Col span={6}>
<Button <Button
loading={loadingRename}
variant="subtle" variant="subtle"
fullWidth fullWidth
color={tema.get().utama} color={tema.get().utama}