Merge pull request #124 from bipproduction/amalia/16-agustus-24

upd: detail task
This commit is contained in:
Amalia
2024-08-16 17:31:56 +08:00
committed by GitHub
18 changed files with 545 additions and 386 deletions

View File

@@ -1,130 +0,0 @@
"use client";
import { LayoutDrawer, LayoutNavbarNew, WARNA } from "@/module/_global";
import { Box, Button, Center, Flex, Group, Input, Stack, Text } from "@mantine/core";
import { useRouter } from "next/navigation";
import React, { useState } from "react";
import { IoIosArrowDropright } from "react-icons/io";
import { BsFiletypeCsv } from "react-icons/bs";
import ResultsDateAndTask from "@/module/project/components/results_date-and_task";
import ResultsFile from "@/module/project/components/results_file";
export default function CreateTask({ searchParams }: { searchParams: any }) {
const router = useRouter();
const [openDrawer, setOpenDrawer] = useState(false);
return (
<Box>
<LayoutNavbarNew back="" title="tambah tugas" menu />
<Box p={20}>
<Stack>
<Input
styles={{
input: {
border: `1px solid ${"#D6D8F6"}`,
borderRadius: 10,
},
}}
placeholder="Nama Proyek"
size="md"
/>
<Box onClick={() => router.push("/task/create?page=task")}>
<Group
justify="space-between"
p={10}
style={{
border: `1px solid ${"#D6D8F6"}`,
borderRadius: 10,
}}
>
<Text>Tambah Tanggal & Tugas</Text>
<IoIosArrowDropright size={25} />
</Group>
</Box>
<Group
justify="space-between"
p={10}
style={{
border: `1px solid ${"#D6D8F6"}`,
borderRadius: 10,
}}
onClick={() => setOpenDrawer(true)}
>
<Text>Upload File</Text>
<IoIosArrowDropright size={25} />
</Group>
</Stack>
{
(searchParams.anggota == 'yes') &&
<>
<ResultsDateAndTask />
</>
}
{(searchParams.files == 'yes') &&
<>
<ResultsFile />
</>
}
{
(searchParams.button == 'yes') &&
<>
<Box mt="xl">
<Button color="white" bg={WARNA.biruTua} size="lg" radius={30} fullWidth onClick={() => router.push('/task')}>
Simpan
</Button>
</Box>
</>
}
</Box>
<LayoutDrawer
opened={openDrawer}
onClose={() => setOpenDrawer(false)}
title={"Pilih File"}
>
<Flex justify={"space-around"}>
<Box onClick={() => ""}>
<Box
bg={"#DCEED8"}
style={{
border: `1px solid ${"#D6D8F6"}`,
padding: 20,
borderRadius: 10,
}}
>
<Center>
<BsFiletypeCsv size={40} />
</Center>
</Box>
<Text mt={10} ta={"center"}>
Pilih file
</Text>
<Text ta={"center"}>diperangkat</Text>
</Box>
<Box onClick={() => router.push("/task/create?page=file-save")}>
<Box
bg={"#DCEED8"}
style={{
border: `1px solid ${"#D6D8F6"}`,
padding: 20,
borderRadius: 10,
}}
>
<Center>
<BsFiletypeCsv size={40} />
</Center>
</Box>
<Text mt={10} ta={"center"}>
Pilih file yang
</Text>
<Text ta={"center"}>sudah ada</Text>
</Box>
</Flex>
</LayoutDrawer>
</Box >
);
}

View File

