style : update skeleton

Deskripsi:
- update announcement
- update celender
- update division
- update task
- update project
- update user

No Issue
This commit is contained in:
lukman
2024-09-02 12:24:43 +08:00
parent b442e6e599
commit 2a8a3a1129
18 changed files with 1302 additions and 1012 deletions

View File

@@ -1,7 +1,7 @@
'use client'
import { LayoutNavbarNew, WARNA } from "@/module/_global";
import LayoutModal from "@/module/_global/layout/layout_modal";
import { Box, Button, Flex, List, rem, Stack, Text, Textarea, TextInput } from "@mantine/core";
import { Box, Button, Flex, List, rem, Skeleton, Stack, Text, Textarea, TextInput } from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks";
import { useState } from "react";
import toast from "react-hot-toast";
@@ -17,10 +17,11 @@ export default function EditAnnouncement() {
const [isOpen, setOpen] = useState(false)
const [isChooseDivisi, setChooseDivisi] = useState(false)
const param = useParams<{ id: string }>()
const [loading, setLoading] = useState(true)
const [touched, setTouched] = useState({
title: false,
desc: false
});
});
const [body, setBody] = useState({
title: "",
desc: "",
@@ -30,6 +31,7 @@ export default function EditAnnouncement() {
async function fetchOneAnnouncement() {
try {
setLoading(true)
memberGroup.set([])
const res = await funGetAnnouncementById(param.id)
if (res.success) {
@@ -62,9 +64,13 @@ export default function EditAnnouncement() {
toast.error(res.message)
}
setLoading(false)
} catch (error) {
console.error(error)
toast.error("Gagal mendapatkan pengumuman, coba lagi nanti")
} finally {
setLoading(false)
}
}
@@ -110,61 +116,83 @@ export default function EditAnnouncement() {
pt={30}
px={20}
>
<TextInput
size="md" type="text" radius={30} placeholder="Judul Pengumuman" withAsterisk label="Judul" w={"100%"}
styles={{
input: {
color: WARNA.biruTua,
borderRadius: WARNA.biruTua,
borderColor: WARNA.biruTua,
},
}}
value={body.title}
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
size="md"
radius={20}
w={"100%"}
label="Pengumuman"
withAsterisk
placeholder="Deskripsi Pengumuman"
styles={{
input: {
color: WARNA.biruTua,
borderRadius: WARNA.biruTua,
borderColor: WARNA.biruTua,
},
}}
value={body.desc}
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
)
}
/>
{loading ?
<>
<Skeleton height={40} mt={20} radius={30} />
<Skeleton height={75} mt={20} radius={10} />
<Skeleton height={40} mt={10} radius={30} />
</>
:
<>
<TextInput
size="md" type="text" radius={30} placeholder="Judul Pengumuman" withAsterisk label="Judul" w={"100%"}
styles={{
input: {
color: WARNA.biruTua,
borderRadius: WARNA.biruTua,
borderColor: WARNA.biruTua,
},
}}
value={body.title}
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
size="md"
radius={10}
w={"100%"}
label="Pengumuman"
withAsterisk
placeholder="Deskripsi Pengumuman"
styles={{
input: {
color: WARNA.biruTua,
borderRadius: WARNA.biruTua,
borderColor: WARNA.biruTua,
},
}}
value={body.desc}
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}>
Pilih Divisi
</Button>
</>
}
<Button onClick={() => { setChooseDivisi(true) }} rightSection={<HiOutlineChevronRight size={14} />} variant="default" fullWidth radius={30} size="md" mt={10}>
Pilih Divisi
</Button>
</Stack>
<Box mb={60} p={20}>
{
{loading ?
Array(3)
.fill(null)
.map((_, i) => (
<Box key={i} mb={20}>
<Skeleton height={20} radius={10} mt={20} width={"30%"} />
<Skeleton height={20} ml={40} radius={10} mt={10} width={"80%"} />
<Skeleton height={20} ml={40} radius={10} mt={20} width={"80%"} />
</Box>
))
:
memberGroup.get().map((v: any, i: any) => {
return (
<Box key={i} mt={10}>
@@ -190,25 +218,29 @@ export default function EditAnnouncement() {
zIndex: 999,
backgroundColor: `${WARNA.bgWhite}`,
}}>
<Button
c={"white"}
bg={WARNA.biruTua}
size="lg"
radius={30}
fullWidth
onClick={() => {
if (
body.title !== "" &&
body.desc !== ""
) {
setOpen(true)
} else {
toast.error("Isi data dengan lengkap")
}
}}
>
Simpan
</Button>
{loading ?
<Skeleton height={40} radius={30} />
:
<Button
c={"white"}
bg={WARNA.biruTua}
size="lg"
radius={30}
fullWidth
onClick={() => {
if (
body.title !== "" &&
body.desc !== ""
) {
setOpen(true)
} else {
toast.error("Isi data dengan lengkap")
}
}}
>
Simpan
</Button>
}
</Box>
<LayoutModal opened={isOpen} onClose={() => setOpen(false)}
description="Apakah Anda yakin ingin mengubah data?"

View File

@@ -1,7 +1,7 @@
"use client";
import { LayoutNavbarNew, WARNA } from '@/module/_global';
import { funGetGroupDivision } from '@/module/group/lib/api_group';
import { Box, Button, Divider, Flex, Group, Stack, Text } from '@mantine/core';
import { Box, Button, Divider, Flex, Group, rem, Skeleton, Stack, Text } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks';
import React, { useState } from 'react';
import { FaCheck } from 'react-icons/fa';
@@ -22,6 +22,7 @@ export default function EditChooseMember({ onClose }: { onClose: (val: any) => v
const [selectAll, setSelectAll] = useState(false);
const [isData, setIsData] = useState<GroupData[]>([])
const memberGroup = useHookstate(globalMemberEditAnnouncement)
const [loading, setLoading] = useState(true)
const handleCheck = (groupId: string, divisionId: string) => {
const newChecked = { ...checked };
@@ -70,6 +71,7 @@ export default function EditChooseMember({ onClose }: { onClose: (val: any) => v
};
async function getData() {
setLoading(true)
const response = await funGetGroupDivision()
setIsData(response.data)
@@ -81,6 +83,7 @@ export default function EditChooseMember({ onClose }: { onClose: (val: any) => v
setChecked(formatArray)
}
setLoading(false)
}
const handleSubmit = () => {
@@ -107,7 +110,7 @@ export default function EditChooseMember({ onClose }: { onClose: (val: any) => v
return (
<div>
<LayoutNavbarNew back="" title="Tambah Divisi Penerima Pengumuman" menu={<></>} />
<Box p={20}>
<Box p={20} pb={100}>
<Group justify='flex-end' mb={20}>
<Text
onClick={handleSelectAll}
@@ -121,60 +124,81 @@ export default function EditChooseMember({ onClose }: { onClose: (val: any) => v
Pilih Semua
</Text>
</Group>
{isData.map((item) => (
<Stack mb={30} key={item.id}>
<Group onClick={() => handleGroupCheck(item.id)} justify='space-between' align='center'>
<Text
style={{
cursor: 'pointer',
display: 'flex',
alignItems: 'center',
}}
fw={checked[item.id] && checked[item.id].length === item.Division.length ? 'bold' : 'normal'}
>
{item.name}
</Text>
<Text
>
{checked[item.id] && checked[item.id].length === item.Division.length ? <FaCheck style={{ marginRight: 10 }} />
: (checked[item.id] && checked[item.id].length > 0 && checked[item.id].length < item.Division.length) ? <FaMinus style={{ marginRight: 10 }} /> : ""}
</Text>
</Group>
<Divider />
{item.Division.map((division) => (
<Box key={division.id}>
<Group onClick={() => handleCheck(item.id, division.id)} justify='space-between' align='center'>
<Text
style={{
cursor: 'pointer',
display: 'flex',
alignItems: 'center',
paddingLeft: 20,
}}
>
{division.name}
</Text>
<Text
style={{
cursor: 'pointer',
display: 'flex',
alignItems: 'center',
paddingLeft: 20,
}}
>
{checked[item.id] && checked[item.id].includes(division.id) ? <FaCheck style={{ marginRight: 10 }} /> : ""}
</Text>
</Group>
<Box pt={15}>
<Divider />
</Box>
{loading ?
Array(6)
.fill(null)
.map((_, i) => (
<Box key={i} mb={20}>
<Skeleton height={20} radius={10} mt={20} width={"30%"} />
<Skeleton height={20} ml={40} radius={10} mt={10} width={"80%"} />
<Skeleton height={20} ml={40} radius={10} mt={20} width={"80%"} />
</Box>
))
:
isData.map((item) => (
<Stack mb={30} key={item.id}>
<Group onClick={() => handleGroupCheck(item.id)} justify='space-between' align='center'>
<Text
style={{
cursor: 'pointer',
display: 'flex',
alignItems: 'center',
}}
fw={checked[item.id] && checked[item.id].length === item.Division.length ? 'bold' : 'normal'}
>
{item.name}
</Text>
<Text
>
{checked[item.id] && checked[item.id].length === item.Division.length ? <FaCheck style={{ marginRight: 10 }} />
: (checked[item.id] && checked[item.id].length > 0 && checked[item.id].length < item.Division.length) ? <FaMinus style={{ marginRight: 10 }} /> : ""}
</Text>
</Group>
<Divider />
{item.Division.map((division) => (
<Box key={division.id}>
<Group onClick={() => handleCheck(item.id, division.id)} justify='space-between' align='center'>
<Text
style={{
cursor: 'pointer',
display: 'flex',
alignItems: 'center',
paddingLeft: 20,
}}
>
{division.name}
</Text>
<Text
style={{
cursor: 'pointer',
display: 'flex',
alignItems: 'center',
paddingLeft: 20,
}}
>
{checked[item.id] && checked[item.id].includes(division.id) ? <FaCheck style={{ marginRight: 10 }} /> : ""}
</Text>
</Group>
<Box pt={15}>
<Divider />
</Box>
</Box>
))}
</Stack>
))}
))}
</Stack>
))
}
<Box mt="xl">
</Box>
<Box pos={'fixed'} bottom={0} p={rem(20)} w={"100%"} style={{
maxWidth: rem(550),
zIndex: 999,
backgroundColor: `${WARNA.bgWhite}`,
}}>
{loading ?
<Skeleton height={50} radius={30} />
:
<Button
color="white"
bg={WARNA.biruTua}
@@ -188,8 +212,7 @@ export default function EditChooseMember({ onClose }: { onClose: (val: any) => v
>
Simpan
</Button>
</Box>
}
</Box>
</div>
);