updated siddhesh

This commit is contained in:
2024-06-28 15:11:57 +05:30
parent 58e799def0
commit 5265aed4f8
13 changed files with 868 additions and 521 deletions

View File

@@ -9,10 +9,8 @@ import {
Tr,
Skeleton,
TableCaption,
Tfoot,
} from "@chakra-ui/react";
import EmptySearchList from "../EmptySearchList";
import Pagination from "../Pagination";
import { useNavigate } from "react-router-dom";
import GlobalStateContext from "../../Contexts/GlobalStateContext";
@@ -22,86 +20,83 @@ const DataTable = ({
isLoading,
tableHeadRow,
emptyMessage,
totalPages,
setMouseEntered,
setMouseEnteredId,
}) => {
const navigate = useNavigate();
const { slideFromRight } = useContext(GlobalStateContext);
const columnWidth =
data && data[0]
? `${(100 / Object.keys(data[0]).length).toFixed(2)}%`
: "auto";
return (
<TableContainer overflowX={"hidden"} className="h-auto mb-3 w-100">
{data?.length === 0 ? (
<EmptySearchList message={emptyMessage} />
) : (
<Table size="sm">
{/* <TableCaption><Pagination totalItems={totalPages} /></TableCaption> */}
<TableCaption>Tanami v1.0</TableCaption>
<Thead backgroundColor="gray.50">
<Tr>
{tableHeadRow.map((heading, index) => (
<Th
textAlign={slideFromRight ? "right" : "left"}
textAlign={tableHeadRow.length - 1 === index ? "center" : "left"}
key={index}
p={3}
w={"auto"}
color={"#004118"}
>
<Skeleton isLoaded={!isLoading}
fadeDuration={0.4} height="20px" >{heading}</Skeleton>
<Skeleton isLoaded={!isLoading} fadeDuration={0.4} height="20px">
{heading}
</Skeleton>
</Th>
))}
</Tr>
</Thead>
<Tbody className="web-text-small">
{ data?.map((item, index) => (
<Tr
onMouseEnter={(e) => {
e.currentTarget.style.backgroundColor = "transparent"; // Change the background color on hover
e.currentTarget.style.transition = "0.1s";
e.currentTarget.style.boxShadow =
"rgba(0, 0, 0, 0.24) 0px 1px 8px";
setMouseEntered(true);
setMouseEnteredId(item.id);
{data?.map((item, index) => (
<Tr
// onMouseEnter={(e) => {
// e.currentTarget.style.backgroundColor = "transparent"; // Change the background color on hover
// e.currentTarget.style.transition = "0.1s";
// e.currentTarget.style.boxShadow =
// "rgba(0, 0, 0, 0.24) 0px 1px 8px";
// setMouseEntered(true);
// setMouseEnteredId(item.id);
// }}
// onMouseLeave={(e) => {
// e.currentTarget.style.backgroundColor = "transparent"; // Revert to default background color on hover out
// e.currentTarget.style.transition = "0.3s";
// e.currentTarget.style.boxShadow = "none";
// setMouseEntered(false);
// }}
transition={"0.5s all"}
_hover={{
bg: "green.50",
cursor: "pointer",
}}
key={index}
>
{tableHeadRow.map((heading, i) => (
<Td
textAlign={tableHeadRow.length - 1 === i ? "center" : "left"}
color={"gray.600"}
key={i}
style={{
whiteSpace: "nowrap",
textOverflow: "ellipsis",
}}
onMouseLeave={(e) => {
e.currentTarget.style.backgroundColor = "transparent"; // Revert to default background color on hover out
e.currentTarget.style.transition = "0.3s";
e.currentTarget.style.boxShadow = "none";
setMouseEntered(false);
}}
transition={"0.5s all"}
_hover={{
bg: "green.50",
cursor: "pointer",
}}
key={index}
className="web-text-small"
// onClick={
// i === tableHeadRow.length - 1 || i === 0
// ? null
// : () => navigate(`edit-sponser/${item.id}`) // Define the onClick handler for other cells
// }
>
{tableHeadRow.map((heading, i) => (
<Td
textAlign={slideFromRight ? "right" : "left"}
color={"gray.600"}
key={i}
style={{
whiteSpace: "nowrap",
textOverflow: "ellipsis",
}}
className="web-text-small"
// onClick={
// i === tableHeadRow.length - 1 || i === 0
// ? null
// : () => navigate(`edit-sponser/${item.id}`) // Define the onClick handler for other cells
// }
>
<Skeleton fadeDuration={index / 12} isLoaded={!isLoading} >{item[heading]}</Skeleton>
</Td>
))}
</Tr>
<Skeleton fadeDuration={index / 12} isLoaded={!isLoading}>
{item[heading]}
</Skeleton>
</Td>
))}
</Tr>
))}
</Tbody>
</Table>
)}

View File

@@ -19,7 +19,7 @@ const FormField = ({
handleImageChange,
...props
}) => (
<FormControl isInvalid={errors[name]} isRequired={isRequired} className="mb-3">
<FormControl w={"49%"} isInvalid={errors[name]} isRequired={isRequired} className="mb-3">
<FormLabel textAlign={arabic ? "right" : "left"} fontSize={"sm"}>{label}</FormLabel>
<Controller
control={control}

View File

@@ -0,0 +1,149 @@
import {
Box,
Button,
Drawer,
DrawerBody,
DrawerCloseButton,
DrawerContent,
DrawerFooter,
DrawerHeader,
DrawerOverlay,
FormControl,
FormHelperText,
FormLabel,
Input,
Text,
useDisclosure,
} from "@chakra-ui/react";
import React, { useContext, useRef, useState, useEffect } from "react";
import { FiEdit3 } from "react-icons/fi";
import { BiMessageSquareEdit } from "react-icons/bi";
import { TbEdit } from "react-icons/tb";
import GlobalStateContext from "../../Contexts/GlobalStateContext";
import { AddIcon } from "@chakra-ui/icons";
// Convert date to YYYY-MM-DD format
const formatDateValue = (date) => {
if (!date) return "";
const d = new Date(date);
let month = "" + (d.getMonth() + 1);
let day = "" + d.getDate();
const year = d.getFullYear();
if (month.length < 2) month = "0" + month;
if (day.length < 2) day = "0" + day;
return [year, month, day].join("-");
};
const AddIOCharges = ({ setCharges, charges }) => {
const btnRef = useRef();
const { isOpen, onOpen, onClose } = useDisclosure();
const [chargeTitle, setChargeTitle] = useState("");
const [chargeValue, setChargeValue] = useState(0.0);
const handleSave = () => {
setCharges([
...charges,
{
title: chargeTitle,
value: chargeValue,
},
]);
setChargeTitle("");
setChargeValue("");
setTimeout(() => {
onClose();
}, 100);
};
return (
<>
<Button
leftIcon={<AddIcon />}
ref={btnRef}
onClick={onOpen}
// colorScheme="forestGreen"
color={"green.500"}
size={"xs"}
// variant={"ghost"}
rounded={"md"}
ms={"auto"}
>
Add Charges
</Button>
<Drawer
isOpen={isOpen}
placement="right"
onClose={onClose}
finalFocusRef={btnRef}
>
<DrawerOverlay />
<DrawerContent>
<DrawerCloseButton />
<DrawerHeader fontSize={"md"}>Add charges</DrawerHeader>
<DrawerBody>
<FormControl mb={4}>
<FormLabel fontSize={"sm"}>Charge title</FormLabel>
<Input
value={chargeTitle}
onChange={(e) => setChargeTitle(e.target.value)}
fontSize={"sm"}
type="text"
size={"sm"}
placeholder="Charge title"
/>
</FormControl>
<FormControl mb={4}>
<FormLabel fontSize={"sm"}>Charge value</FormLabel>
<Input
value={chargeValue}
onChange={(e) => setChargeValue(e.target.value)}
fontSize={"sm"}
type="number"
size={"sm"}
placeholder="00.00$"
/>
<FormHelperText fontSize={"xs"}>
Please enter value in Dollars
</FormHelperText>
</FormControl>
</DrawerBody>
<DrawerFooter>
<Button
variant="outline"
colorScheme={"green"}
rounded={"sm"}
size={"sm"}
mr={3}
onClick={() => {
onClose();
setChargeTitle("");
setChargeValue("");
}}
>
Cancel
</Button>
<Button
colorScheme={"green"}
rounded={"sm"}
size={"sm"}
onClick={handleSave}
>
Save
</Button>
</DrawerFooter>
</DrawerContent>
</Drawer>
</>
);
};
export default AddIOCharges;

View File

@@ -1,4 +1,4 @@
import React, { useContext, useState } from "react";
import React, { useContext, useEffect, useState } from "react";
import { OPACITY_ON_LOAD } from "../../Layout/animations";
import {
Box,
@@ -22,6 +22,7 @@ import GlobalStateContext from "../../Contexts/GlobalStateContext";
import { useNavigate } from "react-router-dom";
import FormField from "../../Components/FormField";
import { v4 as uuidv4 } from "uuid";
import AddIOCharges from "./AddIOCharges";
const schema = yup.object().shape({
ioNameArabic: yup.string().required("Arabic name is required"),
@@ -51,71 +52,63 @@ const schema = yup.object().shape({
.required("Annual Yield is required")
.positive("Must be a positive number"),
banner_image: yup.mixed().required("Profile image is required"),
// .test(
// 'fileSize',
// 'File size is too large',
// value => value && value.size <= 10485760 // 10MB
// )
// .test(
// 'fileType',
// 'Unsupported file format',
// value => value && ['image/jpg', 'image/jpeg', 'image/gif', 'image/png'].includes(value.type)
// ),
other_image: yup.mixed().required("Profile image is required"),
// .test(
// 'fileSize',
// 'File size is too large',
// value => value && value.size <= 10485760 // 10MB
// )
// .test(
// 'fileType',
// 'Unsupported file format',
// value => value && ['image/jpg', 'image/jpeg', 'image/gif', 'image/png'].includes(value.type)
// ),
});
const startYear = 2024;
const endYear = 2124;
// const years = Array.from({ length: endYear - startYear + 1 }, (_, i) => startYear + i);
const years = Array.from({ length: 2124 - 2024 + 1 }, (_, i) => 2024 + i).map(
(year) => ({ value: year, label: year })
);
const years = Array.from(
{ length: endYear - startYear + 1 },
(_, i) => startYear + i
).map((year) => ({ value: year, label: year }));
export function debounce(func, delay) {
let debounceTimer;
return function (...args) {
clearTimeout(debounceTimer);
debounceTimer = setTimeout(() => func.apply(this, args), delay);
};
}
const CreateIO = () => {
const navigate = useNavigate();
const { sponser, setSponser } = useContext(GlobalStateContext);
const { sponser } = useContext(GlobalStateContext);
const [bannerImageData, setBannerImageData] = useState(null);
const [otherImageData, setOtherImageData] = useState(null);
const [selectedBannerImageData, setSelectedBannerImageData] = useState(null);
const [selectedOtherImageData, setSelectedOtherImageData] = useState(null);
const [charges, setCharges] = useState([]);
const [totalCharge, setTotalCharge] = useState(0.0);
const [totalAmount, setTotalAmount] = useState(0.0);
const {
control,
handleSubmit,
reset,
watch,
formState: { errors },
} = useForm({
resolver: yupResolver(schema),
// defaultValues: {
// destributedAmount: 0,
// tenure: 0,
// annualReturn: 0,
// miniInvest: 0,
// annualyield: 0,
// },
});
console.log(errors);
const destributedAmount = Number(watch().destributedAmount) || 0;
useEffect(() => {
const calculateTotalCharge = () => {
const totalChargeValue = charges.reduce(
(acc, { value }) => acc + Number(value),
0
);
setTotalCharge(totalChargeValue);
};
const calculateTotalAmount = () => {
const totalChargeValue = charges.reduce(
(acc, { value }) => acc + Number(value),
0
);
setTotalAmount(destributedAmount + totalChargeValue);
};
calculateTotalCharge();
calculateTotalAmount();
}, [charges, destributedAmount]);
const onSubmit = (data) => {
console.log(data);
navigate("/view-io");
@@ -140,350 +133,484 @@ const CreateIO = () => {
}
};
// Handler for file input
const handleOtherImageChange = (e) => {
const files = Array.from(e.target.files);
const newImageData = [...(otherImageData || []), ...files]; // Ensure otherImageData is an array
// Handler for file input
const handleOtherImageChange = (e) => {
const files = Array.from(e.target.files);
const newImageData = [...(otherImageData || []), ...files]; // Ensure otherImageData is an array
setOtherImageData(newImageData);
setOtherImageData(newImageData);
const readers = files.map(file => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onloadend = () => {
resolve(reader.result);
};
reader.onerror = reject;
reader.readAsDataURL(file);
const readers = files.map((file) => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onloadend = () => {
resolve(reader.result);
};
reader.onerror = reject;
reader.readAsDataURL(file);
});
});
});
Promise.all(readers).then(results => {
setSelectedOtherImageData([...(selectedOtherImageData || []), ...results]); // Ensure selectedOtherImageData is an array
}).catch(error => {
console.error("Error reading files:", error);
});
};
// Function to remove a specific image
const removeOtherImage = (index) => {
const newImageData = otherImageData.filter((_, i) => i !== index);
const newSelectedImageData = selectedOtherImageData.filter((_, i) => i !== index);
Promise.all(readers)
.then((results) => {
setSelectedOtherImageData([
...(selectedOtherImageData || []),
...results,
]); // Ensure selectedOtherImageData is an array
})
.catch((error) => {
console.error("Error reading files:", error);
});
};
// Function to remove a specific image
const removeOtherImage = (index) => {
const newImageData = otherImageData.filter((_, i) => i !== index);
const newSelectedImageData = selectedOtherImageData.filter(
(_, i) => i !== index
);
setOtherImageData(newImageData);
setSelectedOtherImageData(newSelectedImageData);
};
setOtherImageData(newImageData);
setSelectedOtherImageData(newSelectedImageData);
};
return (
<Box {...OPACITY_ON_LOAD} overflowY={"scroll"} height={"100vh"} pb={14}>
<form onSubmit={handleSubmit(onSubmit)}>
<Heading as="h6" size="xs" mt={4}>
Investment Object Details
</Heading>
<Box display={"flex"} gap={0}>
<Box
width={"50%"}
p={5}
display={"flex"}
flexDirection={"column"}
gap={4}
>
<FormField
label="Investment object name"
name="ioName"
control={control}
errors={errors}
isRequired={true}
/>
<Box width={"100%"} p={5} display={"flex"} flexWrap={"wrap"} gap={4}>
<FormField
label="Investment object name"
name="ioName"
control={control}
errors={errors}
isRequired={true}
/>
<FormField
label="Destributed Amount"
placeHolder={"$00.0"}
helperText={"Please enter value in $"}
name="destributedAmount"
type="number"
control={control}
errors={errors}
isRequired={true}
/>
<FormField
label="Investment object"
name="ioNameArabic"
placeHolder={"الرجاء إدخال القيمة"}
control={control}
errors={errors}
isRequired={true}
arabic={true}
/>
<FormField
label="Year"
control={control}
name="year"
type="select"
options={years}
errors={errors}
isRequired={true}
/>
<FormField
label="Destributed Amount"
placeHolder={"$00.0"}
helperText={"Please enter value in $"}
name="destributedAmount"
type="number"
control={control}
errors={errors}
isRequired={true}
/>
<FormField
label="Sponsers Name"
control={control}
name="sponserName"
type="select"
options={sponserOptions}
errors={errors}
isRequired={true}
/>
<FormField
label="Min Invest"
placeHolder={"$00.00"}
helperText={"Please enter value in $"}
name="miniInvest"
type="number"
control={control}
errors={errors}
isRequired={true}
/>
<FormField
label="Tenure"
// helperText={"Please enter value in Dollar"}
name="tenure"
type="number"
control={control}
errors={errors}
isRequired={true}
/>
<FormField
label="Sponsers Name"
control={control}
name="sponserName"
type="select"
options={sponserOptions}
errors={errors}
isRequired={true}
/>
<FormField
label="Annual return"
placeHolder={"00.00%"}
helperText={"Please enter value in percentage"}
name="annualReturn"
type="number"
control={control}
errors={errors}
isRequired={true}
/>
<FormField
label="Year"
control={control}
name="year"
type="select"
options={years}
errors={errors}
isRequired={true}
/>
<FormField
label="Banner image"
control={control}
name="banner_image"
type="fileNormal"
helperText={"You can select only one image for banner."}
errors={errors}
multiple={false}
handleImageChange={handleBannerImageChange}
isRequired={true}
rules={{
required: "Profile image is required",
}}
// register={register} // Pass register function to FormField
/>
<FormField
label="Annual return"
placeHolder={"00.00%"}
helperText={"Please enter value in percentage"}
name="annualReturn"
type="number"
control={control}
errors={errors}
isRequired={true}
/>
{selectedBannerImageData && (
<Box width={"20%"}>
<Image
rounded={"md"}
objectFit={"cover"}
src={selectedBannerImageData}
alt="profile"
width={100}
height={100}
/>
<Box
w={"100%"}
display={"flex"}
flexDirection={"column"}
position={"relative"}
>
<CloseIcon
onClick={() => setSelectedBannerImageData(null)}
className="link pointer"
p={1}
fontSize={"lg"}
color={"red"}
fontWeight={"500"}
rounded={"md"}
position={"absolute"}
top={1}
right={0}
/>
<Text
as={"span"}
fontSize={"xs"}
w={"80%"}
fontWeight={"500"}
mt={1}
isTruncated={true}
>
{bannerImageData?.name}
</Text>
<Text as={"span"} fontSize={"xs"} fontStyle={"italic"}>
{(bannerImageData?.size / (1024 * 1024)).toFixed(2)} mb
</Text>
</Box>
</Box>
)}
</Box>
<FormField
label="Annual yeild"
placeHolder={"00.00%"}
helperText={"Please enter value in percentage"}
name="annualyield"
type="number"
control={control}
errors={errors}
isRequired={true}
/>
<Box
width={"50%"}
p={5}
display={"flex"}
flexDirection={"column"}
gap={4}
>
<FormField
label="Investment object"
name="ioNameArabic"
placeHolder={"الرجاء إدخال القيمة"}
control={control}
errors={errors}
isRequired={true}
arabic={true}
/>
<FormField
label="Quaterly"
control={control}
name="quaterly"
type="select"
options={[
{
label: "Q1",
value: "Q1",
},
{
label: "Q2",
value: "Q2",
},
{
label: "Q3",
value: "Q3",
},
{
label: "Q4",
value: "Q4",
},
]}
errors={errors}
isRequired={true}
/>
<FormField
label="Min Invest"
placeHolder={"$00.00"}
helperText={"Please enter value in $"}
name="miniInvest"
type="number"
control={control}
errors={errors}
isRequired={true}
/>
<FormField
label="Tenure"
// helperText={"Please enter value in Dollar"}
name="tenure"
type="number"
control={control}
errors={errors}
isRequired={true}
/>
<FormField
label="Quaterly"
control={control}
name="quaterly"
type="select"
options={[
{
label: "Q1",
value: "Q1",
},
{
label: "Q2",
value: "Q2",
},
{
label: "Q3",
value: "Q3",
},
{
label: "Q4",
value: "Q4",
},
]}
errors={errors}
isRequired={true}
/>
<FormField
label="Target close"
name="targetClose"
type="date"
control={control}
errors={errors}
isRequired={true}
/>
<FormField
label="Annual yeild"
placeHolder={"00.00%"}
helperText={"Please enter value in percentage"}
name="annualyield"
type="number"
control={control}
errors={errors}
isRequired={true}
/>
<FormField
id="otherImageInput"
label="Other images"
control={control}
name="other_image"
type="fileNormal"
multiple={true}
errors={errors}
handleImageChange={handleOtherImageChange}
isRequired={true}
rules={{
required: "Profile image is required",
}}
// register={register} // Pass register function to FormField
/>
{selectedOtherImageData?.length > 0 && (
<Box width={"100%"} display="flex" flexWrap="wrap" gap={4}>
{selectedOtherImageData.map((imageData, index) => (
<Box key={index} width={"100px"}>
<Image
rounded={"md"}
objectFit={"cover"}
src={imageData}
alt={`profile-${index}`}
width={100}
height={100}
/>
<Box
display={"flex"}
flexDirection={"column"}
position={"relative"}
>
<CloseIcon
onClick={() => removeOtherImage(index)}
bg={"#fff"}
className="link pointer"
p={1}
fontSize={"lg"}
color={"red"}
fontWeight={"500"}
rounded={"md"}
position={"absolute"}
bottom={0}
right={0}
/>
<Text
as={"span"}
fontSize={"xs"}
fontWeight={"500"}
mt={1}
isTruncated={true}
>
{otherImageData[index]?.name}
</Text>
<Text as={"span"} fontSize={"xs"} fontStyle={"italic"}>
{(otherImageData[index]?.size / (1024 * 1024)).toFixed(
2
)}{" "}
mb
</Text>
</Box>
</Box>
))}
{/* <Box width={"100px"} display={'flex'} alignItems={'center'}> */}
<AddIcon
onClick={() => document.getElementById('otherImageInput').click()}
rounded={"md"}
width={50}
height={50}
mt={26}
p={4}
cursor={"pointer"}
// rounded={'md'}
className="link"
/>
{/* </Box> */}
</Box>
)}
</Box>
<FormField
label="Target close"
name="targetClose"
type="date"
control={control}
errors={errors}
isRequired={true}
/>
</Box>
<Divider />
<Heading w={"100%"} as="h6" size="xs" mb={5}>
Uplaod Banner Images
</Heading>
<Box
width={"100%"}
p={5}
pt={0}
display={"flex"}
flexWrap={"wrap"}
gap={4}
>
<FormField
label="Banner image"
control={control}
name="banner_image"
type="fileNormal"
helperText={"You can select only one image for banner."}
errors={errors}
multiple={false}
handleImageChange={handleBannerImageChange}
isRequired={true}
rules={{
required: "Profile image is required",
}}
// register={register} // Pass register function to FormField
/>
<FormField
id="otherImageInput"
label="Other images"
control={control}
name="other_image"
type="fileNormal"
multiple={true}
errors={errors}
handleImageChange={handleOtherImageChange}
isRequired={true}
rules={{
required: "Profile image is required",
}}
// register={register} // Pass register function to FormField
/>
{selectedBannerImageData && (
<Box width={"49%"}>
<Image
rounded={"md"}
objectFit={"cover"}
src={selectedBannerImageData}
alt="profile"
width={100}
height={100}
/>
<Box
w={"30%"}
display={"flex"}
flexDirection={"column"}
position={"relative"}
>
<CloseIcon
onClick={() => setSelectedBannerImageData(null)}
className="link pointer"
p={1}
fontSize={"lg"}
color={"red"}
fontWeight={"500"}
rounded={"md"}
position={"absolute"}
top={1}
right={0}
/>
<Text
as={"span"}
fontSize={"xs"}
w={"70%"}
fontWeight={"500"}
mt={1}
isTruncated={true}
>
{bannerImageData?.name}
</Text>
<Text as={"span"} fontSize={"xs"} fontStyle={"italic"}>
{(bannerImageData?.size / (1024 * 1024)).toFixed(2)} mb
</Text>
</Box>
</Box>
)}
{selectedOtherImageData?.length > 0 && (
<Box width={"49.5%"} display="flex" flexWrap="wrap" gap={4}>
{selectedOtherImageData.map((imageData, index) => (
<Box key={index} width={"100px"}>
<Image
rounded={"md"}
objectFit={"cover"}
src={imageData}
alt={`profile-${index}`}
width={100}
height={100}
/>
<Box
display={"flex"}
flexDirection={"column"}
position={"relative"}
>
<CloseIcon
onClick={() => removeOtherImage(index)}
bg={"#fff"}
className="link pointer"
p={1}
fontSize={"lg"}
color={"red"}
fontWeight={"500"}
rounded={"md"}
position={"absolute"}
bottom={0}
right={0}
/>
<Text
as={"span"}
fontSize={"xs"}
fontWeight={"500"}
mt={1}
isTruncated={true}
>
{otherImageData[index]?.name}
</Text>
<Text as={"span"} fontSize={"xs"} fontStyle={"italic"}>
{(otherImageData[index]?.size / (1024 * 1024)).toFixed(2)}{" "}
mb
</Text>
</Box>
</Box>
))}
{/* <Box width={"100px"} display={'flex'} alignItems={'center'}> */}
<AddIcon
onClick={() =>
document.getElementById("otherImageInput").click()
}
rounded={"md"}
width={50}
height={50}
mt={26}
p={4}
cursor={"pointer"}
// rounded={'md'}
className="link"
/>
{/* </Box> */}
</Box>
)}
</Box>
<Divider />
<Heading
w={"100%"}
display={"flex"}
justifyContent={"space-between"}
as="h6"
size="xs"
mb={5}
pe={6}
>
Final calculation
<AddIOCharges charges={charges} setCharges={setCharges} />
</Heading>
<Box
w={"40%"}
display={"flex"}
justifyContent={"center"}
flexDirection={"column"}
alignItems={"start"}
gap={1}
p={5}
m={1}
rounded={"lg"}
boxShadow={"lg"}
color={"#fff"}
bgGradient="linear(to-tr, #000000, #004118)"
>
{charges.map(({ title, value }, index) => (
<Box as={"span"} w={"100%"} display={"flex"}>
<Text
fontSize={"sm"}
fontWeight={"600"}
as={"span"}
w={"70%"}
bg={""}
>
{title}
</Text>
<Text
as={"span"}
fontSize={"sm"}
fontWeight={"600"}
w={"30%"}
bg={""}
>
$ {value}
</Text>
</Box>
))}
<Box
as={"span"}
w={"100%"}
display={"flex"}
flexDirection={"column"}
gap={2}
>
{totalCharge !== 0 ? (
<Box display={"flex"}>
<Text
fontSize={"sm"}
fontWeight={"500"}
as={"span"}
w={"70%"}
bg={""}
>
Total charges
</Text>
<Text
as={"span"}
fontSize={"sm"}
fontWeight={"600"}
w={"30%"}
bg={""}
>
$ {totalCharge.toFixed(4)}
</Text>
</Box>
) : (
""
)}
<Box display={"flex"}>
<Text
fontSize={"sm"}
fontWeight={"500"}
as={"span"}
w={"70%"}
bg={""}
>
Total distributed amount
</Text>
<Text
as={"span"}
fontSize={"sm"}
fontWeight={"600"}
w={"30%"}
bg={""}
>
$ {destributedAmount.toFixed(4)}
</Text>
</Box>
<Box pt={2} borderTop={"1px solid #fff"} as="span" display={"flex"}>
<Text
fontSize={"sm"}
fontWeight={"500"}
as={"span"}
w={"70%"}
bg={""}
>
Total Net Charges
</Text>
<Text
as={"span"}
fontSize={"sm"}
fontWeight={"600"}
w={"30%"}
bg={""}
>
$ {totalAmount.toFixed(4)}
</Text>
</Box>
</Box>
</Box>
<Box display={"flex"} justifyContent={"flex-end"} p={4}>
<Button
size={"sm"}
width={"50%"}
rounded={"sm"}
type="submit"
colorScheme="green"
mt={4}
>
Submit
</Button>
size={"sm"}
width={"50%"}
rounded={"sm"}
type="submit"
colorScheme="green"
mt={4}
>
Submit
</Button>
</Box>
</form>
{/* <Divider /> */}
</form>
</Box>
);
};

View File

@@ -70,17 +70,17 @@ const ExchangeRate = () => {
<Box {...OPACITY_ON_LOAD} overflowY={"scroll"} height={"100vh"}>
<Tabs position="relative" variant="unstyled" mt={2}>
<TabList>
<Tab fontSize={"sm"}>All</Tab>
<Tab fontSize={"sm"}>Available</Tab>
{/* <Tab fontSize={"sm"}>All</Tab> */}
{/* <Tab fontSize={"sm"}>Available</Tab>
<Tab fontSize={"sm"}>Upcomming</Tab>
<Tab fontSize={"sm"}>Closed</Tab>
<Tab fontSize={"sm"}>Closed</Tab> */}
</TabList>
<TabIndicator
{/* <TabIndicator
mt="-1.5px"
height="2px"
bg="green.500"
borderRadius="1px"
/>
/> */}
<TabPanels>
<TabPanel>
<Box display={"flex"} justifyContent={"space-between"}>
@@ -122,7 +122,7 @@ const ExchangeRate = () => {
)}
</TabPanel>
<TabPanel>
{/* <TabPanel>
<Box display={"flex"} justifyContent={"space-between"}>
<Input
type="search"
@@ -199,7 +199,7 @@ const ExchangeRate = () => {
</Skeleton>
))
)}
</TabPanel>
</TabPanel> */}
</TabPanels>
</Tabs>
</Box>

View File

@@ -141,7 +141,8 @@ const InvestorDetails = () => {
// ),
Action: (
<Button colorScheme="green" size={"xs"} variant={"ghost"}>
<Button
color={"green.500"} size={"xs"} variant={"ghost"}>
Distribute
</Button>
),

View File

@@ -44,7 +44,7 @@ const Login = () => {
const onSubmit = (value) => {
setIsLoading(true);
if (value.name === "Admin" && value.password === "Admin") {
if (value.name === "admin@tanami.com" && value.password === "Admin@123") {
return setTimeout(() => {
// dispatch(loginUser(true));
setIsAuthenticate(true);
@@ -125,7 +125,7 @@ const Login = () => {
className="mb-4"
/>
<span className="fw-bold fs-2 rubix-text-dark text-start">
Welcome back.
Welcome.
</span>
<span className="fw-500 web-text-large text-secondary text-start">
Login to manage tanami.
@@ -134,7 +134,7 @@ const Login = () => {
<FormControl className=" mb-3">
<FormLabel className="rubix-text-dark ps-1 web-text-medium fw-bold">
Owner name <span className="text-danger">*</span>
E-mail <span className="text-danger">*</span>
</FormLabel>
<Input

View File

@@ -78,17 +78,19 @@ const EditExchangeRate = ({ id, setIsLoading }) => {
return (
<>
<Button
leftIcon={<TbEdit/>}
ref={btnRef}
onClick={onOpen}
// colorScheme="forestGreen"
color={"green.500"}
size={"xs"}
variant={"ghost"}
>
Edit
</Button>
<Button
leftIcon={<TbEdit/>}
ref={btnRef}
onClick={onOpen}
// colorScheme="forestGreen"
color={"green.500"}
size={"xs"}
variant={"ghost"}
rounded={'md'}
ms={"auto"}
>
Edit
</Button>
<Drawer
isOpen={isOpen}
placement="right"

View File

@@ -153,7 +153,7 @@ const ExchangeRate = () => {
// <Button colorScheme="green" size={"xs"} variant={"ghost"}>
// Edit
// </Button>
<EditExchangeRate setIsLoading={setIsLoading} id={item.id} />
),
}));

View File

@@ -84,20 +84,21 @@ const AddSponser = () => {
Personal Details
</Heading>
<Box display={"flex"} gap={0}>
<Box
width={"50%"}
p={5}
display={"flex"}
flexDirection={"column"}
gap={4}
>
<Box width={"100%"} p={5} display={"flex"} flexWrap={"wrap"} gap={4}>
<FormField
label="Sponser name"
name="sponserName"
control={control}
errors={errors}
isRequired={true}
/>
/><FormField
placeHolder={"الرجاء إدخال القيمة"}
name="اسم الراعي"
control={control}
errors={errors}
isRequired={true}
arabic={true}
/>
<FormField
label="Mobile no"
name="mobileNo"
@@ -116,22 +117,6 @@ const AddSponser = () => {
/>
</Box>
<Box
width={"50%"}
p={5}
display={"flex"}
flexDirection={"column"}
gap={4}
>
<FormField
label="اسم الراعي"
name="اسم الراعي"
control={control}
errors={errors}
isRequired={true}
arabic={true}
/>
</Box>
</Box>
<Divider />
@@ -141,13 +126,7 @@ const AddSponser = () => {
</Heading>
<Box display={"flex"} gap={0}>
{Array(1).fill(
<Box
width={"50%"}
p={5}
display={"flex"}
flexDirection={"column"}
gap={4}
>
<Box width={"100%"} p={5} display={"flex"} flexWrap={"wrap"} gap={4}>
{/* <FormField
label="Account Holder's Name"
name="accountHolderName"
@@ -246,10 +225,10 @@ const AddSponser = () => {
)}
</Box>
<Box display={"flex"} justifyContent={"flex-start"} p={4}>
<Box display={"flex"} justifyContent={"flex-end"} p={4}>
<Button
size={"sm"}
width={"50%"}
width={"49.5%"}
rounded={"sm"}
type="submit"
colorScheme="green"

View File

@@ -14,6 +14,7 @@ import {
Switch,
Tag,
Text,
Tooltip,
useToast,
} from "@chakra-ui/react";
import React, { useContext, useEffect, useState } from "react";
@@ -21,7 +22,15 @@ import { OPACITY_ON_LOAD } from "../../../Layout/animations";
import DataTable from "../../../Components/DataTable/DataTable";
import { HiDotsVertical } from "react-icons/hi";
import { Link, Link as RouterLink } from "react-router-dom";
import { AddIcon, EmailIcon } from "@chakra-ui/icons";
import {
AddIcon,
CheckIcon,
CloseIcon,
DeleteIcon,
EditIcon,
EmailIcon,
ViewIcon,
} from "@chakra-ui/icons";
import Pagination from "../../../Components/Pagination";
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
import CustomAlertDialog from "../../../Components/CustomAlertDialog";
@@ -31,8 +40,9 @@ import { debounce } from "./AddSponser";
const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date formatter
const Sponser = () => {
const toast = useToast()
const { sponser, setSponser,slideFromRight } = useContext(GlobalStateContext);
const toast = useToast();
const { sponser, setSponser, slideFromRight } =
useContext(GlobalStateContext);
const [searchTerm, setSearchTerm] = useState("");
const [isLoading, setIsLoading] = useState(true);
const [deleteAlert, setDeleteAlert] = useState(false);
@@ -40,8 +50,6 @@ const Sponser = () => {
const [mouseEntered, setMouseEntered] = useState(false);
const [mouseEnteredId, setMouseEnteredId] = useState("");
useEffect(() => {
// Simulate loading
const timer = setTimeout(() => {
@@ -59,23 +67,19 @@ const Sponser = () => {
"Mobile no",
"Status",
"Created At",
"Action",
];
const handleUpdateStatus = debounce((id) => {
setSponser((prevSponser) =>
prevSponser.map((sponsor) =>
sponsor.id === id ? { ...sponsor, status: !sponsor.status } : sponsor
)
);
toast({
render: () => (
<ToastBox
message={"Status changed succesfully.!"}
/>
),
render: () => <ToastBox message={"Status changed succesfully.!"} />,
});
},300) ;
}, 300);
// ====================================================[Table Filter]================================================================
const filteredData = sponser.filter((item) => {
@@ -99,54 +103,55 @@ const Sponser = () => {
const extractedArray = filteredData?.map((item) => ({
id: item?.id,
"Sponser name": (
<Text justifyContent={slideFromRight? 'right': 'left' }
<Text
justifyContent={slideFromRight ? "right" : "left"}
as={"span"}
color={"teal.900"}
fontWeight={'500'}
fontWeight={"500"}
className="d-flex align-items-center web-text-small"
>
{item.sponserName}
</Text>
),
Address: (
<Box w={350} isTruncated={true} >
<Text as={"span"} color={"teal.900"} fontWeight={'500'}>
<Box w={350} isTruncated={true}>
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
{item.sponserAddress}
</Text>
</Box>
),
"Mobile no": (
<Box w={"auto"} isTruncated={true}>
<Text as={"span"} color={"teal.900"} fontWeight={'500'}>
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
{item.mobileNo}
</Text>
</Box>
),
Status:
Status: (
<Switch
size={"sm"}
colorScheme="green"
onChange={() => handleUpdateStatus(item.id)}
isChecked={item.status}
/>
),
// item?.status ? (
// <Badge bg={'transparent'} color={"#05c46b"}>
// Passed
// </Badge>
// ) : (
// <Badge bg={'transparent'} color={"#f53b57"}>
// Not passes
// </Badge>
// ),
// item?.status ? (
// <Badge bg={'transparent'} color={"#05c46b"}>
// Passed
// </Badge>
// ) : (
// <Badge bg={'transparent'} color={"#f53b57"}>
// Not passes
// </Badge>
// ),
,
"Created At": (
<span className="d-flex justify-content-between align-items-center">
<Text as={"span"} color={"gray.600"} fontWeight={'500'}>
<Text as={"span"} color={"gray.600"} fontWeight={"500"}>
{formatDate(item.createdAt)}
</Text>
<Menu>
{/* <Menu>
<MenuButton className="link p-1 rounded-1">
<HiDotsVertical className="rubix-text-dark fs-6" />
</MenuButton>
@@ -169,13 +174,108 @@ const Sponser = () => {
</MenuItem>
</MenuList>
</Portal>
</Menu>
</Menu> */}
</span>
),
Action: (
<Box display={"flex"} justifyContent={"space-between"}>
<Tooltip
rounded={"sm"}
fontSize={"xs"}
label="View"
bg="#fff"
color={"green.500"}
placement="top"
>
<Button
_hover={{ color: "green.500" }}
// transition={"0.5s all"}
color="green.300"
rounded={"sm"}
size={"xs"}
>
<ViewIcon />
</Button>
</Tooltip>
<Tooltip
rounded={"sm"}
fontSize={"xs"}
label="Edit"
bg="#fff"
color={"blue.500"}
placement="top"
>
<Button
_hover={{ color: "blue.500" }}
// transition={"0.5s all"}
color="blue.400"
rounded={"sm"}
size={"xs"}
>
<EditIcon />
</Button>
</Tooltip>
<Tooltip
rounded={"sm"}
fontSize={"xs"}
label="Delete"
bg="#fff"
color={"red.500"}
placement="top"
>
<Button
onClick={() => {
setActionId(item?.id);
setDeleteAlert(true);
}}
_hover={{ color: "red.500" }}
// transition={"0.5s all"}
color="red.300"
rounded={"sm"}
size={"xs"}
>
<DeleteIcon />
</Button>
</Tooltip>
</Box>
),
// "Created At":
// mouseEntered && mouseEnteredId === item?.id ? (
// // false ? (
// <Box w={38} as="span" display={"flex"} justifyContent={"start"} gap={3}>
// <Box as="span" p={1} className="link" rounded={'sm'} >
// <EditIcon fontSize={'md'} />
// </Box>
// <Box as="span" p={1} className="link" rounded={'sm'} >
// <ViewIcon fontSize={'md'} />
// </Box>
// <Box as="span" p={1} className="link" rounded={'sm'} >
// <DeleteIcon fontSize={'md'} />
// </Box>
// </Box>
// ) : (
// <Box
// as="span" display={"flex"} justifyContent={"start"}
// p={1}
// >
// <Text as={"span"} color={"gray.600"} fontWeight={"500"}>
// {formatDate(item.createdAt)}
// </Text>
// </Box>
// ),
}));
const handleDelete = () => {
const updatedSponsors = sponser.filter((sponsor) => sponsor.id !== actionId);
const updatedSponsors = sponser.filter(
(sponsor) => sponsor.id !== actionId
);
setTimeout(() => {
setSponser(updatedSponsors);
@@ -185,9 +285,6 @@ const Sponser = () => {
setIsLoading(true);
};
return (
<Box {...OPACITY_ON_LOAD} overflowY={"scroll"} height={"100vh"} pb={38}>
<Box bg="white.500">
@@ -237,16 +334,12 @@ const Sponser = () => {
setViewActionId={setActionId}
// totalPages={10}
setMouseEnteredId={setMouseEnteredId}
setMouseEntered={setMouseEntered}
/>
<CustomAlertDialog
onClose={()=> setDeleteAlert(false)}
onClose={() => setDeleteAlert(false)}
isOpen={deleteAlert}
message={"Are you sure you want to delete sponers?"}
alertHandler={handleDelete}

View File

@@ -6,6 +6,7 @@ import {
HStack,
Input,
Text,
Tooltip,
useToast,
} from "@chakra-ui/react";
import React, { useContext, useEffect, useState } from "react";
@@ -15,6 +16,7 @@ import Pagination from "../../Components/Pagination";
import GlobalStateContext from "../../Contexts/GlobalStateContext";
import CustomAlertDialog from "../../Components/CustomAlertDialog";
import { formatDate } from "../../Components/Functions/UTCConvertor";
import { CheckIcon, CloseIcon } from "@chakra-ui/icons";
// import { formatDate } from "../../Components/Functions/UTCConvertor";
const PendingRequest = () => {
@@ -65,7 +67,7 @@ const PendingRequest = () => {
"Charges (USD)",
"Year",
"Quater",
"Amount",
"Action",
];
const extractedArray = filteredData?.map((item, index) => ({
@@ -138,16 +140,15 @@ const PendingRequest = () => {
</Text>
),
Amount: (
<Text
justifyContent={slideFromRight ? "right" : "left"}
as={"span"}
color={"gray.600"}
className="d-flex align-items-center web-text-small"
fontWeight={'500'}
>
{item.amount}
</Text>
Action: (
<Box display={'flex'} justifyContent={'space-around'}>
<Tooltip rounded={'sm'} fontSize={'xs'} label='Accept' bg='#fff' color={'green.500'} placement="left-start">
<Button color="green.500" rounded={'sm'} size={'xs'}>
<CheckIcon /></Button></Tooltip>
<Tooltip rounded={'sm'} fontSize={'xs'} label='Reject' bg='#fff' color={'red.500'} placement="left-start">
<Button color="red.500" rounded={'sm'} size={'xs'}>
<CloseIcon /></Button></Tooltip>
</Box>
),
}));

View File

@@ -65,7 +65,7 @@ const ViewHistory = () => {
"Charges (USD)",
"Year",
"Quater",
"Amount",
"Action",
];
const extractedArray = filteredData?.map((item, index) => ({
@@ -138,7 +138,7 @@ const ViewHistory = () => {
</Text>
),
Amount: (
Action: (
<Text
justifyContent={slideFromRight ? "right" : "left"}
as={"span"}