@@ -1,89 +0,0 @@
import { WARNA } from "@/module/_global";
import { Box, Group, Flex, Avatar, Text } from "@mantine/core";
const dataAnggota = [
{
id: 1,
name: "Iqbal Ramadan",
image: "https://i.pravatar.cc/1000?img=5",
email: "iqbal.ramadan@gmail.com",
},
{
id: 2,
name: "Doni Setiawan",
image: "https://i.pravatar.cc/1000?img=10",
email: "doni.setiawan@gmail.com",
},
{
id: 3,
name: "Rangga Agung",
image: "https://i.pravatar.cc/1000?img=51",
email: "rangga.agung@gmail.com",
},
{
id: 4,
name: "Ramadan Sananta",
image: "https://i.pravatar.cc/1000?img=15",
email: "ramadan@gmail.com",
},
{
id: 5,
name: "Imam Baroni",
image: "https://i.pravatar.cc/1000?img=22",
email: "imam.baroni@gmail.com",
},
];
export default function ListAnggotaDetailTask() {
return (
<Box pt={20}>
<Group justify="space-between">
<Text c={WARNA.biruTua}>Anggota Terpilih</Text>
<Text c={WARNA.biruTua}>Total 10 Anggota</Text>
</Group>
<Box pt={10}>
<Box mb={20}>
<Box
style={{
border: `1px solid ${"#C7D6E8"}`,
borderRadius: 10,
}}
px={20}
py={10}
>
<Text c={WARNA.biruTua} fw={"bold"}>
Divisi Kerohanian
</Text>
{dataAnggota.map((v, i) => {
return (
<Flex
justify={"space-between"}
align={"center"}
mt={20}
key={i}
>
<Group>
<Avatar src={v.image} alt="it's me" size="lg" />
<Box>
<Text c={WARNA.biruTua} fw={"bold"}>
{v.name}
</Text>
<Text c={"#5A687D"} fz={14}>
{v.email}
</Text>
</Box>
</Group>
<Text c={WARNA.biruTua} fw={"bold"}>
Anggota
</Text>
</Flex>
);
})}
</Box>
</Box>
</Box>
</Box>
)
}

View File

@@ -1,37 +0,0 @@
import { WARNA } from "@/module/_global";
import { Box, Group, Text } from "@mantine/core";
import { BsFiletypeCsv } from "react-icons/bs";
export default function ListFileDetailTask() {
return (
<Box pt={20}>
<Text fw={'bold'} c={WARNA.biruTua}>File</Text>
<Box bg={"white"} style={{
borderRadius: 10,
border: `1px solid ${"#D6D8F6"}`,
padding: 20
}}>
<Box style={{
borderRadius: 10,
border: `1px solid ${"#D6D8F6"}`,
padding: 10
}} mb={10}>
<Group>
<BsFiletypeCsv size={25} />
<Text>Proyek Laporan Permasyarakatan</Text>
</Group>
</Box>
<Box style={{
borderRadius: 10,
border: `1px solid ${"#D6D8F6"}`,
padding: 10
}}>
<Group>
<BsFiletypeCsv size={25} />
<Text>Proyek Laporan Permasyarakatan</Text>
</Group>
</Box>
</Box>
</Box>
)
}

View File

@@ -1,77 +0,0 @@
'use client'
import { WARNA } from "@/module/_global"
import { Box, Grid, Center, Checkbox, Group, SimpleGrid, Text } from "@mantine/core"
import { AiOutlineFileSync } from "react-icons/ai"
export default function ListTugasDetailTask() {
return (
<Box pt={20}>
<Text fw={"bold"} c={WARNA.biruTua}>
Tanggal & Tugas
</Text>
<Box
bg={"white"}
style={{
borderRadius: 10,
border: `1px solid ${"#D6D8F6"}`,
padding: 20,
}}
>
<Grid>
<Grid.Col span={"auto"}>
<Center>
<Checkbox color="teal" size="md" />
</Center>
</Grid.Col>
<Grid.Col span={10}>
<Box
style={{
borderRadius: 10,
border: `1px solid ${"#D6D8F6"}`,
padding: 10,
}}
>
<Group>
<AiOutlineFileSync size={25} />
<Text>Laporan Permasyarakatan</Text>
</Group>
</Box>
<Box>
<SimpleGrid cols={{ base: 2, sm: 2, lg: 2 }} mt={20}>
<Box>
<Text>Tanggal Mulai</Text>
<Group
justify="center"
bg={"white"}
h={45}
style={{
borderRadius: 10,
border: `1px solid ${"#D6D8F6"}`,
}}
>
<Text>16 Juni 2024</Text>
</Group>
</Box>
<Box>
<Text c={WARNA.biruTua}>Tanggal Berakhir</Text>
<Group
justify="center"
bg={"white"}
h={45}
style={{
borderRadius: 10,
border: `1px solid ${"#D6D8F6"}`,
}}
>
<Text>20 Juni 2024</Text>
</Group>
</Box>
</SimpleGrid>
</Box>
</Grid.Col>
</Grid>
</Box>
</Box>
)
}

