Merge pull request #146 from bipproduction/lukman/26-agustus-2024

feat : update validation
This commit is contained in:
Amalia
2024-08-26 17:36:32 +08:00
committed by GitHub
27 changed files with 762 additions and 318 deletions

View File

@@ -26,6 +26,10 @@ export default function CreateAnnouncement() {
title: "", title: "",
desc: "", desc: "",
}) })
const [touched, setTouched] = useState({
title: false,
desc: false
});
async function onSubmit() { async function onSubmit() {
@@ -85,7 +89,16 @@ export default function CreateAnnouncement() {
}, },
}} }}
value={isData.title} value={isData.title}
onChange={(e) => { setisData({ ...isData, title: e.target.value }) }} onChange={(e) => {
setisData({ ...isData, title: e.target.value })
setTouched({ ...touched, title: false })
}}
onBlur={() => setTouched({ ...touched, title: true })}
error={
touched.title && (
isData.title == "" ? "Judul Tidak Boleh Kosong" : null
)
}
/> />
<Textarea <Textarea
size="md" size="md"
@@ -102,7 +115,16 @@ export default function CreateAnnouncement() {
}, },
}} }}
value={isData.desc} value={isData.desc}
onChange={(e) => { setisData({ ...isData, desc: e.target.value }) }} onChange={(e) => {
setisData({ ...isData, desc: e.target.value })
setTouched({ ...touched, desc: false })
}}
onBlur={() => setTouched({ ...touched, desc: true })}
error={
touched.desc && (
isData.desc == "" ? "Pengumuman Tidak Boleh Kosong" : null
)
}
/> />
<Box pt={10}> <Box pt={10}>
<Group justify="space-between" style={{ <Group justify="space-between" style={{
@@ -145,7 +167,16 @@ export default function CreateAnnouncement() {
size="md" size="md"
radius={30} radius={30}
fullWidth fullWidth
onClick={() => { setOpen(true) }} onClick={() => {
if (
isData.title !== "" &&
isData.desc !== ""
) {
setOpen(true)
} else {
toast.error("Isi data dengan lengkap")
}
}}
> >
Simpan Simpan
</Button> </Button>

View File

@@ -17,6 +17,10 @@ export default function EditAnnouncement() {
const [isOpen, setOpen] = useState(false) const [isOpen, setOpen] = useState(false)
const [isChooseDivisi, setChooseDivisi] = useState(false) const [isChooseDivisi, setChooseDivisi] = useState(false)
const param = useParams<{ id: string }>() const param = useParams<{ id: string }>()
const [touched, setTouched] = useState({
title: false,
desc: false
});
const [body, setBody] = useState({ const [body, setBody] = useState({
title: "", title: "",
desc: "", desc: "",
@@ -116,7 +120,16 @@ export default function EditAnnouncement() {
}, },
}} }}
value={body.title} value={body.title}
onChange={(val) => setBody({ ...body, title: val.target.value })} onChange={(val) => {
setBody({ ...body, title: val.target.value })
setTouched({ ...touched, title: false })
}}
onBlur={() => setTouched({ ...touched, title: true })}
error={
touched.title && (
body.title == "" ? "Judul Tidak Boleh Kosong" : null
)
}
/> />
<Textarea <Textarea
size="md" size="md"
@@ -133,7 +146,17 @@ export default function EditAnnouncement() {
}, },
}} }}
value={body.desc} value={body.desc}
onChange={(val) => setBody({ ...body, desc: val.target.value })} onChange={(val) => {
setBody({ ...body, desc: val.target.value })
setTouched({ ...touched, desc: false })
}}
onBlur={() => setTouched({ ...touched, desc: true })}
error={
touched.desc && (
body.desc == "" ? "Pengumuman Tidak Boleh Kosong" : null
)
}
/> />
<Button onClick={() => { setChooseDivisi(true) }} rightSection={<HiOutlineChevronRight size={14} />} variant="default" fullWidth radius={30} size="md" mt={10}> <Button onClick={() => { setChooseDivisi(true) }} rightSection={<HiOutlineChevronRight size={14} />} variant="default" fullWidth radius={30} size="md" mt={10}>
@@ -169,7 +192,16 @@ export default function EditAnnouncement() {
size="md" size="md"
radius={30} radius={30}
fullWidth fullWidth
onClick={() => { setOpen(true) }} onClick={() => {
if (
body.title !== "" &&
body.desc !== ""
) {
setOpen(true)
} else {
toast.error("Isi data dengan lengkap")
}
}}
> >
Simpan Simpan
</Button> </Button>

View File

@@ -1,6 +1,6 @@
'use client' 'use client'
import { LayoutDrawer, LayoutNavbarNew, WARNA } from '@/module/_global'; import { LayoutDrawer, LayoutNavbarNew, SkeletonSingle, WARNA } from '@/module/_global';
import { ActionIcon, Avatar, Box, CopyButton, Flex, Group, Stack, Text, Tooltip } from '@mantine/core'; import { ActionIcon, Avatar, Box, CopyButton, Flex, Group, Skeleton, Stack, Text, Tooltip } from '@mantine/core';
import React, { useState } from 'react'; import React, { useState } from 'react';
import { BsCalendar2Event, BsCalendarDate } from 'react-icons/bs'; import { BsCalendar2Event, BsCalendarDate } from 'react-icons/bs';
import { MdEventNote, MdOutlineFormatListBulleted } from "react-icons/md"; import { MdEventNote, MdOutlineFormatListBulleted } from "react-icons/md";
@@ -15,6 +15,7 @@ import { useShallowEffect } from '@mantine/hooks';
import moment from "moment"; import moment from "moment";
import "moment/locale/id"; import "moment/locale/id";
import { IDataDetailByIdCalender, IDataDetailByIdMember } from '../lib/type_calender'; import { IDataDetailByIdCalender, IDataDetailByIdMember } from '../lib/type_calender';
import SkeletonDetailEvent from './skeleton_detail_event';
export default function DetailEventDivision() { export default function DetailEventDivision() {
const [openDrawer, setOpenDrawer] = useState(false) const [openDrawer, setOpenDrawer] = useState(false)
@@ -22,16 +23,21 @@ export default function DetailEventDivision() {
const [isDataCalender, setDataCalender] = useState<IDataDetailByIdCalender>() const [isDataCalender, setDataCalender] = useState<IDataDetailByIdCalender>()
const [isDataAnggota, setDataAnggota] = useState<IDataDetailByIdMember[]>([]) const [isDataAnggota, setDataAnggota] = useState<IDataDetailByIdMember[]>([])
const [isLengthMember, setLengthMember] = useState() const [isLengthMember, setLengthMember] = useState()
const [loading, setLoading] = useState(true)
const getData = async () => { const getData = async () => {
try { try {
setLoading(true)
const response = await funGetOneCalender(param.detail) const response = await funGetOneCalender(param.detail)
setDataCalender(response.data.calender) setDataCalender(response.data.calender)
setDataAnggota(response.data.member) setDataAnggota(response.data.member)
setLengthMember(response.data.total) setLengthMember(response.data.total)
setLoading(false)
} catch (error) { } catch (error) {
console.log(error) console.log(error)
} finally {
setLoading(false)
} }
} }
@@ -41,11 +47,15 @@ export default function DetailEventDivision() {
return ( return (
<Box> <Box>
<LayoutNavbarNew back="" title="Detail Event" <LayoutNavbarNew back={`/division/${param.id}/calender/`} title="Detail Event"
menu={<ActionIcon variant="light" onClick={() => setOpenDrawer(true)} bg={WARNA.bgIcon} size="lg" radius="lg" aria-label="Settings"> menu={<ActionIcon variant="light" onClick={() => setOpenDrawer(true)} bg={WARNA.bgIcon} size="lg" radius="lg" aria-label="Settings">
<HiMenu size={20} color='white' /> <HiMenu size={20} color='white' />
</ActionIcon>} /> </ActionIcon>} />
<Box p={20}> <Box p={20}>
{loading
?
<SkeletonDetailEvent/>
:
<Box style={{ <Box style={{
border: `1px solid ${"#D8D8F1"}`, border: `1px solid ${"#D8D8F1"}`,
padding: 20, padding: 20,
@@ -77,6 +87,7 @@ export default function DetailEventDivision() {
</Group> </Group>
<Group mb={10} gap={30}> <Group mb={10} gap={30}>
<LuLink size={25} color={WARNA.biruTua} /> <LuLink size={25} color={WARNA.biruTua} />
{isDataCalender?.linkMeet ? (
<Group justify='space-between'> <Group justify='space-between'>
<Text>{isDataCalender?.linkMeet}</Text> <Text>{isDataCalender?.linkMeet}</Text>
<CopyButton value={String(isDataCalender?.linkMeet)} timeout={2000}> <CopyButton value={String(isDataCalender?.linkMeet)} timeout={2000}>
@@ -93,13 +104,45 @@ export default function DetailEventDivision() {
)} )}
</CopyButton> </CopyButton>
</Group> </Group>
) : (
<Text>-</Text>
)
}
</Group> </Group>
<Group gap={30}> <Group gap={30}>
<MdOutlineFormatListBulleted size={25} color={WARNA.biruTua} /> <MdOutlineFormatListBulleted size={25} color={WARNA.biruTua} />
{isDataCalender?.desc ? (
<Text>{isDataCalender?.desc}</Text> <Text>{isDataCalender?.desc}</Text>
) : (
<Text>-</Text>
)
}
</Group> </Group>
</Stack> </Stack>
</Box> </Box>
}
{loading ?
<Box pt={20}>
<Box
style={{
border: `1px solid ${"#C7D6E8"}`,
borderRadius: 10,
}}
px={20}
pb={20}
>
{Array(4)
.fill(null)
.map((_, i) => (
<Box
key={i}
>
<SkeletonSingle />
</Box>
))}
</Box>
</Box>
:
<Box pt={20}> <Box pt={20}>
<Group justify='space-between'> <Group justify='space-between'>
<Text fw={"bold"}>Total Anggota</Text> <Text fw={"bold"}>Total Anggota</Text>
@@ -139,6 +182,7 @@ export default function DetailEventDivision() {
</Box> </Box>
</Box> </Box>
</Box> </Box>
}
</Box> </Box>
<LayoutDrawer opened={openDrawer} title={'Menu'} onClose={() => setOpenDrawer(false)}> <LayoutDrawer opened={openDrawer} title={'Menu'} onClose={() => setOpenDrawer(false)}>
<DrawerDetailEvent /> <DrawerDetailEvent />

View File

@@ -27,7 +27,6 @@ export default function NavbarCreateDivisionCalender() {
dateStart: false, dateStart: false,
timeStart: false, timeStart: false,
timeEnd: false, timeEnd: false,
linkMeet: false,
repeatEventTyper: false, repeatEventTyper: false,
desc: false desc: false
}) })
@@ -94,7 +93,7 @@ export default function NavbarCreateDivisionCalender() {
return ( return (
<Box> <Box>
<LayoutNavbarNew back="/calender" title="tambah kalender" menu /> <LayoutNavbarNew back={`/division/${param.id}/calender/`} title="tambah kalender" menu />
<Box p={20}> <Box p={20}>
<Stack> <Stack>
<TextInput <TextInput
@@ -179,12 +178,12 @@ export default function NavbarCreateDivisionCalender() {
error={ error={
touched.timeEnd && ( touched.timeEnd && (
isData.timeEnd == "" ? "Waktu Akhir Tidak Boleh Kosong" : null isData.timeEnd == "" ? "Waktu Akhir Tidak Boleh Kosong" : null
) ) ||
(isData.timeStart > isData.timeEnd ? "Waktu Akhir Tidak Tepat" : null)
} }
/> />
</SimpleGrid> </SimpleGrid>
<TextInput <TextInput
required
styles={{ styles={{
input: { input: {
border: `1px solid ${"#D6D8F6"}`, border: `1px solid ${"#D6D8F6"}`,
@@ -196,12 +195,6 @@ export default function NavbarCreateDivisionCalender() {
label="Link Meet" label="Link Meet"
value={isData.linkMeet} value={isData.linkMeet}
onChange={(event) => setData({ ...isData, linkMeet: event.target.value })} onChange={(event) => setData({ ...isData, linkMeet: event.target.value })}
onBlur={() => setTouched({ ...touched, linkMeet: true })}
error={
touched.linkMeet && (
isData.linkMeet == "" ? "Link Meet Tidak Boleh Kosong" : null
)
}
/> />
<Select <Select
required required
@@ -312,7 +305,6 @@ export default function NavbarCreateDivisionCalender() {
isData.dateStart !== " " && isData.dateStart !== " " &&
isData.timeStart !== "" && isData.timeStart !== "" &&
isData.timeEnd !== "" && isData.timeEnd !== "" &&
isData.linkMeet !== "" &&
isData.repeatEventTyper !== "" isData.repeatEventTyper !== ""
) { ) {
setModal(true); setModal(true);

View File

@@ -5,12 +5,14 @@ import React, { useState } from 'react';
import { HiMenu } from 'react-icons/hi'; import { HiMenu } from 'react-icons/hi';
import DawerDivisionCalender from './dawer_division_calender'; import DawerDivisionCalender from './dawer_division_calender';
import DateEventDivision from './date_event_division'; import DateEventDivision from './date_event_division';
import { useParams } from 'next/navigation';
export default function NavbarDivisionCalender() { export default function NavbarDivisionCalender() {
const [openDrawer, setOpenDrawer] = useState(false) const [openDrawer, setOpenDrawer] = useState(false)
const param = useParams<{ id: string }>()
return ( return (
<div> <div>
<LayoutNavbarNew back="" title="Divisi - kalender" <LayoutNavbarNew back={`/division/${param.id}`} title="Divisi - kalender"
menu={ menu={
<ActionIcon variant="light" onClick={() => setOpenDrawer(true)} bg={WARNA.bgIcon} size="lg" radius="lg" aria-label="Settings"> <ActionIcon variant="light" onClick={() => setOpenDrawer(true)} bg={WARNA.bgIcon} size="lg" radius="lg" aria-label="Settings">
<HiMenu size={20} color='white' /> <HiMenu size={20} color='white' />

View File

@@ -0,0 +1,40 @@
import { Box, Group, Skeleton, Stack } from '@mantine/core';
import React from 'react';
export default function SkeletonDetailEvent() {
return (
<Box style={{
border: `1px solid ${"#D8D8F1"}`,
padding: 20,
borderRadius: 10
}}>
<Stack ml={10}>
<Group mb={10} gap={30}>
<Skeleton height={30} width={30} radius="md" />
<Skeleton height={20} width={"60%"} radius="md" />
</Group>
<Group mb={10} gap={30}>
<Skeleton height={30} width={30} radius="md" />
<Skeleton height={20} width={"60%"} radius="md" />
</Group>
<Group mb={10} gap={30}>
<Skeleton height={30} width={30} radius="md" />
<Skeleton height={20} width={"60%"} radius="md" />
</Group>
<Group mb={10} gap={30}>
<Skeleton height={30} width={30} radius="md" />
<Skeleton height={20} width={"60%"} radius="md" />
</Group>
<Group mb={10} gap={30}>
<Skeleton height={30} width={30} radius="md" />
<Skeleton height={20} width={"60%"} radius="md" />
</Group>
<Group gap={30}>
<Skeleton height={30} width={30} radius="md" />
<Skeleton height={20} width={"60%"} radius="md" />
</Group>
</Stack>
</Box>
);
}

View File

@@ -23,6 +23,14 @@ export default function UpdateDivisionCalender() {
const memberValue = memberUser.get() as IFormMemberCalender[] const memberValue = memberUser.get() as IFormMemberCalender[]
const [isDataCalender, setDataCalender] = useState<IDetailByIdCalender>() const [isDataCalender, setDataCalender] = useState<IDetailByIdCalender>()
const [openMember, setOpenMember] = useState(false) const [openMember, setOpenMember] = useState(false)
const [touched, setTouched] = useState({
title: false,
dateStart: false,
timeStart: false,
timeEnd: false,
repeatEventTyper: false,
desc: false
})
const fetchGetOne = async () => { const fetchGetOne = async () => {
try { try {
@@ -40,7 +48,6 @@ export default function UpdateDivisionCalender() {
const [value, setValue] = useState<Date | null>(null); const [value, setValue] = useState<Date | null>(null);
const router = useRouter() const router = useRouter()
async function onSubmit(val: boolean) { async function onSubmit(val: boolean) {
try { try {
if (val) { if (val) {
@@ -77,7 +84,7 @@ export default function UpdateDivisionCalender() {
return ( return (
<Box> <Box>
<LayoutNavbarNew back={`/division/${param.id}/calender`} title="Edit kalender" menu /> <LayoutNavbarNew back={`/division/${param.id}/calender/${param.detail}`} title="Edit kalender" menu />
<Box p={20}> <Box p={20}>
<Stack> <Stack>
<TextInput <TextInput
@@ -99,6 +106,9 @@ export default function UpdateDivisionCalender() {
}) })
} }
} }
onBlur={() => setTouched({ ...touched, title: true })}
required
error={touched.title && !isDataCalender?.title ? "Nama Acara Tidak Boleh Kosong" : null}
/> />
<DateInput <DateInput
styles={{ styles={{
@@ -122,6 +132,10 @@ export default function UpdateDivisionCalender() {
} }
placeholder="Input Tanggal" placeholder="Input Tanggal"
label="Tanggal" label="Tanggal"
minDate={new Date()}
onBlur={() => setTouched({ ...touched, dateStart: true })}
error={touched.dateStart && !isDataCalender?.dateStart ? "Tanggal Tidak Boleh Kosong" : null}
required
/> />
<SimpleGrid <SimpleGrid
cols={{ base: 2, sm: 2, lg: 2 }} cols={{ base: 2, sm: 2, lg: 2 }}
@@ -145,6 +159,9 @@ export default function UpdateDivisionCalender() {
}) })
} }
} }
onBlur={() => setTouched({ ...touched, timeStart: true })}
error={touched.timeStart && !isDataCalender?.timeStart ? "Waktu Awal Tidak Boleh Kosong" : null}
required
/> />
<TimeInput <TimeInput
styles={{ styles={{
@@ -165,6 +182,14 @@ export default function UpdateDivisionCalender() {
}) })
} }
} }
onBlur={() => setTouched({ ...touched, timeEnd: true })}
required
error={
touched.timeEnd && (
isDataCalender?.timeEnd == "" ? "Waktu Akhir Tidak Boleh Kosong" : null
) ||
(String(isDataCalender?.timeStart) > String(isDataCalender?.timeEnd) ? "Waktu Akhir Tidak Tepat" : null)
}
/> />
</SimpleGrid> </SimpleGrid>
<TextInput <TextInput
@@ -215,20 +240,14 @@ export default function UpdateDivisionCalender() {
}) })
} }
} }
onBlur={() => setTouched({ ...touched, repeatEventTyper: true })}
error={
touched.repeatEventTyper && (
isDataCalender?.repeatEventTyper == "" ? "Ulangi Event Tidak Boleh Kosong" : null
)
}
required
/> />
<Box mt={5} onClick={() => setOpenMember(true)}>
<Group
justify="space-between"
p={10}
style={{
border: `1px solid ${"#D6D8F6"}`,
borderRadius: 10,
}}
>
<Text>Tambah Anggota</Text>
<IoIosArrowDropright size={25} />
</Group>
</Box>
<Textarea styles={{ <Textarea styles={{
input: { input: {
border: `1px solid ${"#D6D8F6"}`, border: `1px solid ${"#D6D8F6"}`,
@@ -247,6 +266,19 @@ export default function UpdateDivisionCalender() {
} }
} }
/> />
<Box mt={5} onClick={() => setOpenMember(true)}>
<Group
justify="space-between"
p={10}
style={{
border: `1px solid ${"#D6D8F6"}`,
borderRadius: 10,
}}
>
<Text>Tambah Anggota *</Text>
<IoIosArrowDropright size={25} />
</Group>
</Box>
<Box pt={30}> <Box pt={30}>
<Group justify="space-between"> <Group justify="space-between">
<Text c={WARNA.biruTua}>Anggota Terpilih</Text> <Text c={WARNA.biruTua}>Anggota Terpilih</Text>

View File

@@ -11,6 +11,9 @@ export default function FormCreateDiscussion({ id }: { id: string }) {
const [isValModal, setValModal] = useState(false) const [isValModal, setValModal] = useState(false)
const router = useRouter() const router = useRouter()
const param = useParams<{ id: string }>() const param = useParams<{ id: string }>()
const [touched, setTouched] = useState({
desc: false,
});
const [isData, setData] = useState({ const [isData, setData] = useState({
desc: "", desc: "",
idDivision: id idDivision: id
@@ -26,8 +29,9 @@ export default function FormCreateDiscussion({ id }: { id: string }) {
if (response.success) { if (response.success) {
toast.success(response.message) toast.success(response.message)
router.push(`/division/${response.data.id}/discussion/`) router.push(`/division/${param.id}/discussion/`)
setValModal(false) setValModal(false)
router.back()
} else { } else {
toast.error(response.message) toast.error(response.message)
} }
@@ -62,6 +66,12 @@ export default function FormCreateDiscussion({ id }: { id: string }) {
}} }}
value={isData.desc} value={isData.desc}
onChange={(e) => setData({ ...isData, desc: e.target.value })} onChange={(e) => setData({ ...isData, desc: e.target.value })}
onBlur={() => setTouched({ ...touched, desc: true })}
error={
touched.desc && (
isData.desc == "" ? "Form Tidak Boleh Kosong" : null
)
}
/> />
</Box> </Box>
</Grid.Col> </Grid.Col>
@@ -73,7 +83,15 @@ export default function FormCreateDiscussion({ id }: { id: string }) {
size="lg" size="lg"
radius={30} radius={30}
fullWidth fullWidth
onClick={() => setValModal(true)} onClick={() => {
if (
isData.desc !== ""
) {
setValModal(true)
} else {
toast.error("Form Tidak Boleh Kosong");
}
}}
> >
Simpan Simpan
</Button> </Button>

View File

@@ -13,6 +13,9 @@ export default function FormEditDiscussion() {
const router = useRouter() const router = useRouter()
const param = useParams<{ id: string, detail: string }>() const param = useParams<{ id: string, detail: string }>()
const [isDataOne, setDataOne] = useState("") const [isDataOne, setDataOne] = useState("")
const [touched, setTouched] = useState({
desc: false,
});
async function fetchGetOneDiscussion() { async function fetchGetOneDiscussion() {
try { try {
@@ -53,7 +56,7 @@ export default function FormEditDiscussion() {
}, []) }, [])
return ( return (
<Box> <Box pos={"relative"} h={"89vh"}>
<Box p={20}> <Box p={20}>
<Grid gutter={0} pt={10}> <Grid gutter={0} pt={10}>
<Grid.Col span={"auto"}> <Grid.Col span={"auto"}>
@@ -67,23 +70,37 @@ export default function FormEditDiscussion() {
input: { input: {
border: 'none', border: 'none',
backgroundColor: 'transparent', backgroundColor: 'transparent',
height: "50vh" height: "60vh"
} }
}} }}
value={isDataOne} value={isDataOne}
onChange={(e) => setDataOne(e.target.value)} onChange={(e) => setDataOne(e.target.value)}
onBlur={() => setTouched({ ...touched, desc: true })}
error={
touched.desc && (
isDataOne == "" ? "Form Tidak Boleh Kosong" : null
)
}
/> />
</Box> </Box>
</Grid.Col> </Grid.Col>
</Grid> </Grid>
<Box mt="xl"> <Box pos={"absolute"} bottom={10} left={0} right={0} p={20}>
<Button <Button
color="white" color="white"
bg={WARNA.biruTua} bg={WARNA.biruTua}
size="lg" size="lg"
radius={30} radius={30}
fullWidth fullWidth
onClick={() => setValModal(true)} onClick={() => {
if (
isDataOne !== ""
) {
setValModal(true)
} else {
toast.error("Form Tidak Boleh Kosong");
}
}}
> >
Simpan Simpan
</Button> </Button>

View File

@@ -8,6 +8,8 @@ import { HiMagnifyingGlass } from "react-icons/hi2";
import { funGetAllDiscussion } from "../lib/api_discussion"; import { funGetAllDiscussion } from "../lib/api_discussion";
import { useShallowEffect } from "@mantine/hooks"; import { useShallowEffect } from "@mantine/hooks";
import { IDataDiscussion } from "../lib/type_discussion"; import { IDataDiscussion } from "../lib/type_discussion";
import toast from "react-hot-toast";
import _ from "lodash";
export default function ListDiscussion({ id }: { id: string }) { export default function ListDiscussion({ id }: { id: string }) {
const [isData, setData] = useState<IDataDiscussion[]>([]) const [isData, setData] = useState<IDataDiscussion[]>([])
@@ -19,7 +21,13 @@ export default function ListDiscussion({ id }: { id: string }) {
try { try {
setLoading(true) setLoading(true)
const response = await funGetAllDiscussion('?division=' + id + '&search=' + searchQuery) const response = await funGetAllDiscussion('?division=' + id + '&search=' + searchQuery)
if (
response.success
) {
setData(response.data) setData(response.data)
} else {
toast.error(response.message)
}
setLoading(false) setLoading(false)
} catch (error) { } catch (error) {
console.log(error) console.log(error)
@@ -84,6 +92,12 @@ export default function ListDiscussion({ id }: { id: string }) {
</Box> </Box>
)) ))
: :
_.isEmpty(isData)
?
<Box style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '50vh' }}>
<Text c="dimmed" ta={"center"} fs={"italic"}>Tidak ada Diskusi</Text>
</Box>
:
isData.map((v, i) => { isData.map((v, i) => {
return ( return (
<Box key={i} pl={10} pr={10}> <Box key={i} pl={10} pr={10}>

View File

@@ -36,6 +36,10 @@ export default function CreateDivision() {
name: "", name: "",
desc: "", desc: "",
}); });
const [touched, setTouched] = useState({
idGroup: false,
name: false,
});
async function loadData() { async function loadData() {
const loadGroup = await funGetAllGroup('?active=true') const loadGroup = await funGetAllGroup('?active=true')
@@ -124,7 +128,12 @@ export default function CreateDivision() {
onChange={(val) => { onChange={(val) => {
onChooseGroup(val) onChooseGroup(val)
}} }}
onBlur={() => setTouched({ ...touched, idGroup: true })}
error={
touched.idGroup && (
body.idGroup == "" ? "Grup Tidak Boleh Kosong" : null
)
}
value={body.idGroup} value={body.idGroup}
/> />
) )
@@ -137,6 +146,12 @@ export default function CreateDivision() {
radius={40} radius={40}
value={body.name} value={body.name}
onChange={(val) => { setBody({ ...body, name: val.target.value }) }} onChange={(val) => { setBody({ ...body, name: val.target.value }) }}
onBlur={() => setTouched({ ...touched, name: true })}
error={
touched.name && (
body.name == "" ? "Nama Tidak Boleh Kosong" : null
)
}
/> />
<Textarea size="md" placeholder="Deskripsi" label="Deskripsi" value={body.desc} radius={10} onChange={(val) => { setBody({ ...body, desc: val.currentTarget.value }) }} /> <Textarea size="md" placeholder="Deskripsi" label="Deskripsi" value={body.desc} radius={10} onChange={(val) => { setBody({ ...body, desc: val.currentTarget.value }) }} />
<Box onClick={() => { onToChooseAnggota() }}> <Box onClick={() => { onToChooseAnggota() }}>

View File

@@ -22,12 +22,9 @@ export default function EditDivision() {
desc: "", desc: "",
}); });
function onTrue(val: boolean) { const [touched, setTouched] = useState({
if (val) { name: false,
toast.success("Sukses! Data tersimpan"); });
}
setOpenModal(false)
}
async function getOneData() { async function getOneData() {
@@ -88,7 +85,16 @@ export default function EditDivision() {
required required
radius={40} radius={40}
value={body.name} value={body.name}
onChange={(e) => { setBody({ ...body, name: e.target.value }) }} onChange={(e) => {
setBody({ ...body, name: e.target.value })
setTouched({ ...touched, name: false })
}}
onBlur={() => setTouched({ ...touched, name: true })}
error={
touched.name && (
body.name == "" ? "Judul Tidak Boleh Kosong" : null
)
}
/> />
<Textarea placeholder="Deskripsi" label="Deskripsi" size="md" radius={10} <Textarea placeholder="Deskripsi" label="Deskripsi" size="md" radius={10}
value={body.desc} value={body.desc}
@@ -107,7 +113,15 @@ export default function EditDivision() {
size="lg" size="lg"
radius={30} radius={30}
fullWidth fullWidth
onClick={() => { setOpenModal(true) }} onClick={() => {
if (
body.name !== ""
) {
setOpenModal(true)
} else {
toast.error("Judul Tidak Boleh Kosong")
}
}}
> >
Simpan Simpan
</Button> </Button>

View File

@@ -7,12 +7,14 @@ import EchartPaiReport from './echart_pai_report';
import EchartBarReport from './echart_bar_report'; import EchartBarReport from './echart_bar_report';
import EventReport from './event_report'; import EventReport from './event_report';
import DiscussionReport from './discussion_report'; import DiscussionReport from './discussion_report';
import { useParams } from 'next/navigation';
export default function ReportDivisionId() { export default function ReportDivisionId() {
const [value, setValue] = useState<Date | null>(null); const [value, setValue] = useState<Date | null>(null);
const param = useParams<{ id: string }>()
return ( return (
<Box> <Box>
<LayoutNavbarNew back="/division/1" title="Report Divisi" menu /> <LayoutNavbarNew back={`/division/${param.id}`} title="Report Divisi" menu />
<Box p={20}> <Box p={20}>
<Stack> <Stack>
<DateInput <DateInput

View File

@@ -18,6 +18,9 @@ import toast from "react-hot-toast";
export default function DrawerGroup({ onSuccess, }: { onSuccess: (val: boolean) => void; }) { export default function DrawerGroup({ onSuccess, }: { onSuccess: (val: boolean) => void; }) {
const [openDrawerGroup, setOpenDrawerGroup] = useState(false); const [openDrawerGroup, setOpenDrawerGroup] = useState(false);
const [namaGroup, setNamaGroup] = useState(""); const [namaGroup, setNamaGroup] = useState("");
const [touched, setTouched] = useState({
name: false,
});
async function createData() { async function createData() {
@@ -50,7 +53,7 @@ export default function DrawerGroup({ onSuccess, }: { onSuccess: (val: boolean)
<IoAddCircle size={30} color={WARNA.biruTua} /> <IoAddCircle size={30} color={WARNA.biruTua} />
</Box> </Box>
<Box> <Box>
<Text c={WARNA.biruTua}>Tambah Group</Text> <Text c={WARNA.biruTua}>Tambah Grup</Text>
</Box> </Box>
</Flex> </Flex>
</SimpleGrid> </SimpleGrid>
@@ -71,8 +74,15 @@ export default function DrawerGroup({ onSuccess, }: { onSuccess: (val: boolean)
}} }}
size="lg" size="lg"
radius={10} radius={10}
label="Grup"
required
placeholder="Grup" placeholder="Grup"
onChange={(e) => setNamaGroup(e.target.value)} onChange={(e) => {
setNamaGroup(e.target.value)
setTouched({ ...touched, name: false })
}}
error={touched.name ? "Error! harus memasukkan grup" : ""}
onBlur={() => setTouched({ ...touched, name: true })}
/> />
<Box mt={"xl"}> <Box mt={"xl"}>
<Button <Button

View File

@@ -24,6 +24,9 @@ export default function EditDrawerGroup({ onUpdated, id, isActive, }: { onUpdate
const [isModal, setModal] = useState(false); const [isModal, setModal] = useState(false);
const [name, setName] = useState(""); const [name, setName] = useState("");
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [touched, setTouched] = useState({
name: false,
});
async function getOneGroup() { async function getOneGroup() {
try { try {
@@ -135,9 +138,18 @@ export default function EditDrawerGroup({ onUpdated, id, isActive, }: { onUpdate
}} }}
size="lg" size="lg"
value={name} value={name}
onChange={(e) => setName(e.target.value)} onChange={(e) => {
setName(e.target.value)
setTouched({ ...touched, name: false })
}}
onBlur={() => setTouched({ ...touched, name: true })}
error={touched.name ? "Error! harus memasukkan grup" : ""}
radius={10} radius={10}
placeholder="Grup" placeholder="Grup"
label="Grup"
required
/> />
<Box mt={"xl"}> <Box mt={"xl"}>
<Button <Button

View File

@@ -20,6 +20,10 @@ export default function DrawerDetailPosition({ onUpdated, id, isActive }: {
idGroup: "" idGroup: ""
}) })
const [listGroup, setListGorup] = useState<IDataPosition[]>([]) const [listGroup, setListGorup] = useState<IDataPosition[]>([])
const [touched, setTouched] = useState({
name: false,
idGroup: false
});
function onCLose() { function onCLose() {
onUpdated(true) onUpdated(true)
@@ -153,7 +157,10 @@ export default function DrawerDetailPosition({ onUpdated, id, isActive }: {
} }
value={String(data.idGroup)} value={String(data.idGroup)}
mb={5} mb={5}
onChange={(val) => setData({ ...data, idGroup: val })} onChange={(val) => {
setData({ ...data, idGroup: val })
setTouched({ ...touched, idGroup: false })
}}
withAsterisk withAsterisk
styles={{ styles={{
input: { input: {
@@ -162,6 +169,12 @@ export default function DrawerDetailPosition({ onUpdated, id, isActive }: {
borderColor: WARNA.biruTua, borderColor: WARNA.biruTua,
}, },
}} }}
error={
touched.idGroup && (
data.idGroup == "" ? "Grup Tidak Boleh Kosong" : null
)
}
onBlur={() => setTouched({ ...touched, idGroup: true })}
/> />
<TextInput <TextInput
label="Jabatan" label="Jabatan"
@@ -172,10 +185,20 @@ export default function DrawerDetailPosition({ onUpdated, id, isActive }: {
borderColor: WARNA.biruTua, borderColor: WARNA.biruTua,
}, },
}} }}
required
my={15} my={15}
size="md" size="md"
value={String(data.name)} value={String(data.name)}
onChange={(e) => setData({ ...data, name: e.target.value })} onChange={(e) => {
setData({ ...data, name: e.target.value })
setTouched({ ...touched, name: false })
}}
onBlur={() => setTouched({ ...touched, name: true })}
error={
touched.name && (
data.name == "" ? "Nama Jabatan Tidak Boleh Kosong" : null
)
}
radius={10} radius={10}
placeholder="Nama Jabatan" placeholder="Nama Jabatan"
/> />

View File

@@ -14,6 +14,10 @@ export default function DrawerListPosition({ onCreated }: { onCreated: (val: boo
const [openDrawerGroup, setOpenDrawerGroup] = useState(false) const [openDrawerGroup, setOpenDrawerGroup] = useState(false)
const router = useRouter() const router = useRouter()
const [listGroup, setListGorup] = useState<IDataGroup[]>([]) const [listGroup, setListGorup] = useState<IDataGroup[]>([])
const [touched, setTouched] = useState({
name: false,
idGroup: false
});
const [listData, setListData] = useState({ const [listData, setListData] = useState({
name: "", name: "",
@@ -101,10 +105,13 @@ export default function DrawerListPosition({ onCreated }: { onCreated: (val: boo
radius={10} radius={10}
mb={5} mb={5}
withAsterisk withAsterisk
onChange={(val: any) => setListData({ onChange={(val: any) => {
setListData({
...listData, ...listData,
idGroup: val idGroup: val
})} })
setTouched({ ...touched, idGroup: false })
}}
styles={{ styles={{
input: { input: {
color: WARNA.biruTua, color: WARNA.biruTua,
@@ -112,6 +119,13 @@ export default function DrawerListPosition({ onCreated }: { onCreated: (val: boo
borderColor: WARNA.biruTua, borderColor: WARNA.biruTua,
}, },
}} }}
error={
touched.idGroup && (
listData.idGroup == "" ? "Grup Tidak Boleh Kosong" : null
)
}
onFocus={() => setTouched({ ...touched, idGroup: true })}
onBlur={() => setTouched({ ...touched, idGroup: true })}
/> />
<TextInput <TextInput
label="Jabatan" label="Jabatan"
@@ -124,12 +138,23 @@ export default function DrawerListPosition({ onCreated }: { onCreated: (val: boo
}} }}
my={15} my={15}
size="md" size="md"
onChange={(event: any) => setListData({ onChange={(event: any) => {
setListData({
...listData, ...listData,
name: event.target.value name: event.target.value
})} })
setTouched({ ...touched, name: false })
}}
radius={10} radius={10}
placeholder="Nama Jabatan" placeholder="Nama Jabatan"
error={
touched.name && (
listData.name == "" ? "Nama Jabatan Tidak Boleh Kosong" : null
)
}
onFocus={() => setTouched({ ...touched, name: true })}
onBlur={() => setTouched({ ...touched, name: true })}
required
/> />
<Box mt={'xl'}> <Box mt={'xl'}>
<Button <Button

View File

@@ -43,7 +43,11 @@ export default function CreateProject() {
const [body, setBody] = useState<any>({ const [body, setBody] = useState<any>({
idGroup: "", idGroup: "",
title: "", title: "",
desc: "", });
const [touched, setTouched] = useState({
title: false,
idGroup: false,
desc: false
}); });
function deleteFile(index: number) { function deleteFile(index: number) {
@@ -138,9 +142,16 @@ export default function CreateProject() {
}))} }))}
onChange={(val) => { onChange={(val) => {
onChooseGroup(val) onChooseGroup(val)
setTouched({ ...touched, idGroup: false })
}} }}
value={(body.idGroup=="")?null:body.idGroup} value={(body.idGroup == "") ? null : body.idGroup}
onBlur={() => setTouched({ ...touched, idGroup: true })}
error={
touched.idGroup && (
body.idGroup == "" ? "Grup Tidak Boleh Kosong" : null
)
}
/> />
) )
} }
@@ -157,6 +168,12 @@ export default function CreateProject() {
size="md" size="md"
value={body.title} value={body.title}
onChange={(e) => setBody({ ...body, title: e.target.value })} onChange={(e) => setBody({ ...body, title: e.target.value })}
onBlur={() => setTouched({ ...touched, title: true })}
error={
touched.title && (
body.title == "" ? "Proyek Tidak Boleh Kosong" : null
)
}
/> />
<Box onClick={() => { setOpenTugas(true) }}> <Box onClick={() => { setOpenTugas(true) }}>
<Group <Group

View File

@@ -10,6 +10,7 @@ import {
SimpleGrid, SimpleGrid,
Stack, Stack,
Text, Text,
TextInput,
} from "@mantine/core"; } from "@mantine/core";
import React, { useState } from "react"; import React, { useState } from "react";
import { DatePicker } from "@mantine/dates"; import { DatePicker } from "@mantine/dates";
@@ -27,6 +28,9 @@ export default function AddDetailTask() {
const [title, setTitle] = useState("") const [title, setTitle] = useState("")
const [openModal, setOpenModal] = useState(false) const [openModal, setOpenModal] = useState(false)
const param = useParams<{ id: string, detail: string }>() const param = useParams<{ id: string, detail: string }>()
const [touched, setTouched] = useState({
title: false,
});
function onVerification() { function onVerification() {
if (value[0] == null || value[1] == null) if (value[0] == null || value[1] == null)
@@ -106,17 +110,25 @@ export default function AddDetailTask() {
</Box> </Box>
</SimpleGrid> </SimpleGrid>
<Stack pt={15}> <Stack pt={15}>
<Input <TextInput
styles={{ styles={{
input: { input: {
border: `1px solid ${"#D6D8F6"}`, border: `1px solid ${"#D6D8F6"}`,
borderRadius: 10, borderRadius: 10,
}, },
}} }}
label="Tahapan"
placeholder="Input Nama Tahapan" placeholder="Input Nama Tahapan"
size="md" size="md"
required
value={title} value={title}
onChange={(e) => setTitle(e.target.value)} onChange={(e) => {
setTitle(e.target.value)
setTouched({ ...touched, title: false })
}
}
onBlur={() => setTouched({ ...touched, title: true })}
error={touched.title ? "Tahapan wajib diisi" : undefined}
/> />
</Stack> </Stack>
<Box mt={"xl"}> <Box mt={"xl"}>

View File

@@ -121,26 +121,13 @@ export default function AddMemberDetailTask() {
menu menu
/> />
<Box p={20}> <Box p={20}>
{/* <TextInput
styles={{
input: {
color: WARNA.biruTua,
borderRadius: WARNA.biruTua,
borderColor: WARNA.biruTua,
},
}}
size="md"
radius={30}
leftSection={<HiMagnifyingGlass size={20} />}
placeholder="Pencarian"
/> */}
<Group justify="space-between" mt={20} onClick={handleSelectAll}> <Group justify="space-between" mt={20} onClick={handleSelectAll}>
<Text c={WARNA.biruTua} fw={"bold"}> <Text c={WARNA.biruTua} fw={"bold"}>
Pilih Semua Anggota Pilih Semua Anggota
</Text> </Text>
{selectAll ? <FaCheck style={{ marginRight: 10 }} /> : ""} {selectAll ? <FaCheck style={{ marginRight: 10 }} /> : ""}
</Group> </Group>
{/* <Box mt={15}> <Box mt={15}>
{isData.map((v, i) => { {isData.map((v, i) => {
const isSelected = selectedFiles.some((i: any) => i?.idUser == v.idUser); const isSelected = selectedFiles.some((i: any) => i?.idUser == v.idUser);
const found = isDataMember.some((i: any) => i.idUser == v.idUser) const found = isDataMember.some((i: any) => i.idUser == v.idUser)
@@ -175,7 +162,7 @@ export default function AddMemberDetailTask() {
</Box> </Box>
); );
})} })}
</Box> */} </Box>
<Box mt={"xl"}> <Box mt={"xl"}>
<Button <Button
c={"white"} c={"white"}

View File

@@ -18,6 +18,9 @@ export default function CancelTask() {
const [alasan, setAlasan] = useState("") const [alasan, setAlasan] = useState("")
const [openModal, setOpenModal] = useState(false) const [openModal, setOpenModal] = useState(false)
const param = useParams<{ id: string, detail: string }>() const param = useParams<{ id: string, detail: string }>()
const [touched, setTouched] = useState({
reason: false,
});
function onVerification() { function onVerification() {
if (alasan == "") if (alasan == "")
@@ -44,7 +47,7 @@ export default function CancelTask() {
return ( return (
<Box> <Box pos={"relative"} h={"100vh"}>
<LayoutNavbarNew back="" title={"Pembatalan Tugas"} menu /> <LayoutNavbarNew back="" title={"Pembatalan Tugas"} menu />
<Box p={20}> <Box p={20}>
<Stack pt={15}> <Stack pt={15}>
@@ -56,10 +59,15 @@ export default function CancelTask() {
}} }}
value={alasan} value={alasan}
size="md" placeholder='Contoh : Tugas tidak sesuai' label="Alasan Pembatalan" size="md" placeholder='Contoh : Tugas tidak sesuai' label="Alasan Pembatalan"
onChange={(event) => setAlasan(event.target.value)} onChange={(event) => {
setAlasan(event.target.value)
setTouched({ ...touched, reason: false })
}}
error={touched.reason ? "Error! harus memasukkan alasan pembatalan tugas" : ""}
onBlur={() => setTouched({ ...touched, reason: true })}
/> />
</Stack> </Stack>
<Box mt={"xl"}> <Box pos={"absolute"} bottom={10} left={0} right={0} p={20}>
<Button <Button
c={"white"} c={"white"}
bg={WARNA.biruTua} bg={WARNA.biruTua}

View File

@@ -10,10 +10,11 @@ import {
SimpleGrid, SimpleGrid,
Stack, Stack,
Text, Text,
TextInput,
} from "@mantine/core"; } from "@mantine/core";
import React, { useState } from "react"; import React, { useState } from "react";
import { DatePicker } from "@mantine/dates"; import { DatePicker } from "@mantine/dates";
import { useRouter } from "next/navigation"; import { useParams, useRouter } from "next/navigation";
import toast from "react-hot-toast"; import toast from "react-hot-toast";
import { IFormDateTask } from "../lib/type_task"; import { IFormDateTask } from "../lib/type_task";
import moment from "moment"; import moment from "moment";
@@ -22,7 +23,11 @@ import moment from "moment";
export default function ViewDateEndTask({ onClose }: { onClose: (val: IFormDateTask) => void }) { export default function ViewDateEndTask({ onClose }: { onClose: (val: IFormDateTask) => void }) {
const [value, setValue] = useState<[Date | null, Date | null]>([null, null]); const [value, setValue] = useState<[Date | null, Date | null]>([null, null]);
const router = useRouter() const router = useRouter()
const param = useParams<{ id: string }>()
const [title, setTitle] = useState("") const [title, setTitle] = useState("")
const [touched, setTouched] = useState({
title: false,
});
function onSubmit() { function onSubmit() {
if (value[0] == null || value[1] == null) if (value[0] == null || value[1] == null)
@@ -43,7 +48,7 @@ export default function ViewDateEndTask({ onClose }: { onClose: (val: IFormDateT
return ( return (
<Box> <Box>
<LayoutNavbarNew back="" title={"Tanggal Tugas"} menu /> <LayoutNavbarNew back={`/division/${param.id}/task/create`} title={"Tanggal Tugas"} menu />
<Box p={20}> <Box p={20}>
<Group <Group
justify="center" justify="center"
@@ -85,7 +90,7 @@ export default function ViewDateEndTask({ onClose }: { onClose: (val: IFormDateT
</Box> </Box>
</SimpleGrid> </SimpleGrid>
<Stack pt={15}> <Stack pt={15}>
<Input <TextInput
styles={{ styles={{
input: { input: {
border: `1px solid ${"#D6D8F6"}`, border: `1px solid ${"#D6D8F6"}`,
@@ -93,9 +98,16 @@ export default function ViewDateEndTask({ onClose }: { onClose: (val: IFormDateT
}, },
}} }}
placeholder="Input Nama Tahapan" placeholder="Input Nama Tahapan"
label="Judul Tugas"
required
size="md" size="md"
value={title} value={title}
onChange={(e) => setTitle(e.target.value)} onChange={(e) => {
setTitle(e.target.value)
setTouched({ ...touched, title: false })
}}
onBlur={() => setTouched({ ...touched, title: true })}
error={touched.title && title == "" ? "Judul Tugas Tidak Boleh Kosong" : null}
/> />
</Stack> </Stack>
<Box mt={"xl"}> <Box mt={"xl"}>

View File

@@ -1,6 +1,6 @@
"use client"; "use client";
import { LayoutDrawer, LayoutNavbarNew, WARNA } from "@/module/_global"; import { LayoutDrawer, LayoutNavbarNew, WARNA } from "@/module/_global";
import { Avatar, Box, Button, Center, Flex, Group, Input, SimpleGrid, Stack, Text } from "@mantine/core"; import { Avatar, Box, Button, Center, Flex, Group, Input, SimpleGrid, Stack, Text, TextInput } from "@mantine/core";
import { useParams, useRouter } from "next/navigation"; import { useParams, useRouter } from "next/navigation";
import React, { useRef, useState } from "react"; import React, { useRef, useState } from "react";
import { IoIosArrowDropright } from "react-icons/io"; import { IoIosArrowDropright } from "react-icons/io";
@@ -37,6 +37,11 @@ export default function CreateTask() {
const [indexDelFile, setIndexDelFile] = useState<number>(0) const [indexDelFile, setIndexDelFile] = useState<number>(0)
const [indexDelTask, setIndexDelTask] = useState<number>(0) const [indexDelTask, setIndexDelTask] = useState<number>(0)
const [title, setTitle] = useState("") const [title, setTitle] = useState("")
const [touched, setTouched] = useState({
title: false,
task: false,
member: false
});
function deleteFile(index: number) { function deleteFile(index: number) {
setListFile([...listFile.filter((val, i) => i !== index)]) setListFile([...listFile.filter((val, i) => i !== index)])
@@ -52,7 +57,14 @@ export default function CreateTask() {
async function onSubmit() { async function onSubmit() {
try { try {
const response = await funCreateTask({ idDivision: param.id, title, task: dataTask, file: fileForm, member: memberValue }) const response = await funCreateTask(
{
idDivision: param.id,
title,
task: dataTask,
file: fileForm,
member: memberValue
})
if (response.success) { if (response.success) {
toast.success(response.message) toast.success(response.message)
@@ -81,20 +93,31 @@ export default function CreateTask() {
return ( return (
<Box> <Box>
<LayoutNavbarNew back="" title="tambah tugas" menu /> <LayoutNavbarNew back={`/division/${param.id}/task/`} title="tambah tugas" menu />
<Box p={20}> <Box p={20}>
<Stack> <Stack>
<Input <TextInput
styles={{ styles={{
input: { input: {
border: `1px solid ${"#D6D8F6"}`, border: `1px solid ${"#D6D8F6"}`,
borderRadius: 10, borderRadius: 10,
}, },
}} }}
placeholder="Nama Proyek" placeholder="Nama Tugas"
size="md" size="md"
label="Judul Tugas"
value={title} value={title}
onChange={(e) => setTitle(e.target.value)} onChange={(e) => {
setTitle(e.target.value)
setTouched({ ...touched, title: false })
}}
onBlur={() => setTouched({ ...touched, title: true })}
required
error={
touched.title && (
title == "" ? "Nama Tidak Boleh Kosong" : null
)
}
/> />
<Box onClick={() => { setOpenTugas(true) }}> <Box onClick={() => { setOpenTugas(true) }}>
<Group <Group
@@ -227,7 +250,20 @@ export default function CreateTask() {
<Box mt="xl"> <Box mt="xl">
<Button color="white" bg={WARNA.biruTua} size="lg" radius={30} fullWidth onClick={() => setOpenModal(true)}> <Button
color="white"
bg={WARNA.biruTua}
size="lg" radius={30}
fullWidth
onClick={() => {
if (
title !== ""
) {
setOpenModal(true)
} else {
toast.error("Semua form harus diisi")
}
}}>
Simpan Simpan
</Button> </Button>
</Box> </Box>

View File

@@ -6,6 +6,7 @@ import {
Input, Input,
Stack, Stack,
Textarea, Textarea,
TextInput,
} from "@mantine/core"; } from "@mantine/core";
import React, { useState } from "react"; import React, { useState } from "react";
import { useParams, useRouter } from "next/navigation"; import { useParams, useRouter } from "next/navigation";
@@ -20,6 +21,9 @@ export default function EditTask() {
const [title, setTitle] = useState("") const [title, setTitle] = useState("")
const [openModal, setOpenModal] = useState(false) const [openModal, setOpenModal] = useState(false)
const param = useParams<{ id: string, detail: string }>() const param = useParams<{ id: string, detail: string }>()
const [touched, setTouched] = useState({
title: false,
});
function onVerification() { function onVerification() {
if (title == "") if (title == "")
@@ -65,11 +69,11 @@ export default function EditTask() {
return ( return (
<Box> <Box pos={"relative"} h={"100vh"}>
<LayoutNavbarNew back="" title={"Edit Judul Tugas"} menu /> <LayoutNavbarNew back="" title={"Edit Judul Tugas"} menu />
<Box p={20}> <Box p={20}>
<Stack pt={15}> <Stack pt={15}>
<Input <TextInput
styles={{ styles={{
input: { input: {
border: `1px solid ${"#D6D8F6"}`, border: `1px solid ${"#D6D8F6"}`,
@@ -77,12 +81,22 @@ export default function EditTask() {
}, },
}} }}
placeholder="Tugas" placeholder="Tugas"
label="Judul Tugas"
size="md" size="md"
value={title} value={title}
onChange={(e) => { setTitle(e.target.value) }} onChange={(e) => {
setTitle(e.target.value)
setTouched({ ...touched, title: false })
}}
error={
touched.title && (
title == "" ? "Error! harus memasukkan judul tugas" : null
)
}
onBlur={() => setTouched({ ...touched, title: true })}
/> />
</Stack> </Stack>
<Box mt={"xl"}> <Box pos={"absolute"} bottom={10} left={0} right={0} p={20}>
<Button <Button
c={"white"} c={"white"}
bg={WARNA.biruTua} bg={WARNA.biruTua}

View File

@@ -39,7 +39,7 @@ export default function NavbarDetailDivisionTask() {
return ( return (
<> <>
<LayoutNavbarNew back="" title={name} menu={ <LayoutNavbarNew back={`/division/${param.id}/task/`} title={name} menu={
<ActionIcon <ActionIcon
variant="light" variant="light"
bg={WARNA.bgIcon} bg={WARNA.bgIcon}

View File

@@ -165,6 +165,7 @@ export default function CreateMember() {
} }
onChange={(val: any) => { onChange={(val: any) => {
changeGrup(val); changeGrup(val);
setTouched({ ...touched, idGroup: false })
}} }}
onBlur={() => setTouched({ ...touched, idGroup: true })} onBlur={() => setTouched({ ...touched, idGroup: true })}
error={ error={
@@ -196,11 +197,13 @@ export default function CreateMember() {
})) }))
: [] : []
} }
onChange={(val: any) => onChange={(val: any) => {
setListData({ setListData({
...listData, ...listData,
idPosition: val, idPosition: val,
}) })
setTouched({ ...touched, idPosition: false })
}
} }
value={listData.idPosition == "" ? null : listData.idPosition} value={listData.idPosition == "" ? null : listData.idPosition}
onBlur={() => setTouched({ ...touched, idPosition: true })} onBlur={() => setTouched({ ...touched, idPosition: true })}
@@ -233,11 +236,13 @@ export default function CreateMember() {
})) }))
: [] : []
} }
onChange={(val: any) => onChange={(val: any) => {
setListData({ setListData({
...listData, ...listData,
idUserRole: val, idUserRole: val,
}) })
setTouched({ ...touched, idUserRole: false })
}
} }
onBlur={() => setTouched({ ...touched, idUserRole: true })} onBlur={() => setTouched({ ...touched, idUserRole: true })}
error={ error={
@@ -263,7 +268,7 @@ export default function CreateMember() {
}} }}
onChange={(event: any) => { onChange={(event: any) => {
setListData({ ...listData, nik: event.target.value }); setListData({ ...listData, nik: event.target.value });
setTouched({ ...touched, nik: true }); setTouched({ ...touched, nik: false });
}} }}
onBlur={() => setTouched({ ...touched, nik: true })} onBlur={() => setTouched({ ...touched, nik: true })}
error={ error={
@@ -288,11 +293,13 @@ export default function CreateMember() {
borderColor: WARNA.biruTua, borderColor: WARNA.biruTua,
}, },
}} }}
onChange={(event: any) => onChange={(event: any) => {
setListData({ setListData({
...listData, ...listData,
name: event.target.value, name: event.target.value,
}) })
setTouched({ ...touched, name: false })
}
} }
onBlur={() => setTouched({ ...touched, name: true })} onBlur={() => setTouched({ ...touched, name: true })}
error={ error={
@@ -316,11 +323,13 @@ export default function CreateMember() {
borderColor: WARNA.biruTua, borderColor: WARNA.biruTua,
}, },
}} }}
onChange={(event: any) => onChange={(event: any) => {
setListData({ setListData({
...listData, ...listData,
email: event.target.value, email: event.target.value,
}) })
setTouched({ ...touched, email: false })
}
} }
onBlur={() => setTouched({ ...touched, email: true })} onBlur={() => setTouched({ ...touched, email: true })}
error={ error={
@@ -345,11 +354,13 @@ export default function CreateMember() {
borderColor: WARNA.biruTua, borderColor: WARNA.biruTua,
}, },
}} }}
onChange={(event: any) => onChange={(event: any) => {
setListData({ setListData({
...listData, ...listData,
phone: event.target.value, phone: event.target.value,
}) })
setTouched({ ...touched, phone: false })
}
} }
onBlur={() => setTouched({ ...touched, phone: true })} onBlur={() => setTouched({ ...touched, phone: true })}
error={ error={
@@ -378,11 +389,13 @@ export default function CreateMember() {
{ value: "M", label: "Laki-laki" }, { value: "M", label: "Laki-laki" },
{ value: "F", label: "Perempuan" }, { value: "F", label: "Perempuan" },
]} ]}
onChange={(val: any) => onChange={(val: any) => {
setListData({ setListData({
...listData, ...listData,
gender: val, gender: val,
}) })
setTouched({ ...touched, gender: false })
}
} }
onBlur={() => setTouched({ ...touched, gender: true })} onBlur={() => setTouched({ ...touched, gender: true })}
error={ error={

View File

@@ -165,6 +165,7 @@ export default function EditMember({ id }: { id: string }) {
} }
onChange={(val: any) => { onChange={(val: any) => {
changeGrup(val) changeGrup(val)
setTouched({ ...touched, idGroup: false })
}} }}
value={data?.idGroup} value={data?.idGroup}
onBlur={() => setTouched({ ...touched, idGroup: true })} onBlur={() => setTouched({ ...touched, idGroup: true })}
@@ -191,7 +192,10 @@ export default function EditMember({ id }: { id: string }) {
})) }))
: [] : []
} }
onChange={(val: any) => setData({ ...data, idPosition: val })} onChange={(val: any) => {
setData({ ...data, idPosition: val })
setTouched({ ...touched, idPosition: false })
}}
value={(data?.idPosition == "") ? null : data.idPosition} value={(data?.idPosition == "") ? null : data.idPosition}
onBlur={() => setTouched({ ...touched, idPosition: true })} onBlur={() => setTouched({ ...touched, idPosition: true })}
error={ error={
@@ -217,7 +221,10 @@ export default function EditMember({ id }: { id: string }) {
})) }))
: [] : []
} }
onChange={(val: any) => setData({ ...data, idUserRole: val })} onChange={(val: any) => {
setData({ ...data, idUserRole: val })
setTouched({ ...touched, idUserRole: false })
}}
value={data?.idUserRole} value={data?.idUserRole}
onBlur={() => setTouched({ ...touched, idUserRole: true })} onBlur={() => setTouched({ ...touched, idUserRole: true })}
error={ error={
@@ -235,7 +242,10 @@ export default function EditMember({ id }: { id: string }) {
borderColor: WARNA.biruTua, borderColor: WARNA.biruTua,
}, },
}} }}
onChange={(e) => setData({ ...data, nik: e.target.value })} onChange={(e) => {
setData({ ...data, nik: e.target.value })
setTouched({ ...touched, nik: false })
}}
value={data.nik} value={data.nik}
onBlur={() => setTouched({ ...touched, nik: true })} onBlur={() => setTouched({ ...touched, nik: true })}
error={ error={
@@ -254,7 +264,10 @@ export default function EditMember({ id }: { id: string }) {
borderColor: WARNA.biruTua, borderColor: WARNA.biruTua,
}, },
}} }}
onChange={(e) => setData({ ...data, name: e.target.value })} onChange={(e) => {
setData({ ...data, name: e.target.value })
setTouched({ ...touched, name: false })
}}
value={data.name} value={data.name}
onBlur={() => setTouched({ ...touched, name: true })} onBlur={() => setTouched({ ...touched, name: true })}
error={ error={
@@ -272,7 +285,10 @@ export default function EditMember({ id }: { id: string }) {
borderColor: WARNA.biruTua, borderColor: WARNA.biruTua,
}, },
}} }}
onChange={(e) => setData({ ...data, email: e.target.value })} onChange={(e) => {
setData({ ...data, email: e.target.value })
setTouched({ ...touched, email: false })
}}
value={data.email} value={data.email}
onBlur={() => setTouched({ ...touched, email: true })} onBlur={() => setTouched({ ...touched, email: true })}
error={ error={
@@ -291,7 +307,10 @@ export default function EditMember({ id }: { id: string }) {
borderColor: WARNA.biruTua, borderColor: WARNA.biruTua,
}, },
}} }}
onChange={(e) => setData({ ...data, phone: e.target.value })} onChange={(e) => {
setData({ ...data, phone: e.target.value })
setTouched({ ...touched, phone: false })
}}
value={data.phone} value={data.phone}
onBlur={() => setTouched({ ...touched, phone: true })} onBlur={() => setTouched({ ...touched, phone: true })}
error={ error={
@@ -322,7 +341,10 @@ export default function EditMember({ id }: { id: string }) {
} }
] ]
} }
onChange={(val: any) => setData({ ...data, gender: val })} onChange={(val: any) => {
setData({ ...data, gender: val })
setTouched({ ...touched, gender: false })
}}
value={data.gender} value={data.gender}
onBlur={() => setTouched({ ...touched, gender: true })} onBlur={() => setTouched({ ...touched, gender: true })}
error={ error={