diff --git a/src/Components/Banner/AddBanner.jsx b/src/Components/Banner/AddBanner.jsx index 9c015bc..2a94ecb 100644 --- a/src/Components/Banner/AddBanner.jsx +++ b/src/Components/Banner/AddBanner.jsx @@ -28,6 +28,7 @@ import { import { useNavigate } from "react-router-dom"; import Loader01 from "../../Components/Loaders/Loader01"; import Header from "../Header"; +import ToastBox from "../ToastBox"; const AddBanner = ({ createApi, navigateLink, title }) => { const toast = useToast(); @@ -67,18 +68,18 @@ const AddBanner = ({ createApi, navigateLink, title }) => { if (response?.data?.statusCode === 200) { setIsLoading(false); toast({ - title: response?.data?.message, - status: "success", - isClosable: true, + render: () => ( + + ), }); reset(); navigate(navigateLink); } else if (response?.data?.statusCode === 500) { setIsLoading(false); toast({ - title: response?.data?.message, - status: "success", - isClosable: true, + render: () => ( + + ), }); } }) diff --git a/src/Components/Banner/BannerEdit.jsx b/src/Components/Banner/BannerEdit.jsx new file mode 100644 index 0000000..fef3bb5 --- /dev/null +++ b/src/Components/Banner/BannerEdit.jsx @@ -0,0 +1,8 @@ + +const BannerEdit = ({title}) => { + return ( +
{title}
+ ) +} + +export default BannerEdit \ No newline at end of file diff --git a/src/Components/Banner/BannerTable.jsx b/src/Components/Banner/BannerTable.jsx index bbaf007..bc9bff9 100644 --- a/src/Components/Banner/BannerTable.jsx +++ b/src/Components/Banner/BannerTable.jsx @@ -37,11 +37,15 @@ const BannerCommunity = ({ statusUpdateApi, title, addLink, + viewLink, + editLink + }) => { // ====================================================[Hooks]=================================================================== const toast = useToast(); const [deleteAlert, setDeleteAlert] = useState(false); const [actionId, setActionId] = useState(null); + const [actionStatus, setActionStatus] = useState(null); const [deleteIsLoading, setDeleteIsLoading] = useState(false); const [searchTerm, setSearchTerm] = useState(""); const [statusFilter, setStatusFilter] = useState("all"); @@ -56,24 +60,29 @@ const BannerCommunity = ({ // ====================================================[Functions]=================================================================== - const handleDelete = async (bannerId) => { + const handleDelete = async (bannerId, status) => { + if (status) { + return toast({ + render: () => ( + + ), + }); + + } try { // Trigger the mutation setDeleteIsLoading(true); await deleteApi(bannerId) .then((response) => { // Handle the response here - console.log("Mutation response:", response?.data?.statusCode); - console.log("Mutation response:", response?.data?.message); if (response?.data?.statusCode === 200) { setDeleteIsLoading(false); setDeleteAlert(false); toast({ - title: response?.data?.message, - status: "success", - duration: 1000, - isClosable: true, + render: () => ( + + ), }); } }) @@ -95,8 +104,8 @@ const BannerCommunity = ({ ), }); - } - + }else{ + try { // Trigger the mutation await statusUpdateApi({ id }) @@ -114,6 +123,8 @@ const BannerCommunity = ({ // Handle errors console.error("Error updating community status:", error); } + } + }; // ====================================================[Table Filter]================================================================ @@ -208,16 +219,17 @@ const BannerCommunity = ({ - + Edit - + View { setActionId(item.id); setDeleteAlert(true); + setActionStatus(item.status) }} className="web-text-medium" > @@ -339,7 +351,7 @@ const BannerCommunity = ({ setDeleteAlert(false)} isOpen={deleteAlert} - alertHandler={() => handleDelete(actionId)} + alertHandler={() => handleDelete(actionId, actionStatus)} message={"Are you sure you want to delete member?"} isLoading={deleteIsLoading} /> diff --git a/src/Components/Functions/FileNameAlter.jsx b/src/Components/Functions/FileNameAlter.jsx new file mode 100644 index 0000000..1ab4128 --- /dev/null +++ b/src/Components/Functions/FileNameAlter.jsx @@ -0,0 +1,9 @@ +const extractFilename = (filePath) => { + console.log(filePath); + // Use the split method to break the path into parts based on '/' + const parts = filePath.split('/'); + // Return the last part, which is the filename + return parts[parts.length - 1]; +}; + +export default extractFilename ; diff --git a/src/Components/Loaders/FullscreenLoaders.jsx b/src/Components/Loaders/FullscreenLoaders.jsx index 0705dba..3d6dfd6 100644 --- a/src/Components/Loaders/FullscreenLoaders.jsx +++ b/src/Components/Loaders/FullscreenLoaders.jsx @@ -10,7 +10,7 @@ const FullscreenLoaders = () => { w={"100%"} h={"90%"} > - + ); }; diff --git a/src/Components/TabularView/TabularView.jsx b/src/Components/TabularView/TabularView.jsx new file mode 100644 index 0000000..70f29cf --- /dev/null +++ b/src/Components/TabularView/TabularView.jsx @@ -0,0 +1,138 @@ +import { Box, HStack, Input, Select, Text } from "@chakra-ui/react"; +import { OPACITY_ON_LOAD } from "../../Layout/animations"; +import { TABLE_PAGINATION } from "../../Constants/Paginations"; +import { useGetVideosQuery } from "../../Services/api.service"; +import { useState } from "react"; +import Header from "../../Components/Header"; +import { ChevronLeftIcon, ChevronRightIcon } from "@chakra-ui/icons"; +import DataTable from "../../Components/DataTable/DataTable"; + +const TabularView = ({ + apiData, + tableHeadRow, + title, + btnTitle, + link, + extractedArray, + searchTerm, + setSearchTerm, + statusFilter, + setStatusFilter, + currentPage, + setCurrentPage, + pageSize, + setPageSize, + totalPages +}) => { + const [displayRange, setDisplayRange] = useState({ + start: TABLE_PAGINATION?.page, + end: pageSize, + }); + // ====================================================[Pagination Setup]================================================================ + const paginationPrev = () => { + if (currentPage > 1) { + setCurrentPage(currentPage - 1); + updateDisplayRange(currentPage - 1); + } + }; + + console.log(apiData?.data?.data); + + const paginationNext = () => { + const totalPage = Math.ceil(totalPages / pageSize); + if (currentPage < totalPage) { + setCurrentPage(currentPage + 1); + updateDisplayRange(currentPage + 1); + } + }; + const updateDisplayRange = (page) => { + const start = (page - 1) * pageSize + 1; + const end = Math.min(start + pageSize - 1, totalPages); + setDisplayRange({ start, end }); + }; + + + + return ( + +
+ + + + setSearchTerm(e.target.value)} + /> + + + + + + + + + {displayRange.start} - {displayRange.end} of{" "} + {totalPages} + + + + + + + + {/* ====================================================[ Table ]================================================================ */} + + + ); +}; + +export default TabularView; diff --git a/src/Pages/Banners/Banner.jsx b/src/Pages/Banners/Banner.jsx index c163b80..4721884 100644 --- a/src/Pages/Banners/Banner.jsx +++ b/src/Pages/Banners/Banner.jsx @@ -4,6 +4,7 @@ import { OPACITY_ON_LOAD } from "../../Layout/animations"; import { useGetBuildBannerQuery, useGetCommunityBannerQuery, + useGetHomeBannerQuery, useGetLearnBannerQuery, useGetNewsBannerQuery, } from "../../Services/api.service"; @@ -15,6 +16,7 @@ const Banner = () => { const learnBanner = useGetLearnBannerQuery(); const buildBanner = useGetBuildBannerQuery(); const newsBanner = useGetNewsBannerQuery(); + const homeBanner = useGetHomeBannerQuery(); return ( @@ -54,8 +56,8 @@ const Banner = () => { diff --git a/src/Pages/Banners/BannerBuild/BannerBuild.jsx b/src/Pages/Banners/BannerBuild/BannerBuild.jsx index 2f1faba..0cd0279 100644 --- a/src/Pages/Banners/BannerBuild/BannerBuild.jsx +++ b/src/Pages/Banners/BannerBuild/BannerBuild.jsx @@ -15,6 +15,8 @@ const BannerBuild = () => { { +const BannerBuildAdd = () => { const [createBuildBannerData] = useCreateBuildBannerMutation(); return ( { ); }; -export default BuildBannerAdd; +export default BannerBuildAdd; diff --git a/src/Pages/Banners/BannerBuild/BannerBuildEdit.jsx b/src/Pages/Banners/BannerBuild/BannerBuildEdit.jsx new file mode 100644 index 0000000..7429fb7 --- /dev/null +++ b/src/Pages/Banners/BannerBuild/BannerBuildEdit.jsx @@ -0,0 +1,10 @@ +import React from 'react' +import BannerEdit from '../../../Components/Banner/BannerEdit' + +const BannerBuildEdit = () => { + return ( + + ) +} + +export default BannerBuildEdit \ No newline at end of file diff --git a/src/Pages/Banners/BannerCommunity/BannerCommunity.jsx b/src/Pages/Banners/BannerCommunity/BannerCommunity.jsx index dbe8acb..3eb0dc2 100644 --- a/src/Pages/Banners/BannerCommunity/BannerCommunity.jsx +++ b/src/Pages/Banners/BannerCommunity/BannerCommunity.jsx @@ -11,11 +11,15 @@ const BannerCommunity = () => { const [deleteCommunityBanner] = useDeleteCommunityBannerMutation(); const [updateCommunityBannerStatus] = useUpdateCommunityBannerStatusMutation(); + + return ( { { +const BannerLearnAdd = () => { const [createLearnBannerData] = useCreateLearnBannerMutation(); return ( { ); }; -export default LearnBannerAdd; +export default BannerLearnAdd; diff --git a/src/Pages/Banners/BannerLearn/BannerLearnEdit.jsx b/src/Pages/Banners/BannerLearn/BannerLearnEdit.jsx new file mode 100644 index 0000000..f76bb11 --- /dev/null +++ b/src/Pages/Banners/BannerLearn/BannerLearnEdit.jsx @@ -0,0 +1,10 @@ +import React from 'react' +import BannerEdit from '../../../Components/Banner/BannerEdit' + +const BannerLearnEdit = () => { + return ( + + ) +} + +export default BannerLearnEdit \ No newline at end of file diff --git a/src/Pages/Events/ViewLearnBanner.jsx b/src/Pages/Banners/BannerLearn/BannerLearnView.jsx similarity index 58% rename from src/Pages/Events/ViewLearnBanner.jsx rename to src/Pages/Banners/BannerLearn/BannerLearnView.jsx index 55b7380..cbdc3a1 100644 --- a/src/Pages/Events/ViewLearnBanner.jsx +++ b/src/Pages/Banners/BannerLearn/BannerLearnView.jsx @@ -1,9 +1,9 @@ import React from "react"; import { useParams } from "react-router-dom"; -import { useGetLearnBannerByIdQuery } from "../../Services/api.service"; -import BannerView from "../../Components/Banner/BannerView"; +import { useGetLearnBannerByIdQuery } from "../../../Services/api.service"; +import BannerView from "../../../Components/Banner/BannerView"; -const ViewLearnBanner = () => { +const BannerLearnView = () => { const { id } = useParams(); console.log(id); const { data, error, isLoading } = useGetLearnBannerByIdQuery(id); @@ -12,4 +12,4 @@ const ViewLearnBanner = () => { return ; }; -export default ViewLearnBanner; +export default BannerLearnView; diff --git a/src/Pages/Banners/BannerNews/BannerNews.jsx b/src/Pages/Banners/BannerNews/BannerNews.jsx index 60a91d8..1f7039c 100644 --- a/src/Pages/Banners/BannerNews/BannerNews.jsx +++ b/src/Pages/Banners/BannerNews/BannerNews.jsx @@ -22,6 +22,8 @@ const BannerNews = () => { { +const BannerNewsAdd = () => { const [createNewsBannerData] = useCreateNewsBannerMutation(); return ( ); }; -export default NewsBannerAdd; +export default BannerNewsAdd; diff --git a/src/Pages/Banners/BannerNews/BannerNewsEdit.jsx b/src/Pages/Banners/BannerNews/BannerNewsEdit.jsx new file mode 100644 index 0000000..b81e162 --- /dev/null +++ b/src/Pages/Banners/BannerNews/BannerNewsEdit.jsx @@ -0,0 +1,10 @@ +import React from 'react' +import BannerEdit from '../../../Components/Banner/BannerEdit' + +const BannerNewsEdit = () => { + return ( + + ) +} + +export default BannerNewsEdit \ No newline at end of file diff --git a/src/Pages/Banners/BannerNews/BannerNewsView.jsx b/src/Pages/Banners/BannerNews/BannerNewsView.jsx new file mode 100644 index 0000000..1fe236d --- /dev/null +++ b/src/Pages/Banners/BannerNews/BannerNewsView.jsx @@ -0,0 +1,15 @@ +import React from "react"; +import { useParams } from "react-router-dom"; +import { useGetLearnBannerByIdQuery, useGetNewsBannerByIdQuery } from "../../../Services/api.service"; +import BannerView from "../../../Components/Banner/BannerView"; + +const BannerNewsView = () => { + const { id } = useParams(); + console.log(id); + const { data, error, isLoading } = useGetNewsBannerByIdQuery(id); + + + return ; +}; + +export default BannerNewsView; diff --git a/src/Pages/Banners/BannersNew/BannersNews.jsx b/src/Pages/Banners/BannersNew/BannersNews.jsx deleted file mode 100644 index 78a991e..0000000 --- a/src/Pages/Banners/BannersNew/BannersNews.jsx +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react' -import { useParams } from 'react-router-dom'; -import { useGetNewsBannerByIdQuery } from '../../../Services/api.service'; -import BannerView from '../../../Components/Banner/BannerView'; - -const BannersNews = () => { - const { id } = useParams(); - const { data, error, isLoading } = useGetNewsBannerByIdQuery(id); - - return ; -} - -export default BannersNews \ No newline at end of file diff --git a/src/Pages/Banners/HomeBanner/HomeBanner.jsx b/src/Pages/Banners/HomeBanner/HomeBanner.jsx new file mode 100644 index 0000000..83324fb --- /dev/null +++ b/src/Pages/Banners/HomeBanner/HomeBanner.jsx @@ -0,0 +1,39 @@ +import React from "react"; +import { + useDeleteBuildBannerMutation, + useDeleteHomeBannerMutation, + useDeleteLearnBannerMutation, + useDeleteNewsBannerMutation, + useGetBuildBannerQuery, + useGetHomeBannerQuery, + useGetLearnBannerQuery, + useGetNewsBannerQuery, + useUpdateBuildBannerStatusMutation, + useUpdateHomeBannerStatusMutation, + useUpdateLearnBannerStatusMutation, + useUpdateNewsBannerStatusMutation, +} from "../../../Services/api.service"; +import BannerTable from "../../../Components/Banner/BannerTable"; + +const HomeBanner = () => { + const homeBanner = useGetHomeBannerQuery(); + + + const [deleteHomeBanner] = useDeleteHomeBannerMutation(); + + const [updateHomeBuildStatus] = useUpdateHomeBannerStatusMutation(); + const { data, error, isLoading } = useUpdateNewsBannerStatusMutation(); + return ( + + ); +}; + +export default HomeBanner; diff --git a/src/Pages/Banners/HomeBanner/HomeBannerAdd.jsx b/src/Pages/Banners/HomeBanner/HomeBannerAdd.jsx new file mode 100644 index 0000000..d1513ec --- /dev/null +++ b/src/Pages/Banners/HomeBanner/HomeBannerAdd.jsx @@ -0,0 +1,15 @@ +import AddBanner from "../../../Components/Banner/AddBanner"; +import { useCreateHomeBannerMutation } from "../../../Services/api.service"; + +const HomeBannerAdd = () => { + const [createLearnBannerData] = useCreateHomeBannerMutation(); + return ( + + ); +}; + +export default HomeBannerAdd; diff --git a/src/Pages/Banners/HomeBanner/HomeBannerEdit.jsx b/src/Pages/Banners/HomeBanner/HomeBannerEdit.jsx new file mode 100644 index 0000000..6c59682 --- /dev/null +++ b/src/Pages/Banners/HomeBanner/HomeBannerEdit.jsx @@ -0,0 +1,10 @@ +import React from 'react' +import BannerEdit from '../../../Components/Banner/BannerEdit' + +const HomeBannerEdit = () => { + return ( + + ) +} + +export default HomeBannerEdit \ No newline at end of file diff --git a/src/Pages/Banners/HomeBanner/HomeBannerView.jsx b/src/Pages/Banners/HomeBanner/HomeBannerView.jsx new file mode 100644 index 0000000..27f9e24 --- /dev/null +++ b/src/Pages/Banners/HomeBanner/HomeBannerView.jsx @@ -0,0 +1,15 @@ +import React from "react"; +import { useParams } from "react-router-dom"; +import { useGetHomeBannerByIdQuery, useGetNewsBannerByIdQuery } from "../../../Services/api.service"; +import BannerView from "../../../Components/Banner/BannerView"; + +const HomeBannerView = () => { + const { id } = useParams(); + console.log(id); + const { data, error, isLoading } = useGetHomeBannerByIdQuery(id); + + + return ; +}; + +export default HomeBannerView; diff --git a/src/Pages/BlogsAndArticles/AddBlogsAndArticles.jsx b/src/Pages/BlogsAndArticles/AddBlogsAndArticles.jsx index 324c4f2..22e87ac 100644 --- a/src/Pages/BlogsAndArticles/AddBlogsAndArticles.jsx +++ b/src/Pages/BlogsAndArticles/AddBlogsAndArticles.jsx @@ -31,6 +31,7 @@ import ReactQuill from "react-quill"; import "react-quill/dist/quill.snow.css"; import ChipSelector from "../../Components/ChipSelector/ChipSelector"; import Header from "../../Components/Header"; +import ToastBox from "../../Components/ToastBox"; const AddBlogsAndArticles = () => { const toast = useToast(); @@ -94,9 +95,9 @@ const AddBlogsAndArticles = () => { if (response?.data?.statusCode === 201) { setIsLoading(false); toast({ - title: response?.data?.message, - status: "success", - isClosable: true, + render: () => ( + + ), }); reset(); navigate("/blogs-articles"); diff --git a/src/Pages/BlogsAndArticles/BlogsAndArticles.jsx b/src/Pages/BlogsAndArticles/BlogsAndArticles.jsx index 9443064..55d40bf 100644 --- a/src/Pages/BlogsAndArticles/BlogsAndArticles.jsx +++ b/src/Pages/BlogsAndArticles/BlogsAndArticles.jsx @@ -51,10 +51,16 @@ import { HiDotsVertical } from "react-icons/hi"; import { formatDate } from "../../Components/Functions/UTCConvertor"; import CustomAlertDialog from "../../Components/CustomAlertDialog"; import Header from "../../Components/Header"; +import ToastBox from "../../Components/ToastBox"; +import TabularView from "../../Components/TabularView/TabularView"; +import { TABLE_PAGINATION } from "../../Constants/Paginations"; const BlogsAndArticles = () => { // ====================================================[Hooks]=================================================================== const toast = useToast(); + const [pageSize, setPageSize] = useState(TABLE_PAGINATION?.size); + const [currentPage, setCurrentPage] = useState(1); + const [deleteAlert, setDeleteAlert] = useState(false); const [actionId, setActionId] = useState(null); const [deleteIsLoading, setDeleteIsLoading] = useState(false); @@ -99,9 +105,12 @@ const BlogsAndArticles = () => { if (response?.data?.statusCode === 201) { console.log("toasted"); toast({ - title: response?.data?.message, - status: "success", - isClosable: true, + render: () => ( + + ), }); } }) @@ -208,7 +217,7 @@ const BlogsAndArticles = () => { w={220} > {item?.tags?.map(({ id, tag }) => ( - + {tag} ))} @@ -257,79 +266,32 @@ const BlogsAndArticles = () => { }); return ( - - {/* ====================================================[ Top bar ]================================================================ */} - - {/* */} - -
- - - {/* - - Blogs - - */} - - setSearchTerm(e.target.value)} - /> - - - - - - - {/* ====================================================[ Table ]================================================================ */} - + - - {/* ====================================================[ Alert ]================================================================ */} setDeleteAlert(false)} isOpen={deleteAlert} alertHandler={() => handleDelete(actionId)} - message={"Are you sure you want to delete member?"} + message={"Are you sure you want to delete video?"} isLoading={deleteIsLoading} /> - + ); }; diff --git a/src/Pages/BlogsAndArticles/EditBlogsAndArticles.jsx b/src/Pages/BlogsAndArticles/EditBlogsAndArticles.jsx index 27dfe08..9326a44 100644 --- a/src/Pages/BlogsAndArticles/EditBlogsAndArticles.jsx +++ b/src/Pages/BlogsAndArticles/EditBlogsAndArticles.jsx @@ -134,9 +134,9 @@ const EditBlogsAndArticles = () => { if (response?.data?.statusCode === 201) { setIsLoading01(false); toast({ - title: response?.data?.message, - status: "success", - isClosable: true, + render: () => ( + + ), }); reset(); navigate("/blogs-articles"); diff --git a/src/Pages/Community/AddComunity.jsx b/src/Pages/Community/AddComunity.jsx index 1653546..a545dca 100644 --- a/src/Pages/Community/AddComunity.jsx +++ b/src/Pages/Community/AddComunity.jsx @@ -30,6 +30,7 @@ import { import { useNavigate } from "react-router-dom"; import Loader01 from "../../Components/Loaders/Loader01"; import Header from "../../Components/Header"; +import { CloseIcon } from "@chakra-ui/icons"; const AddComunity = () => { const toast = useToast(); @@ -38,6 +39,7 @@ const AddComunity = () => { const [createCommunityData] = useCreateCommunityMutation(); // Invoke the hook to get the mutation function const [isLoading, setIsLoading] = useState(false); const [selectedImage, setSelectedImage] = useState(fallbackImage); + const [imageData, setImageData] = useState(null); const { register, @@ -69,9 +71,9 @@ const AddComunity = () => { if (response?.data?.statusCode === 200) { setIsLoading(false); toast({ - title: response?.data?.message, - status: "success", - isClosable: true, + render: () => ( + + ), }); reset(); navigate("/community"); @@ -91,6 +93,7 @@ const AddComunity = () => { const handleImageChange = (e) => { const file = e.target.files[0]; + setImageData(file); if (file) { const reader = new FileReader(); reader.onloadend = () => { @@ -129,7 +132,10 @@ const AddComunity = () => { Below is the profile that will be displayed on the community page. - + { src={selectedImage} alt="Selected Image" /> + {selectedImage === fallbackImage || imageData === null ? ( + "" + ) : ( + + + {imageData?.name} + + {(imageData?.size / (1024 * 1024)).toFixed(2)} mb + + + setSelectedImage(fallbackImage)} className=" web-text-large link rounded-2 pointer p-1" as="span" > + + + )} diff --git a/src/Pages/Community/Community.jsx b/src/Pages/Community/Community.jsx index 0154eb1..7891471 100644 --- a/src/Pages/Community/Community.jsx +++ b/src/Pages/Community/Community.jsx @@ -55,6 +55,7 @@ import CommunityCardDisplay from "./CommunityCardDisplay"; import CommunityBannerCard from "./CommunityBannerCard"; import Header from "../../Components/Header"; import { TABLE_PAGINATION } from "../../Constants/Paginations"; +import ToastBox from "../../Components/ToastBox"; const Community = () => { // ====================================================[Hooks]=================================================================== @@ -71,11 +72,16 @@ const Community = () => { const [pageSize, setPageSize] = useState(TABLE_PAGINATION?.size); const [currentPage, setCurrentPage] = useState(1); + + const [displayRange, setDisplayRange] = useState({ start: TABLE_PAGINATION?.page, end: pageSize }); const community = useGetCommunityQuery({ page: currentPage, size: pageSize }); + + + const [deleteCommunity] = useDeleteCommunityMutation(); const [updateCommunityStatus] = useUpdateCommunityStatusMutation(); @@ -114,9 +120,9 @@ const Community = () => { if (response?.data?.statusCode === 201) { console.log("toasted"); toast({ - title: response?.data?.message, - status: "success", - isClosable: true, + render: () => ( + + ), }); } }) diff --git a/src/Pages/Events/Events.jsx b/src/Pages/Events/Events.jsx index ee00f6a..f392bb8 100644 --- a/src/Pages/Events/Events.jsx +++ b/src/Pages/Events/Events.jsx @@ -10,6 +10,7 @@ import { HiDotsVertical } from 'react-icons/hi'; import { Link as RouterLink } from "react-router-dom"; import { formatDate } from '../../Components/Functions/UTCConvertor'; import CustomAlertDialog from '../../Components/CustomAlertDialog'; +import ToastBox from '../../Components/ToastBox'; const Events = () => { // ====================================================[Hooks]=================================================================== @@ -38,13 +39,15 @@ const Events = () => { setDeleteIsLoading(true); await deleteEvents(id) .then((response) => { - // Handle the response here - console.log("Mutation response:", response?.data?.statusCode); - console.log("Mutation response:", response?.data?.message); if (response?.data?.statusCode === 201) { setDeleteIsLoading(false); setDeleteAlert(false); + toast({ + render: () => ( + + ), + }); } }) .catch((error) => { @@ -59,8 +62,6 @@ const Events = () => { }; const handleUpdateStatus = async (id) => { - console.log(id); - try { // Trigger the mutation @@ -68,11 +69,10 @@ const Events = () => { .then((response) => { console.log(response?.data); if (response?.data?.statusCode === 201) { - console.log("toasted"); toast({ - title: response?.data?.message, - status: "success", - isClosable: true, + render: () => ( + + ), }); } }) @@ -103,6 +103,7 @@ const Events = () => { updateDisplayRange(currentPage + 1); } }; + const updateDisplayRange = (page) => { const start = (page - 1) * pageSize + 1; const end = Math.min(start + pageSize - 1, events?.data?.data?.totalItems); @@ -192,10 +193,6 @@ const Events = () => { }; }) - - - - return ( { const [createNews] = useCreateNewsMutation(); // Invoke the hook to get the mutation function const [isLoading, setIsLoading] = useState(false); const [selectedImage, setSelectedImage] = useState(fallbackImage); + const [ imageData, setImageData ] = useState(null) + + + + const { register, @@ -75,18 +80,18 @@ const AddNews = () => { if (response?.data?.statusCode === 200) { setIsLoading(false); toast({ - title: response?.data?.message, - status: "success", - isClosable: true, + render: () => ( + + ), }); reset(); navigate("/news"); } else if (response?.data?.statusCode === 500) { setIsLoading(false); toast({ - title: response?.data?.message, - status: "success", - isClosable: true, + render: () => ( + + ), }); } }) @@ -105,6 +110,7 @@ const AddNews = () => { const handleImageChange = (e) => { const file = e.target.files[0]; + setImageData(file); if (file) { const reader = new FileReader(); reader.onloadend = () => { @@ -155,6 +161,16 @@ const AddNews = () => { src={selectedImage} alt="Selected Image" /> + {selectedImage === fallbackImage || imageData === null ? ( + "" + ) : ( + + {imageData?.name} + + {(imageData?.size / (1024 * 1024)).toFixed(2)} mb + + + )} */} diff --git a/src/Pages/Videos.jsx b/src/Pages/Videos.jsx index a03b36c..930ae90 100644 --- a/src/Pages/Videos.jsx +++ b/src/Pages/Videos.jsx @@ -1,19 +1,263 @@ -import { Box } from '@chakra-ui/react' -import { OPACITY_ON_LOAD } from '../Layout/animations' +import { + Box, + HStack, + Image, + Input, + Menu, + MenuButton, + MenuItem, + MenuList, + Portal, + Select, + Switch, + Text, + Tooltip, + useToast, +} from "@chakra-ui/react"; +import { TABLE_PAGINATION } from "../Constants/Paginations"; +import { + useDeleteVideosMutation, + useGetVideosQuery, + useUpdateVideosStatusMutation, +} from "../Services/api.service"; +import { useState } from "react"; +import Header from "../Components/Header"; +import { ChevronLeftIcon, ChevronRightIcon } from "@chakra-ui/icons"; +import DataTable from "../Components/DataTable/DataTable"; +import TabularView from "../Components/TabularView/TabularView"; +import { HiDotsVertical } from "react-icons/hi"; +import { Link } from "react-router-dom"; +import { formatDate } from "../Components/Functions/UTCConvertor"; +import CustomAlertDialog from "../Components/CustomAlertDialog"; +import ToastBox from "../Components/ToastBox"; const Videos = () => { - return ( - Videos - ) -} + const toast = useToast(); + const [pageSize, setPageSize] = useState(TABLE_PAGINATION?.size); + const [currentPage, setCurrentPage] = useState(1); + const [searchTerm, setSearchTerm] = useState(""); + const [statusFilter, setStatusFilter] = useState("all"); -export default Videos \ No newline at end of file + const [deleteAlert, setDeleteAlert] = useState(false); + const [actionId, setActionId] = useState(null); + const [deleteIsLoading, setDeleteIsLoading] = useState(false); + + const videos = useGetVideosQuery({ page: currentPage, size: pageSize }); + const [deleteVideos] = useDeleteVideosMutation(); + const [updateVideoStatus] = useUpdateVideosStatusMutation(); + + const filteredData = videos?.data?.data?.data?.rows?.filter((item) => { + // Filter by name (case insensitive) + const name = item.title; + const searchLower = searchTerm.toLowerCase(); + const nameMatches = name.toLowerCase().includes(searchLower); + + // Filter by status + const status = item.status; + + const statusMatches = + statusFilter === "all" || + (statusFilter === "active" && status === true) || + (statusFilter === "inactive" && status === false); + + return nameMatches && statusMatches; + }); + + // ====================================================[Table Setup]================================================================ + const tableHeadRow = [ + "Thumbnail", + "Title", + "Discription", + "Duration", + "Active", + "Created At", + ]; + + const extractedArray = filteredData?.map((item, index) => { + return { + Thumbnail: ( + Dan Abramov + ), + + Title: ( + + {item?.title} + + ), + Discription: ( + + + + {item?.description} + + + + ), + Duration: ( + + {item?.duration} min + + ), + Active: ( + handleUpdateStatus(item.id, item?.status)} + isChecked={item.status} + // disabled={item.status} + /> + ), + "Created At": ( + + + {formatDate(item?.createdAt)} + + + + + + + + + Edit + + + View + + { + setActionId(item.id); + setDeleteAlert(true); + }} + className="web-text-medium" + > + Delete + + + + + + ), + }; + }); + + // ====================================================[Functions]=================================================================== + const handleDelete = async (communityId) => { + try { + // Trigger the mutation + setDeleteIsLoading(true); + await deleteVideos(communityId) + .then((response) => { + // Handle the response here + console.log("Mutation response:", response?.data?.statusCode); + console.log("Mutation response:", response?.data?.message); + + if (response?.data?.statusCode === 201) { + setDeleteIsLoading(false); + setDeleteAlert(false); + toast({ + render: () => ( + + ), + }); + } + }) + .catch((error) => { + console.error("Error creating community:", error); + setDeleteIsLoading(false); + setDeleteAlert(false); + }); + } catch (error) { + // Handle errors + console.log("Error deleting community:", error); + } + }; + + + + + + const handleUpdateStatus = async (id) => { + try { + // Trigger the mutation + await updateVideoStatus({ id }) + .then((response) => { + if (response?.data?.statusCode === 201) { + toast({ + render: () => ( + + ), + }); + } + }) + .catch((error) => { + console.log(error); + }); + } catch (error) { + // Handle errors + console.error("Error updating community status:", error); + } + }; + + + + + + + + + return ( + <> + + setDeleteAlert(false)} + isOpen={deleteAlert} + alertHandler={() => handleDelete(actionId)} + message={"Are you sure you want to delete video?"} + isLoading={deleteIsLoading} + /> + + ); +}; + +export default Videos; + + + +// Event & Community Pending \ No newline at end of file diff --git a/src/Pages/Whitepapers.jsx b/src/Pages/Whitepapers.jsx deleted file mode 100644 index 7d9a7cd..0000000 --- a/src/Pages/Whitepapers.jsx +++ /dev/null @@ -1,18 +0,0 @@ -import { Box } from '@chakra-ui/react' -import { OPACITY_ON_LOAD } from '../Layout/animations' - -const Whitepapers = () => { - return ( - Whitepapers - ) -} - -export default Whitepapers \ No newline at end of file diff --git a/src/Pages/Whitepapers/AddWhitepapers.jsx b/src/Pages/Whitepapers/AddWhitepapers.jsx new file mode 100644 index 0000000..36fdf35 --- /dev/null +++ b/src/Pages/Whitepapers/AddWhitepapers.jsx @@ -0,0 +1,330 @@ +import { Box, Button, Divider, FormControl, FormHelperText, FormLabel, Heading, Image, Input, Stack, useToast } from '@chakra-ui/react' +import React, { useState } from 'react' +import { OPACITY_ON_LOAD } from '../../Layout/animations' +import Header from '../../Components/Header' +import { useNavigate } from 'react-router-dom' +import fallbackImage from "../../assets/ultp-fallback-img.webp"; +import { addWhitePapers } from '../../Validations/Validations' +import { TiWarning } from 'react-icons/ti' +import { yupResolver } from "@hookform/resolvers/yup"; +import { useForm } from "react-hook-form"; +import { motion } from 'framer-motion' +import Loader01 from '../../Components/Loaders/Loader01' +import { useCreateWhitepaperMutation } from '../../Services/api.service' +import ToastBox from '../../Components/ToastBox' + +const AddWhitepapers = () => { + const toast = useToast(); + const navigate = useNavigate(); + const [isLoading, setIsLoading] = useState(false); + const [selectedImage, setSelectedImage] = useState(fallbackImage); + const [ imageData, setImageData ] = useState(null) + + const [createWhitepaper] = useCreateWhitepaperMutation(); + + const { + register, + handleSubmit, + reset, + formState: { errors }, + } = useForm({ + resolver: yupResolver(addWhitePapers), + }); + + + + + const handleImageChange = (e) => { + const file = e.target.files[0]; + setImageData(file); + if (file) { + const reader = new FileReader(); + reader.onloadend = () => { + setSelectedImage(reader.result); + }; + reader.readAsDataURL(file); + } + }; + + const onSubmit = async (data) => { + try { + setIsLoading(true); + const formData = new FormData(); + formData.append("title", data.title); + if (data.image[0]) { + formData.append("image", data.image[0]); + } + if (data.document[0]) { + formData.append("document", data.document[0]); + } + // Trigger the mutation + createWhitepaper(formData) + .then((response) => { + // Handle the response here + + if (response?.data?.statusCode === 201) { + setIsLoading(false); + toast({ + render: () => ( + + ), + }); + reset(); + navigate("/whitepaper"); + } else if (response?.data?.statusCode === 500) { + setIsLoading(false); + toast({ + render: () => ( + + ), + }); + } + }) + .catch((error) => { + // Handle errors + console.error("Error creating community:", error); + setIsLoading(false); + // Handle error notification if needed + }); + } catch (error) { + // Handle errors + console.error("Error creating community:", error); + setIsLoading(false); + } + }; + + + return ( + + +
+ + + + + + Whitepaper Info + + + Select the platform for which you need to create this campaign. + + + + + + Whitepaper banner image + + + Below is the whitepaper banner image that will be whitepaper on the community page. + + + + Selected Image + {selectedImage === fallbackImage || imageData === null ? ( + "" + ) : ( + + {imageData?.name} + + {(imageData?.size / (1024 * 1024)).toFixed(2)} mb + + + )} + + + + +
+ + + + + Title + + + {errors.title && ( + + {errors.title.message} + + )} + + + + + + + + Document + + + {errors.document && ( + + {errors.document.message} + + )} + + + + + + + Banner image + + {/* */} + + + + + + + + Drop images here + + + or click to upload + + + + + + + + + {errors.image && ( + + {" "} + {errors.image.message} + + )} + + Maximum limit of image is 5mb. + + + + + + + + + + +
+ +
+ + ) +} + +export default AddWhitepapers \ No newline at end of file diff --git a/src/Pages/Whitepapers/EditWhitepaper.jsx b/src/Pages/Whitepapers/EditWhitepaper.jsx new file mode 100644 index 0000000..63b0bcf --- /dev/null +++ b/src/Pages/Whitepapers/EditWhitepaper.jsx @@ -0,0 +1,9 @@ +import React from 'react' + +const EditWhitepaper = () => { + return ( +
EditWhitepaper
+ ) +} + +export default EditWhitepaper \ No newline at end of file diff --git a/src/Pages/Whitepapers/ViewWhitePaper.jsx b/src/Pages/Whitepapers/ViewWhitePaper.jsx new file mode 100644 index 0000000..2ab0ebc --- /dev/null +++ b/src/Pages/Whitepapers/ViewWhitePaper.jsx @@ -0,0 +1,108 @@ +import React from "react"; +import { OPACITY_ON_LOAD } from "../../Layout/animations"; +import { Box, Divider, Image, Tag, Text, useToast } from "@chakra-ui/react"; +import { useNavigate, useParams } from "react-router-dom"; +import Header from "../../Components/Header"; +import { useGetWhitepaperByIdQuery } from "../../Services/api.service"; +import { AttachmentIcon } from "@chakra-ui/icons"; +import extractFilename from "../../Components/Functions/FileNameAlter"; +import FullscreenLoaders from "../../Components/Loaders/FullscreenLoaders"; + +const ViewWhitePaper = () => { + const { id } = useParams(); + const toast = useToast(); + const navigate = useNavigate(); + const { data, error, isLoading } = useGetWhitepaperByIdQuery(id); + const whitepaper = data?.data?.data; + console.log(whitepaper?.document); + + if (isLoading) { + return ; + } + + return ( + +
+ + + + + Whitepaper Info + + + Select the platform for which you need to create this campaign. + + + + + + Whitepaper banner image + + + Below is the profile that will be displayed on the community page. + + + + Selected Image + + + + + + + Status + + {whitepaper?.status ? ( + + Active + + ) : ( + + Inactive + + )} + + + + Title + {whitepaper?.title} + + + + + Document + {extractFilename(whitepaper?.document)} + + + + + + + + + + + + + ); +}; + +export default ViewWhitePaper; diff --git a/src/Pages/Whitepapers/Whitepapers.jsx b/src/Pages/Whitepapers/Whitepapers.jsx new file mode 100644 index 0000000..1e0d48f --- /dev/null +++ b/src/Pages/Whitepapers/Whitepapers.jsx @@ -0,0 +1,262 @@ +import { + Box, + Image, + Menu, + MenuButton, + MenuItem, + MenuList, + Portal, + Switch, + Text, + Tooltip, + useToast, +} from "@chakra-ui/react"; +import { OPACITY_ON_LOAD } from "../../Layout/animations"; +import { TABLE_PAGINATION } from "../../Constants/Paginations"; +import { + useDeleteWhitepaperMutation, + useGetWhitePaperQuery, + useUpdateWhitepaperStatusMutation, +} from "../../Services/api.service"; +import { useState } from "react"; +import TabularView from "../../Components/TabularView/TabularView"; +import CustomAlertDialog from "../../Components/CustomAlertDialog"; +import { HiDotsVertical } from "react-icons/hi"; +import { Link } from "react-router-dom"; +import { formatDate } from "../../Components/Functions/UTCConvertor"; +import ToastBox from "../../Components/ToastBox"; +import extractFilename from "../../Components/Functions/FileNameAlter"; + +const Whitepapers = () => { + const toast = useToast(); + const [pageSize, setPageSize] = useState(TABLE_PAGINATION?.size); + const [currentPage, setCurrentPage] = useState(1); + const [searchTerm, setSearchTerm] = useState(""); + const [statusFilter, setStatusFilter] = useState("all"); + + const [deleteAlert, setDeleteAlert] = useState(false); + const [actionId, setActionId] = useState(null); + const [actionStatus, setActionStatus] = useState(null); + const [deleteIsLoading, setDeleteIsLoading] = useState(false); + + const whitePaper = useGetWhitePaperQuery({ + page: currentPage, + size: pageSize, + }); + const [deleteWhitepaper] = useDeleteWhitepaperMutation(); + const [updateWhitepaperStatus] = useUpdateWhitepaperStatusMutation(); + + const filteredData = whitePaper?.data?.data?.data?.rows?.filter((item) => { + // Filter by name (case insensitive) + const name = item.title; + const searchLower = searchTerm.toLowerCase(); + const nameMatches = name.toLowerCase().includes(searchLower); + + // Filter by status + const status = item.status; + + const statusMatches = + statusFilter === "all" || + (statusFilter === "active" && status === true) || + (statusFilter === "inactive" && status === false); + + return nameMatches && statusMatches; + }); + + // ====================================================[Table Setup]================================================================ + const tableHeadRow = [ + "Banner image", + "Title", + "Document", + "Active", + "Created At", + ]; + + const extractedArray = filteredData?.map((item, index) => { + return { + "Banner image": ( + Dan Abramov + ), + + Title: ( + + {item?.title} + + ), + Document: ( + + + + {extractFilename(item?.document)} + + + + ), + Active: ( + handleUpdateStatus(item.id, item?.status)} + isChecked={item.status} + // disabled={item.status} + /> + ), + "Created At": ( + + + {formatDate(item?.createdAt)} + + + + + + + + + Edit + + + View + + { + setActionId(item.id); + setDeleteAlert(true); + setActionStatus(item.status); + }} + className="web-text-medium" + > + Delete + + + + + + ), + }; + }); + + // ====================================================[Functions]=================================================================== + const handleDelete = async (communityId, status) => { + if (status) { + return toast({ + render: () => ( + + ), + }); + } + + try { + // Trigger the mutation + setDeleteIsLoading(true); + await deleteWhitepaper(communityId) + .then((response) => { + // Handle the response here + console.log("Mutation response:", response?.data?.statusCode); + console.log("Mutation response:", response?.data?.message); + + if (response?.data?.statusCode === 201) { + setDeleteIsLoading(false); + setDeleteAlert(false); + toast({ + render: () => ( + + ), + }); + } + }) + .catch((error) => { + console.error("Error creating community:", error); + setDeleteIsLoading(false); + setDeleteAlert(false); + }); + } catch (error) { + // Handle errors + console.log("Error deleting community:", error); + } + }; + + const handleUpdateStatus = async (id) => { + try { + await updateWhitepaperStatus({ id }) + .then((response) => { + console.log(response?.data); + if (response?.data?.statusCode === 201) { + toast({ + render: () => ( + + ), + }); + + // whitePaper?.refetch() + } + }) + .catch((error) => { + console.log(error); + }); + } catch (error) { + // Handle errors + console.error("Error updating community status:", error); + } + }; + + + return ( + <> + + setDeleteAlert(false)} + isOpen={deleteAlert} + alertHandler={() => handleDelete(actionId)} + message={"Are you sure you want to delete video?"} + isLoading={deleteIsLoading} + /> + + ); +}; + +export default Whitepapers; + + + + + diff --git a/src/Routes/Routes.js b/src/Routes/Routes.js index ca953d2..516d33d 100644 --- a/src/Routes/Routes.js +++ b/src/Routes/Routes.js @@ -7,7 +7,7 @@ import ComunityViewPage from "../Pages/Community/ComunityViewPage"; import Events from "../Pages/Events/Events"; import Home from "../Pages/Banners/Banner"; import Videos from "../Pages/Videos"; -import Whitepapers from "../Pages/Whitepapers"; +import Whitepapers from "../Pages/Whitepapers/Whitepapers"; import BannerCommunity from "../Pages/Banners/BannerCommunity/BannerCommunity"; import BannerComunityEditPage from "../Pages/Banners/BannerCommunity/BannerCommunityEdit"; import BannerComunityViewPage from "../Pages/Banners/BannerCommunity/BannerCommunityView"; @@ -19,24 +19,44 @@ import ViewNews from "../Pages/News/ViewNews"; import ViewBlogsAndArticles from "../Pages/BlogsAndArticles/ViewBlogsAndArticles"; import EditBlogsAndArticles from "../Pages/BlogsAndArticles/EditBlogsAndArticles"; import BannerLearn from "../Pages/Banners/BannerLearn/BannerLearn"; -import AddLearnBanner from "../Pages/Banners/BannerLearn/LearnBannerAdd"; import HelpAndSupport from "../Pages/News/HelpAndSupport"; import AddEvents from "../Pages/Events/AddEvents"; -import ViewLearnBanner from "../Pages/Events/ViewLearnBanner"; +import ViewLearnBanner from "../Pages/Banners/BannerLearn/BannerLearnView"; import BannerBuildView from "../Pages/Banners/BannerBuild/BannerBuildView"; -import BannersNews from "../Pages/Banners/BannersNew/BannersNews"; import BannerBuild from "../Pages/Banners/BannerBuild/BannerBuild"; import BannerNews from "../Pages/Banners/BannerNews/BannerNews"; import BannerCommunityAdd from "../Pages/Banners/BannerCommunity/BannerCommunityAdd"; -import BuildBannerAdd from "../Pages/Banners/BannerBuild/BuildBannerAdd"; -import NewsBannerAdd from "../Pages/Banners/BannersNew/NewsBannerAdd"; +import BannerLearnAdd from "../Pages/Banners/BannerLearn/BannerLearnAdd"; +import BannerLearnEdit from "../Pages/Banners/BannerLearn/BannerLearnEdit"; +import BannerBuildAdd from "../Pages/Banners/BannerBuild/BannerBuildAdd"; +import BannerBuildEdit from "../Pages/Banners/BannerBuild/BannerBuildEdit"; +import BannerNewsEdit from "../Pages/Banners/BannerNews/BannerNewsEdit"; +import BannerNewsView from "../Pages/Banners/BannerNews/BannerNewsView"; +import HomeBanner from "../Pages/Banners/HomeBanner/HomeBanner"; +import BannerNewsAdd from "../Pages/Banners/BannerNews/BannerNewsAdd"; +import BannerHomeAdd from "../Pages/Banners/HomeBanner/HomeBannerAdd"; +import HomeBannerView from "../Pages/Banners/HomeBanner/HomeBannerView"; +import HomeBannerAdd from "../Pages/Banners/HomeBanner/HomeBannerAdd"; +import HomeBannerEdit from "../Pages/Banners/HomeBanner/HomeBannerEdit"; +import AddWhitepapers from "../Pages/Whitepapers/AddWhitepapers"; +import ViewWhitePaper from "../Pages/Whitepapers/ViewWhitePaper"; +import EditWhitepaper from "../Pages/Whitepapers/EditWhitepaper"; export const RouteLink = [ { path: "/", Component: Home }, { path: "/videos", Component: Videos }, - { path: "/whitepaper", Component: Whitepapers }, { path: "/help-and-support", Component: HelpAndSupport }, + + { path: "/whitepaper", Component: Whitepapers }, + { path: "whitepaper/add-whitepaper", Component: AddWhitepapers }, + { path: "whitepaper/view/:id", Component: ViewWhitePaper }, + { path: "whitepaper/edit/:id", Component: EditWhitepaper }, + + + + + { path: "/community", Component: Community }, { path: "community/view/:id", Component: ComunityViewPage }, { path: "community/edit/:id", Component: ComunityEditPage }, @@ -57,29 +77,28 @@ export const RouteLink = [ // =============[ learn banner ]================ { path: "banner/learn", Component: BannerLearn }, - { path: "banner/learn/add-banner", Component: AddLearnBanner }, + { path: "banner/learn/add-banner", Component: BannerLearnAdd }, { path: "banner/learn/view/:id", Component: ViewLearnBanner }, - { path: "banner/learn/edit/:id", Component: ViewLearnBanner }, + { path: "banner/learn/edit/:id", Component: BannerLearnEdit }, // =============[ build banner ]================ { path: "banner/build", Component: BannerBuild }, - { path: "banner/build/add-banner", Component: BuildBannerAdd }, + { path: "banner/build/add-banner", Component: BannerBuildAdd }, { path: "banner/build/view/:id", Component: BannerBuildView }, - { path: "banner/build/edit/:id", Component: BannerBuildView }, + { path: "banner/build/edit/:id", Component: BannerBuildEdit }, // =============[ news banner ]================ { path: "banner/news", Component: BannerNews }, - { path: "banner/news/add-banner", Component: NewsBannerAdd }, - { path: "banner/news/view/:id", Component: BannersNews }, - { path: "banner/news/edit/:id", Component: BannersNews }, - + { path: "banner/news/add-banner", Component: BannerNewsAdd }, + { path: "banner/news/view/:id", Component: BannerNewsView }, + { path: "banner/news/edit/:id", Component: BannerNewsEdit }, // =============[ home banner ]================ - { path: "banner/home", Component: BannerNews }, - { path: "banner/home/add-banner", Component: NewsBannerAdd }, - { path: "banner/home/view/:id", Component: BannersNews }, - { path: "banner/home/edit/:id", Component: BannersNews }, + { path: "banner/home", Component: HomeBanner }, + { path: "banner/home/add-banner", Component: HomeBannerAdd }, + { path: "banner/home/view/:id", Component: HomeBannerView }, + { path: "banner/home/edit/:id", Component: HomeBannerEdit }, // =============[ blog ]================ { path: "/blogs-articles", Component: BlogsAndArticles }, diff --git a/src/Services/api.service.js b/src/Services/api.service.js index ab53db5..318206a 100644 --- a/src/Services/api.service.js +++ b/src/Services/api.service.js @@ -28,6 +28,11 @@ export const rubixApi = createApi({ "getEventsBannerById", "getEventsBanner", "getEventsBannerById", + + "getVideos", + + + "getWhitePaper" ], endpoints: (builder) => ({ // ===============[ Community cards endpoints ]======================= @@ -327,6 +332,15 @@ export const rubixApi = createApi({ query: () => "/admin/home", providesTags: ["getHomeBanner"], }), + createHomeBanner: builder.mutation({ + query: (newBanner) => ({ + url: "/admin/home", + method: "POST", + body: newBanner, + }), + invalidatesTags: ["getHomeBanner"], + }), + getHomeBannerById: builder.query({ query: (id) => `/admin/home/${id}`, providesTags: ["getHomeBannerById"], @@ -345,6 +359,69 @@ export const rubixApi = createApi({ }), invalidatesTags: ["getHomeBanner"], }), + + + + + // ===============[ Videos endpoints ]======================= + getVideos: builder.query({ + query: ({ page, size }) => `/admin/video?page=${page}&size=${size}`, + providesTags: ["getVideos"], + }), + updateVideosStatus: builder.mutation({ + query: ({ id }) => ({ + url: `/admin/video/change-visibility/${id}`, + method: "POST", + }), + invalidatesTags: ["getVideos"], + }), + deleteVideos: builder.mutation({ + query: (id) => ({ + url: `/admin/video/${id}`, + method: "DELETE", + }), + invalidatesTags: ["getVideos"], + }), + + + // ===============[ White paper endpoints ]======================= + getWhitePaper: builder.query({ + query: ({ page, size }) => `/admin/whitepaper?page=${page}&size=${size}`, + providesTags: ["getWhitePaper"], + }), + updateWhitepaperStatus: builder.mutation({ + query: ({ id }) => ({ + url: `/admin/whitepaper/change-visibility/${id}`, + method: "POST", + }), + invalidatesTags: ["getWhitePaper"], + }), + deleteWhitepaper: builder.mutation({ + query: (id) => ({ + url: `/admin/whitepaper/${id}`, + method: "DELETE", + }), + invalidatesTags: ["getWhitePaper"], + }), + + createWhitepaper: builder.mutation({ + query: (newBanner) => ({ + url: "/admin/whitepaper", + method: "POST", + body: newBanner, + }), + invalidatesTags: ["getWhitePaper"], + }), + getWhitepaperById: builder.query({ + query: (id) => `/admin/whitepaper/${id}`, + providesTags: ["getWhitePaper"], + }), + + + + + + }), }); @@ -396,8 +473,29 @@ export const { useGetNewsByIdQuery, useUpdateNewsMutation, + useGetHomeBannerQuery, + useCreateHomeBannerMutation, + useDeleteHomeBannerMutation, + useUpdateHomeBannerStatusMutation, + useGetHomeBannerByIdQuery, + + + useGetEventsQuery, useCreateEventsMutation, useUpdateEventsStatusMutation, useDeleteEventsMutation, + + + useGetVideosQuery, + useDeleteVideosMutation, + useUpdateVideosStatusMutation, + + + + useGetWhitePaperQuery, + useUpdateWhitepaperStatusMutation, + useDeleteWhitepaperMutation, + useCreateWhitepaperMutation, + useGetWhitepaperByIdQuery, } = rubixApi; diff --git a/src/Validations/Validations.js b/src/Validations/Validations.js index 22bd520..8b3b3a9 100644 --- a/src/Validations/Validations.js +++ b/src/Validations/Validations.js @@ -10,7 +10,28 @@ export const addCommunitySchema = Yup.object().shape({ designation: Yup.string().required("Designation is required"), description: Yup.string().required("Description is required"), linkedin: Yup.string().required("Linked In link is required"), - profile_image: Yup.mixed().required("Display picture is required"), + profile_image: Yup.mixed() + .test("required", "You need to provide a file", (files) => { + // return file && file.size <-- u can use this if you don't want to allow empty files to be uploaded; + if (files) return true; + return false; + }) + .test( + "fileSize", + " The maximum size of profile picture is 15MB.", + (files) => { + //if u want to allow only certain file sizes + try { + if (files.length !== 0) { + return files[0].size <= 15000000; + } + return true; + } catch (error) { + return false; + } + } + ) + .optional(), }); export const schemaEdit = Yup.object().shape({ @@ -25,7 +46,28 @@ export const addCommunityBannerSchema = Yup.object().shape({ sub_heading: Yup.string().required("Designation is required"), CTO_button_title: Yup.string().required("Description is required"), CTO_button_link: Yup.string().required("Linked In link is required"), - banner_image: Yup.mixed().required("Display picture is required"), + banner_image: Yup.mixed() + .test("required", "You need to provide a file", (files) => { + // return file && file.size <-- u can use this if you don't want to allow empty files to be uploaded; + if (files) return true; + return false; + }) + .test( + "fileSize", + " The maximum size of profile picture is 15MB.", + (files) => { + //if u want to allow only certain file sizes + try { + if (files.length !== 0) { + return files[0].size <= 15000000; + } + return true; + } catch (error) { + return false; + } + } + ) + .optional(), }); export const editCommunityBannerSchema = Yup.object().shape({ @@ -49,7 +91,48 @@ export const addNews = Yup.object().shape({ release_date: Yup.date().required("Release date is required"), meta_description: Yup.string().required("Description is required"), content: Yup.string().required("Content is required"), - banner_image: Yup.mixed().required("Banner image is required"), + banner_image: Yup.mixed() + .test("required", "You need to provide a file", (files) => { + // return file && file.size <-- u can use this if you don't want to allow empty files to be uploaded; + if (files) return true; + return false; + }) + .test( + "fileSize", + " The maximum size of profile picture is 15MB.", + (files) => { + //if u want to allow only certain file sizes + try { + if (files.length !== 0) { + return files[0].size <= 15000000; + } + return true; + } catch (error) { + return false; + } + } + ) + .test("file_formate", "Image file has unsupported format.", (files) => { + // // console.log(files[0].type) + + const SUPPORTED_FORMATS = [ + "image/jpeg", + "image/png", + "image/gif", + "image/tiff", + "image/svg+xml", + ]; + try { + if (files.length !== 0) { + setPreviewImage(URL.createObjectURL(files[0])); + return files && SUPPORTED_FORMATS.includes(files[0].type); + } + return true; + } catch (error) { + return false; + } + }) + .optional(), }); export const editNews = Yup.object().shape({ @@ -57,12 +140,50 @@ export const editNews = Yup.object().shape({ release_date: Yup.date(), meta_description: Yup.string(), content: Yup.string(), - banner_image: Yup.mixed().required("Banner image is required"), + banner_image: Yup.mixed() + .test("required", "You need to provide a file", (files) => { + // return file && file.size <-- u can use this if you don't want to allow empty files to be uploaded; + if (files) return true; + return false; + }) + .test( + "fileSize", + " The maximum size of profile picture is 15MB.", + (files) => { + //if u want to allow only certain file sizes + try { + if (files.length !== 0) { + return files[0].size <= 15000000; + } + return true; + } catch (error) { + return false; + } + } + ) + .test("file_formate", "Image file has unsupported format.", (files) => { + // // console.log(files[0].type) + + const SUPPORTED_FORMATS = [ + "image/jpeg", + "image/png", + "image/gif", + "image/tiff", + "image/svg+xml", + ]; + try { + if (files.length !== 0) { + setPreviewImage(URL.createObjectURL(files[0])); + return files && SUPPORTED_FORMATS.includes(files[0].type); + } + return true; + } catch (error) { + return false; + } + }) + .optional(), }); - - - export const addEvents = Yup.object().shape({ title: Yup.string().required("title is required"), content: Yup.string().required("content is required"), @@ -71,13 +192,146 @@ export const addEvents = Yup.object().shape({ organizer_mobile_number: Yup.string().required("Org contact is required") .matches(/^[0-9]{10}$/, "Mobile number must be 10 digits"), organizer_email: Yup.string().required("Org email is required").email("Please enter valid email"), - banner_image: Yup.mixed().required("Banner image is required"), + banner_image: Yup.mixed() + .test("required", "You need to provide a file", (files) => { + // return file && file.size <-- u can use this if you don't want to allow empty files to be uploaded; + if (files) return true; + return false; + }) + .test( + "fileSize", + " The maximum size of profile picture is 15MB.", + (files) => { + //if u want to allow only certain file sizes + try { + if (files.length !== 0) { + return files[0].size <= 15000000; + } + return true; + } catch (error) { + return false; + } + } + ) + .test("file_formate", "Image file has unsupported format.", (files) => { + // // console.log(files[0].type) + + const SUPPORTED_FORMATS = [ + "image/jpeg", + "image/png", + "image/gif", + "image/tiff", + "image/svg+xml", + ]; + try { + if (files.length !== 0) { + setPreviewImage(URL.createObjectURL(files[0])); + return files && SUPPORTED_FORMATS.includes(files[0].type); + } + return true; + } catch (error) { + return false; + } + }) + .optional(), }); -// test("fileSize", "Image must be at least 2MB", (value) => { +export const addWhitePapers = Yup.object().shape({ + title: Yup.string().required("title is required"), + image: Yup.mixed() + .test("required", "You need to provide a file", (files) => { + // return file && file.size <-- u can use this if you don't want to allow empty files to be uploaded; + if (files) return true; + return false; + }) + .test( + "fileSize", + " The maximum size of profile picture is 15MB.", + (files) => { + //if u want to allow only certain file sizes + try { + if (files.length !== 0) { + return files[0].size <= 15000000; + } + return true; + } catch (error) { + return false; + } + } + ) + // .test("file_formate", "Image file has unsupported format.", (files) => { + // // // console.log(files[0].type) + + // const SUPPORTED_FORMATS = [ + // "image/jpeg", + // "image/jpg", + // "image/png", + // "image/gif", + // "image/tiff", + // "image/svg+xml", + // ]; + // try { + // if (files.length !== 0) { + // setPreviewImage(URL.createObjectURL(files[0])); + // return files && SUPPORTED_FORMATS.includes(files[0].type); + // } + // return true; + // } catch (error) { + // return false; + // } + // }) + .optional(), + document: Yup.mixed() + .test("required", "You need to provide a file", (files) => { + // return file && file.size <-- u can use this if you don't want to allow empty files to be uploaded; + if (files) return true; + return false; + }) + .test( + "fileSize", + " The maximum size of profile picture is 15MB.", + (files) => { + //if u want to allow only certain file sizes + try { + if (files.length !== 0) { + return files[0].size <= 15000000; + } + return true; + } catch (error) { + return false; + } + } + ).optional() + // .test("file_formate", "Image file has unsupported format.", (files) => { + // // // console.log(files[0].type) + + // const SUPPORTED_FORMATS = [ + // "image/jpeg", + // "image/png", + // "image/jpg", + // "image/gif", + // "image/tiff", + // "image/svg+xml", + // ]; + // try { + // if (files.length !== 0) { + // setPreviewImage(URL.createObjectURL(files[0])); + // return files && SUPPORTED_FORMATS.includes(files[0].type); + // } + // return true; + // } catch (error) { + // return false; + // } + // }) + , + +}); + + +// test("fileSize", "Image must be at least 15MB", (value) => { // if (!value) return true; // const fileSizeInBytes = value.size; // const fileSizeInMB = fileSizeInBytes / (1024 * 1024);