View File

@@ -1,23 +0,0 @@
'use client'
import { LayoutNavbarNew, WARNA } from "@/module/_global";
import { ActionIcon } from "@mantine/core";
import { useRouter } from "next/navigation";
import { LuClipboardEdit } from "react-icons/lu";
export default function NavbarDetailDivisionTask() {
const router = useRouter()
return (
<LayoutNavbarNew back="" title="Tugas 1" menu={
<ActionIcon
variant="light"
bg={WARNA.bgIcon}
size="lg"
radius="lg"
aria-label="Settings"
onClick={() => router.push("/task/update/1")}
>
<LuClipboardEdit size={20} color="white" />
</ActionIcon>
} />
)
}

View File

@@ -1,20 +0,0 @@
import { Box } from "@mantine/core";
import NavbarDetailDivisionTask from "../component/navbar_detail_division_task";
import ProgressDetailTask from "../component/detail_progress_task";
import ListTugasDetailTask from "../component/detail_list_tugas_task";
import ListFileDetailTask from "../component/detail_list_file_task";
import ListAnggotaDetailTask from "../component/detail_list_anggota_task";
export default function ViewDetailDivisionTask() {
return (
<Box>
<NavbarDetailDivisionTask />
<Box p={20}>
<ProgressDetailTask />
<ListTugasDetailTask />
<ListFileDetailTask />
<ListAnggotaDetailTask />
</Box>
</Box>
)
}

View File

@@ -9,7 +9,6 @@ import ViewDivisionCalender from "./_division_fitur/calender/view/view_division_
import ViewHistoryDivisionCalender from "./_division_fitur/calender/view/view_history_division_calender";
import ViewUpdateDivisionCalender from "./_division_fitur/calender/view/view_update_division_calender";
import ViewDocumentDivision from "./_division_fitur/document/view/view_document_division";
import ViewDetailDivisionTask from "./_division_fitur/task/view/view_detail_division_task";
import ViewUpdateProgressDivisionTask from "./_division_fitur/task/view/view_update_progress_division_task";
import CreateAdminDivision from "./ui/create_admin_division";
import CreateUsers from "./ui/create_users";
@@ -30,7 +29,6 @@ import { funGetDivisionById } from './lib/api_division';
export { CreateUsers };
export { CreateAdminDivision };
export { ViewDetailDivisionTask };
export { ViewUpdateProgressDivisionTask };
export { ViewDivisionCalender };
export { ViewCreateDivisionCalender };

View File

@@ -1,7 +1,12 @@
import ViewDateEndTask from "./ui/create_date_end_task";
import CreateTask from "./ui/create_task";
import CreateUsersProject from "./ui/create_users_project";
import ListAnggotaDetailTask from "./ui/detail_list_anggota_task";
import ListFileDetailTask from "./ui/detail_list_file_task";
import ListTugasDetailTask from "./ui/detail_list_tugas_task";
import ProgressDetailTask from "./ui/detail_progress_task";
import FileSave from "./ui/file_save";
import NavbarDetailDivisionTask from "./ui/navbar_detail_division_task";
import NavbarDivisionTask from "./ui/navbar_division_task";
import TabsDivisionTask from "./ui/tabs_division_task";
@@ -10,4 +15,9 @@ export { TabsDivisionTask }
export { CreateTask }
export { ViewDateEndTask }
export { CreateUsersProject }
export { FileSave }
export { FileSave }
export { NavbarDetailDivisionTask }
export { ListTugasDetailTask }
export { ProgressDetailTask }
export { ListFileDetailTask }
export { ListAnggotaDetailTask }

View File

@@ -18,4 +18,9 @@ export const funCreateTask = async (data: IFormTaskDivision) => {
body: JSON.stringify(data),
});
return await response.json().catch(() => null);
};
};
export const funGetTaskDivisionById = async (path: string, kategori: string) => {
const response = await fetch(`/api/task/${path}?cat=${kategori}`);
return await response.json().catch(() => null);
}

View File

@@ -31,4 +31,25 @@ export interface IFormTaskDivision {
export interface IListFileTask {
name: string,
extension: string
}
export interface IDataListTaskDivision {
id: string
title: string
dateStart: string
dateEnd: string
status: number
}
export interface IDataMemberTaskDivision {
id: string
name: string
email: string
}
export interface IDataFileTaskDivision {
id: string
name: string
extension: string
}

View File

@@ -0,0 +1,88 @@
'use client'
import { WARNA } from "@/module/_global";
import { Box, Group, Flex, Avatar, Text } from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks";
import { useParams } from "next/navigation";
import { useState } from "react";
import toast from "react-hot-toast";
import { funGetTaskDivisionById } from "../lib/api_task";
import { IDataMemberTaskDivision } from "../lib/type_task";
export default function ListAnggotaDetailTask() {
const [isData, setData] = useState<IDataMemberTaskDivision[]>([])
const [loading, setLoading] = useState(true)
const param = useParams<{ id: string, detail: string }>()
async function getOneData() {
try {
setLoading(true)
const res = await funGetTaskDivisionById(param.detail, 'member');
if (res.success) {
setData(res.data)
} else {
toast.error(res.message);
}
} catch (error) {
console.error(error);
toast.error("Gagal mendapatkan member tugas divisi, coba lagi nanti");
} finally {
setLoading(false)
}
}
useShallowEffect(() => {
getOneData();
}, [param.detail])
return (
<Box pt={20}>
<Group justify="space-between">
<Text c={WARNA.biruTua}>Anggota Terpilih</Text>
<Text c={WARNA.biruTua}>Total {isData.length} Anggota</Text>
</Group>
<Box pt={10}>
<Box mb={20}>
<Box
style={{
border: `1px solid ${"#C7D6E8"}`,
borderRadius: 10,
}}
px={20}
py={10}
>
{
loading ? <Text>loading</Text> :
isData.length === 0 ? <Text>Tidak ada anggota</Text> :
isData.map((v, i) => {
return (
<Flex
justify={"space-between"}
align={"center"}
mt={20}
key={i}
>
<Group>
<Avatar src={""} alt="it's me" size="lg" />
<Box>
<Text c={WARNA.biruTua} fw={"bold"}>
{v.name}
</Text>
<Text c={"#5A687D"} fz={14}>
{v.email}
</Text>
</Box>
</Group>
<Text c={WARNA.biruTua} fw={"bold"}>
Anggota
</Text>
</Flex>
);
})}
</Box>
</Box>
</Box>
</Box>
)
}

View File

@@ -0,0 +1,76 @@
'use client'
import { WARNA } from "@/module/_global";
import { Box, Group, Text } from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks";
import { useParams } from "next/navigation";
import { useState } from "react";
import toast from "react-hot-toast";
import { BsFiletypeCsv, BsFiletypeHeic, BsFiletypeJpg, BsFiletypePdf, BsFiletypePng } from "react-icons/bs";
import { funGetTaskDivisionById } from "../lib/api_task";
import { IDataFileTaskDivision } from "../lib/type_task";
export default function ListFileDetailTask() {
const [isData, setData] = useState<IDataFileTaskDivision[]>([])
const [loading, setLoading] = useState(true)
const param = useParams<{ id: string, detail: string }>()
async function getOneData() {
try {
setLoading(true)
const res = await funGetTaskDivisionById(param.detail, 'file');
if (res.success) {
setData(res.data)
} else {
toast.error(res.message);
}
} catch (error) {
console.error(error);
toast.error("Gagal mendapatkan file tugas divisi, coba lagi nanti");
} finally {
setLoading(false)
}
}
useShallowEffect(() => {
getOneData();
}, [param.detail])
return (
<Box pt={20}>
<Text fw={'bold'} c={WARNA.biruTua}>File</Text>
<Box bg={"white"} style={{
borderRadius: 10,
border: `1px solid ${"#D6D8F6"}`,
padding: 20
}}>
{
loading ? <Text>loading</Text> :
isData.length === 0 ? <Text>Tidak ada file</Text> :
isData.map((item, index) => {
return (
<Box
key={index}
style={{
borderRadius: 10,
border: `1px solid ${"#D6D8F6"}`,
padding: 10
}}
mb={10}
>
<Group>
{item.extension == "pdf" && <BsFiletypePdf size={25} />}
{item.extension == "csv" && <BsFiletypeCsv size={25} />}
{item.extension == "png" && <BsFiletypePng size={25} />}
{item.extension == "jpg" || item.extension == "jpeg" && <BsFiletypeJpg size={25} />}
{item.extension == "heic" && <BsFiletypeHeic size={25} />}
<Text>{item.name}</Text>
</Group>
</Box>
)
})
}
</Box>
</Box>
)
}

View File

@@ -0,0 +1,116 @@
'use client'
import { WARNA } from "@/module/_global"
import { Box, Grid, Center, Checkbox, Group, SimpleGrid, Text } from "@mantine/core"
import { useShallowEffect } from "@mantine/hooks"
import { useParams } from "next/navigation"
import toast from "react-hot-toast"
import { AiOutlineFileSync } from "react-icons/ai"
import { funGetTaskDivisionById } from "../lib/api_task"
import { useState } from "react"
import { IDataListTaskDivision } from "../lib/type_task"
export default function ListTugasDetailTask() {
const [isData, setData] = useState<IDataListTaskDivision[]>([])
const [loading, setLoading] = useState(true)
const param = useParams<{ id: string, detail: string }>()
async function getOneData() {
try {
setLoading(true)
const res = await funGetTaskDivisionById(param.detail, 'task');
if (res.success) {
setData(res.data)
} else {
toast.error(res.message);
}
} catch (error) {
console.error(error);
toast.error("Gagal mendapatkan list tugas divisi, coba lagi nanti");
} finally {
setLoading(false)
}
}
useShallowEffect(() => {
getOneData();
}, [param.detail])
return (
<Box pt={20}>
<Text fw={"bold"} c={WARNA.biruTua}>
Tanggal & Tugas
</Text>
<Box
bg={"white"}
style={{
borderRadius: 10,
border: `1px solid ${"#D6D8F6"}`,
padding: 20,
}}
>
{
loading ? <Text>loading</Text> :
isData.length === 0 ? <Text>Tidak ada tugas</Text> :
isData.map((item, index) => {
return (
<Grid key={index} style={{ borderBottom: "1px solid #D6D8F6" }} pb={10} mb={10}>
<Grid.Col span={"auto"}>
<Center>
<Checkbox color="teal" size="md" checked={(item.status === 1) ? true : false} disabled />
</Center>
</Grid.Col>
<Grid.Col span={10}>
<Box
style={{
borderRadius: 10,
border: `1px solid ${"#D6D8F6"}`,
padding: 10,
}}
>
<Group>
<AiOutlineFileSync size={25} />
<Text>{item.title}</Text>
</Group>
</Box>
<Box>
<SimpleGrid cols={{ base: 2, sm: 2, lg: 2 }} mt={20}>
<Box>
<Text>Tanggal Mulai</Text>
<Group
justify="center"
bg={"white"}
h={45}
style={{
borderRadius: 10,
border: `1px solid ${"#D6D8F6"}`,
}}
>
<Text>{item.dateStart}</Text>
</Group>
</Box>
<Box>
<Text c={WARNA.biruTua}>Tanggal Berakhir</Text>
<Group
justify="center"
bg={"white"}
h={45}
style={{
borderRadius: 10,
border: `1px solid ${"#D6D8F6"}`,
}}
>
<Text>{item.dateEnd}</Text>
</Group>
</Box>
</SimpleGrid>
</Box>
</Grid.Col>
</Grid>
)
})
}
</Box>
</Box>
)
}

View File

@@ -1,9 +1,37 @@
'use client'
import { WARNA } from "@/module/_global";
import { Box, Grid, ActionIcon, Progress, Text } from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks";
import { useParams } from "next/navigation";
import toast from "react-hot-toast";
import { HiMiniPresentationChartBar } from "react-icons/hi2";
import { funGetTaskDivisionById } from "../lib/api_task";
import { useState } from "react";
export default function ProgressDetailTask() {
const [valProgress, setValProgress] = useState(0)
const [valLastUpdate, setValLastUpdate] = useState('')
const param = useParams<{ id: string, detail: string }>()
async function getOneData() {
try {
const res = await funGetTaskDivisionById(param.detail, 'progress');
if (res.success) {
setValProgress(res.data.progress);
setValLastUpdate(res.data.lastUpdate);
} else {
toast.error(res.message);
}
} catch (error) {
console.error(error);
toast.error("Gagal mendapatkan progress tugas divisi, coba lagi nanti");
}
}
useShallowEffect(() => {
getOneData();
}, [param.detail])
return (
<Box mt={10}>
<Box
@@ -27,7 +55,7 @@ export default function ProgressDetailTask() {
</Grid.Col>
<Grid.Col span={9}>
<Box>
<Text>Kemajuan Proyek 60%</Text>
<Text>Kemajuan Proyek {valProgress}%</Text>
<Progress
style={{
border: `1px solid ${"#BDBDBD"}`,
@@ -36,9 +64,9 @@ export default function ProgressDetailTask() {
color="#FCAA4B"
radius="md"
size="xl"
value={60}
value={valProgress}
/>
<Text>18 Juni 2024</Text>
<Text>{valLastUpdate}</Text>
</Box>
</Grid.Col>
</Grid>

View File

@@ -136,7 +136,7 @@ export default function ListDivisionTask() {
{isData.map((v, i) => {
return (
<Box key={i}>
<Group justify="space-between" mb={10} onClick={() => router.push(`/task/${v.id}`)}>
<Group justify="space-between" mb={10} onClick={() => router.push(`task/${v.id}`)}>
<Group>
<Center>
<ActionIcon

View File

@@ -0,0 +1,50 @@
'use client'
import { LayoutNavbarNew, WARNA } from "@/module/_global";
import { ActionIcon } from "@mantine/core";
import { useParams, useRouter } from "next/navigation";
import { useState } from "react";
import toast from "react-hot-toast";
import { LuClipboardEdit } from "react-icons/lu";
import { funGetTaskDivisionById } from "../lib/api_task";
import { useShallowEffect } from "@mantine/hooks";
export default function NavbarDetailDivisionTask() {
const router = useRouter()
const param = useParams<{ id: string, detail: string }>()
const [name, setName] = useState('')
async function getOneData() {
try {
const res = await funGetTaskDivisionById(param.detail, 'data');
if (res.success) {
setName(res.data.title);
} else {
toast.error(res.message);
}
} catch (error) {
console.error(error);
toast.error("Gagal mendapatkan data tugas divisi, coba lagi nanti");
}
}
useShallowEffect(() => {
getOneData();
}, [param.detail])
return (
<LayoutNavbarNew back="" title={name} menu={
<ActionIcon
variant="light"
bg={WARNA.bgIcon}
size="lg"
radius="lg"
aria-label="Settings"
onClick={() => router.push("/task/update/1")}
>
<LuClipboardEdit size={20} color="white" />
</ActionIcon>
} />
)
}