diff --git a/package-lock.json b/package-lock.json index 4d05ac0..ffac950 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,6 +25,7 @@ "react-router-dom": "^6.26.1", "react-scripts": "5.0.1", "react-toastify": "^10.0.5", + "sweetalert2": "^11.12.4", "web-vitals": "^2.1.4" } }, @@ -18652,6 +18653,16 @@ "boolbase": "~1.0.0" } }, + "node_modules/sweetalert2": { + "version": "11.12.4", + "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.12.4.tgz", + "integrity": "sha512-ZSpyaLbAmn4b7xjnV9x9BFD1UOrCAhIzm1D8dZ443kGxtVKqbTIA5SgXs4xeEtmFfEXUyC3RBgpSlu1AXmCiHA==", + "license": "MIT", + "funding": { + "type": "individual", + "url": "https://github.com/sponsors/limonte" + } + }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", diff --git a/package.json b/package.json index 2f32aa4..d97f494 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "hbaseapp", - "version": "0.1.0", + "name": "react-placeholder", + "version": "1.0.0", "private": true, "dependencies": { "@emotion/react": "^11.13.0", @@ -20,6 +20,7 @@ "react-router-dom": "^6.26.1", "react-scripts": "5.0.1", "react-toastify": "^10.0.5", + "sweetalert2": "^11.12.4", "web-vitals": "^2.1.4" }, "scripts": { diff --git a/public/favicon.ico b/public/favicon.ico deleted file mode 100644 index a11777c..0000000 Binary files a/public/favicon.ico and /dev/null differ diff --git a/public/index.html b/public/index.html index aa069f2..ec0b93c 100644 --- a/public/index.html +++ b/public/index.html @@ -7,37 +7,16 @@ - - - React App + + Humbingo React Placeholder
- + diff --git a/public/logo192.png b/public/logo192.png deleted file mode 100644 index fc44b0a..0000000 Binary files a/public/logo192.png and /dev/null differ diff --git a/public/logo512.png b/public/logo512.png deleted file mode 100644 index a4e47a6..0000000 Binary files a/public/logo512.png and /dev/null differ diff --git a/src/App.css b/src/App.css index 74b5e05..e69de29 100644 --- a/src/App.css +++ b/src/App.css @@ -1,38 +0,0 @@ -.App { - text-align: center; -} - -.App-logo { - height: 40vmin; - pointer-events: none; -} - -@media (prefers-reduced-motion: no-preference) { - .App-logo { - animation: App-logo-spin infinite 20s linear; - } -} - -.App-header { - background-color: #282c34; - min-height: 100vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: calc(10px + 2vmin); - color: white; -} - -.App-link { - color: #61dafb; -} - -@keyframes App-logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} diff --git a/src/App.js b/src/App.js index f93faa9..dfa9c29 100644 --- a/src/App.js +++ b/src/App.js @@ -1,25 +1,28 @@ import React from 'react'; -import LoginPage from './pages/UI/login/login'; import { BrowserRouter, Route, Routes } from 'react-router-dom'; -import { AuthProvider } from './auth/AuthContext'; -import { Auth } from './auth/auth'; -import Footer from './components/footer'; // Import the Footer component -import Home from './pages/UI/home/home'; + +import { AuthProvider } from './utils/auth/AuthContext'; +import { Auth } from './utils/auth/auth'; +import LoginPage from './components/pages/Login'; +import Home from './components/pages/Home'; +import APIManagerStarter from './components/pages/APIManagerStarter'; +import Footer from './components/common/Footer'; + + const App = () => { return ( -
} />} exact /> - - } />} exact /> + } />} exact /> + } />} exact /> -
+ ); }; diff --git a/src/App.test.js b/src/App.test.js deleted file mode 100644 index 1f03afe..0000000 --- a/src/App.test.js +++ /dev/null @@ -1,8 +0,0 @@ -import { render, screen } from '@testing-library/react'; -import App from './App'; - -test('renders learn react link', () => { - render(); - const linkElement = screen.getByText(/learn react/i); - expect(linkElement).toBeInTheDocument(); -}); diff --git a/src/api-manager/.gitignore b/src/api-manager/.gitignore deleted file mode 100644 index 4d29575..0000000 --- a/src/api-manager/.gitignore +++ /dev/null @@ -1,23 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - -# production -/build - -# misc -.DS_Store -.env.local -.env.development.local -.env.test.local -.env.production.local - -npm-debug.log* -yarn-debug.log* -yarn-error.log* diff --git a/src/api-manager/APIManager.js b/src/api-manager/APIManager.js deleted file mode 100644 index 789e6d5..0000000 --- a/src/api-manager/APIManager.js +++ /dev/null @@ -1,416 +0,0 @@ -import React, { useEffect, useState } from "react"; -import { useNavigate } from "react-router-dom"; -import { toast } from "react-toastify"; -import "react-toastify/dist/ReactToastify.css"; -import Swal from "sweetalert2"; -import "./style.css"; -import useAPIManager from "./useAPIManager"; -import { - Button, - Table, - TableBody, - TableCell, - TableContainer, - TableHead, - TableRow, - Paper, - Menu, - MenuItem, - Fade, - Card, - CardContent, -} from "@mui/material"; -import FormWithDrawer from "./FormWithDrawer"; -import MoreVertIcon from "@mui/icons-material/MoreVert"; -import Pagination from "./Pagination"; - -function APIManager(props) { - const dataSchema = props.data; - const { Get, Delete, Patch, getAPI, getHost } = useAPIManager( - props.globalConfig, - props.token - ); - const dataApi = getAPI(props.data.api); - const [apiData, setApiData] = useState([]); - const [searchQuery, setSearchQuery] = useState(""); - const [orderBy, setOrderBy] = useState(""); // Column to sort - const [order, setOrder] = useState("asc"); - const [page, setPage] = useState(0); - const [rowsPerPage, setRowsPerPage] = useState(50); - const [sortedColumn, setSortedColumn] = useState(null); - const [filteredData, setFilteredData] = useState([]); - const [anchorEls, setAnchorEls] = useState({}); // Updated state for menu anchors - const [mounted, setMounted] = useState(false); - const [nextPage, setNextPage] = useState(null); - const [previousPage, setPreviousPage] = useState(null); - const [totalCount, setTotalCount] = useState(0); - const [currentPage, setCurrentPage] = useState(1); - const [loading, setLoading] = useState(true); - - const updateFormTitle = props.updateFormTitle ? props.updateFormTitle : ""; - const createFormTitle = props.createFormTitle ? props.createFormTitle : ""; - const actionBtnName = props.actionBtnName - ? props.actionBtnName - : "Create New Data"; - const createRequired = props.createRequired === false ? false : true; - const editRequired = props.editRequired === false ? false : true; - const searchRequired = props.searchRequired === false ? false : true; - - const createField = dataSchema.createField; - const editField = dataSchema.editField; - const showField = dataSchema.showField; - const manageRecord = true; - - let navigate = useNavigate(); - const getData = async () => { - makeApiRequest(dataApi); - }; - - const makeApiRequest = async (api) => { - try { - setSearchQuery(""); - const result = await Get(api ? api : dataApi); - setNextPage(result.next); - setPreviousPage(result.previous); - setTotalCount(result.count); - setApiData(result.results); - setFilteredData(result.results); - } catch (err) { - if (err.code == "ERR_BAD_REQUEST") { - toast.error("Unauthorised access to page, Contact admin for access."); - navigate("/"); - } else { - toast.error(err.message); - } - } finally { - setLoading(false); - } - }; - - const pageChangeRequest = (url) => { - if (getPageUrl(url) != null) { - makeApiRequest(getHost() + getPageUrl(url)); - } - }; - - async function softDelete(data) { - try { - await Patch(dataApi, data["id"], { is_deleted: true }) - .then(() => { - toast.success("Record updated successfully!"); - getData(); - }) - .catch((err) => { - getData(); - toast.error(err || "Error"); - }); - } catch { - getData(); - toast.error("Something Went wrong contact Humbingo"); - } - } - - async function restore(data) { - try { - await Patch(dataApi, data["id"], { is_deleted: false }) - .then(() => { - toast.success("Record updated successfully!"); - getData(); - }) - .catch((err) => { - getData(); - toast.error(err || "Error"); - }); - } catch { - getData(); - toast.error("Something Went wrong contact Humbingo"); - } - } - - async function forceDelete(data) { - await Swal.fire({ - title: "Data will be removed permanently! Are you sure?", - icon: "warning", - showCancelButton: true, - confirmButtonColor: "#3085d6", - cancelButtonColor: "#d33", - confirmButtonText: "Yes, delete it!", - }).then(async (result) => { - if (result.isConfirmed) { - try { - await Delete(dataApi, data["id"]) - .then(() => { - toast.success("Record updated successfully!"); - getData(); - }) - .catch((err) => { - getData(); - toast.error(err || "Error"); - }); - } catch { - getData(); - toast.error("Something Went wrong contact Humbingo"); - } - } - }); - } - - const getValueFromUrl = (url, parameterName) => { - try { - const regex = new RegExp(`${parameterName}=([^&]+)`); - const match = url.match(regex); - return match ? match[1] : null; - } catch { - return null; - } - }; - - function getPageUrl(url) { - let urls = ""; - try { - const urlObject = new URL(url); - urls = urlObject.pathname + urlObject.search; - } catch { - return null; - } - return urls; - } - - useEffect(() => { - setMounted(true); - return () => { - setMounted(false); - }; - }, []); - - useEffect(() => { - if (loading && mounted) { - getData(); - } - }, [loading, mounted]); - - const handleSearchInputChange = (event) => { - const query = event.target.value; - makeApiRequest(dataApi + "?search=" + query); - setSearchQuery(query); - }; - - const handleSort = (columnKey) => { - const isAsc = orderBy === columnKey && order === "asc"; - setOrderBy(columnKey); - setOrder(isAsc ? "desc" : "asc"); - setSortedColumn(columnKey); - }; - - const sortedData = stableSort(filteredData, getComparator(order, orderBy)); - const visibleRows = sortedData.slice( - page * rowsPerPage, - page * rowsPerPage + rowsPerPage - ); - - function stableSort(array, comparator) { - const stabilizedThis = array.map((el, index) => [el, index]); - stabilizedThis.sort((a, b) => { - const order = comparator(a[0], b[0]); - if (order !== 0) return order; - return a[1] - b[1]; - }); - return stabilizedThis.map((el) => el[0]); - } - - function getComparator(order, orderBy) { - return order === "desc" - ? (a, b) => descendingComparator(a, b, orderBy) - : (a, b) => -descendingComparator(a, b, orderBy); - } - - function descendingComparator(a, b, orderBy) { - if (b[orderBy] < a[orderBy]) { - return -1; - } - if (b[orderBy] > a[orderBy]) { - return 1; - } - return 0; - } - - const handleMenuClick = (event, rowIndex) => { - setAnchorEls((prev) => ({ - ...prev, - [rowIndex]: event.currentTarget, - })); - }; - - const handleMenuClose = (rowIndex) => { - setAnchorEls((prev) => ({ - ...prev, - [rowIndex]: null, - })); - }; - - return ( - <> - {loading ? ( -
- Loading -
- ) : ( -
- - - {createRequired && ( - getData()} - buttonStyle={{ margin: "10px", backgroundColor: "#17202A" }} - /> - )} - {searchRequired && ( -
- -
- )} -
-
- - - - - {showField.map((th, index) => { - const isSorted = orderBy === th.key; - const isAsc = orderBy === th.key && order === "asc"; - return ( - handleSort(th.key)} - > - {th.label} {isSorted && (isAsc ? "▲" : "▼")} - - ); - })} - {manageRecord && ( - - Action - - )} - - - - {visibleRows.map((data, rowIndex) => ( - - {showField.map((field, i) => ( - {data[field.key]} - ))} - {manageRecord && ( - - {editRequired && ( - handleMenuClose(rowIndex)} - refreshData={() => getData()} - buttonStyle={{ fontSize: "12px", padding: "5px" }} - buttonVarient="outlined" - updateFormTitle={updateFormTitle} - submitBtnTitle="Update Data" - /> - )} - - - handleMenuClose(rowIndex)} - TransitionComponent={Fade} - > - {data.is_deleted ? ( - restore(data)}> - Show Record - - ) : ( - softDelete(data)}> - Hide Record - - )} - forceDelete(data)}> - Remove Record - - - - )} - - ))} - -
- -
-
- )} - - ); -} - -export default APIManager; diff --git a/src/api-manager/AutoCompleteField.js b/src/api-manager/AutoCompleteField.js deleted file mode 100644 index 26fe564..0000000 --- a/src/api-manager/AutoCompleteField.js +++ /dev/null @@ -1,109 +0,0 @@ -import React, { useEffect, useState } from "react"; -import TextField from "@mui/material/TextField"; -import Autocomplete from "@mui/material/Autocomplete"; -import useApi from "../useApi"; -import { toast } from "react-toastify"; - -const AutoCompleteField = (props) => { - const [api, setApi] = useState(props.api); - const searchOptionHook = props.searchOptionHook; - const fieldLabel = props.label; - const fieldName = props.name; - const optionKey = props.optionKey ? props.optionKey : "id"; - const [searchData, setSearchData] = useState([]); - const [storageData, setStorageData] = useState( - JSON.parse(localStorage.getItem("dynamicField")) - ); - const [value, setValue] = useState(""); - const { Get } = useApi(); - const [tempValue, setTempValue] = useState( - storageData - ? storageData[storageData.findIndex((item) => item.name === fieldName)] - : "" - ); - - let newApi = async () => { - let tempApi = api; - if (props.hook != undefined) { - tempApi = `${tempApi}${ - storageData[storageData.findIndex((item) => item.name === props.hook)] - .key - }/`; - } - return tempApi; - }; - - let getdata = async () => { - try{ - const tempApi = await newApi(); - let response = await Get(tempApi); - let _searchData = []; - await response.data.map((data) => { - _searchData.push({ - label: data[searchOptionHook], - key: data[optionKey], - }); - }); - setSearchData(_searchData); - }catch{ - toast.error("Something went wrong contact humbingo.") - } - // await axios - // .get(tempApi) - // .then(async (response) => { - // let _searchData = []; - // await response.data.map((data) => { - // _searchData.push({ - // label: data[searchOptionHook], - // key: data[optionKey], - // }); - // }); - - // setSearchData(_searchData); - // }) - // .catch((error) => { - // console.error(error); - // }); - }; - useEffect(() => { - getdata(); - }, []); - - let getDataFromJson = (e) => { - const acccess = e.target.value; - let respData = searchData.find((f) => f.label === acccess); - - respData ? setValue(respData.key) : console.log("this is undefined"); - if (props.onBlur != undefined) { - if (respData != undefined) { - props.onBlur(respData); - } - } - }; - - return searchData.length > 0 ? ( - <> -
-
- getDataFromJson(e)} - value={tempValue} - renderInput={(params) => ( - - )} - /> - {/* onSelect={(e) => getDataFromJson(e)} */} -
-
- - - ) : ( - "" - ); -}; - -export default AutoCompleteField; diff --git a/src/api-manager/CrudManager.js b/src/api-manager/CrudManager.js deleted file mode 100644 index 1cb342b..0000000 --- a/src/api-manager/CrudManager.js +++ /dev/null @@ -1,416 +0,0 @@ -import React, { useEffect, useState } from "react"; -import { useNavigate } from "react-router-dom"; -import { toast } from "react-toastify"; -import "react-toastify/dist/ReactToastify.css"; -import Swal from "sweetalert2"; -import "./style.css"; -import useAPIManager from "./useAPIManager"; -import { - Button, - Table, - TableBody, - TableCell, - TableContainer, - TableHead, - TableRow, - Paper, - Menu, - MenuItem, - Fade, - Card, - CardContent, -} from "@mui/material"; -import FormWithDrawer from "./FormWithDrawer"; -import MoreVertIcon from "@mui/icons-material/MoreVert"; -import Pagination from "./Pagination"; - -function CrudManager(props) { - const dataSchema = props.data; - const { Get, Delete, Patch, getAPI, getHost } = useAPIManager( - props.globalConfig, - props.token - ); - const dataApi = getAPI(props.data.api); - const [apiData, setApiData] = useState([]); - const [searchQuery, setSearchQuery] = useState(""); - const [orderBy, setOrderBy] = useState(""); // Column to sort - const [order, setOrder] = useState("asc"); - const [page, setPage] = useState(0); - const [rowsPerPage, setRowsPerPage] = useState(50); - const [sortedColumn, setSortedColumn] = useState(null); - const [filteredData, setFilteredData] = useState([]); - const [anchorEls, setAnchorEls] = useState({}); // Updated state for menu anchors - const [mounted, setMounted] = useState(false); - const [nextPage, setNextPage] = useState(null); - const [previousPage, setPreviousPage] = useState(null); - const [totalCount, setTotalCount] = useState(0); - const [currentPage, setCurrentPage] = useState(1); - const [loading, setLoading] = useState(true); - - const updateFormTitle = props.updateFormTitle ? props.updateFormTitle : ""; - const createFormTitle = props.createFormTitle ? props.createFormTitle : ""; - const actionBtnName = props.actionBtnName - ? props.actionBtnName - : "Create New Data"; - const createRequired = props.createRequired === false ? false : true; - const editRequired = props.editRequired === false ? false : true; - const searchRequired = props.searchRequired === false ? false : true; - - const createField = dataSchema.createField; - const editField = dataSchema.editField; - const showField = dataSchema.showField; - const manageRecord = true; - - let navigate = useNavigate(); - const getData = async () => { - makeApiRequest(dataApi); - }; - - const makeApiRequest = async (api) => { - try { - setSearchQuery(""); - const result = await Get(api ? api : dataApi); - setNextPage(result.next); - setPreviousPage(result.previous); - setTotalCount(result.count); - setApiData(result.results); - setFilteredData(result.results); - } catch (err) { - if (err.code == "ERR_BAD_REQUEST") { - toast.error("Unauthorised access to page, Contact admin for access."); - navigate("/"); - } else { - toast.error(err.message); - } - } finally { - setLoading(false); - } - }; - - const pageChangeRequest = (url) => { - if (getPageUrl(url) != null) { - makeApiRequest(getHost() + getPageUrl(url)); - } - }; - - async function softDelete(data) { - try { - await Patch(dataApi, data["id"], { is_deleted: true }) - .then(() => { - toast.success("Record updated successfully!"); - getData(); - }) - .catch((err) => { - getData(); - toast.error(err || "Error"); - }); - } catch { - getData(); - toast.error("Something Went wrong contact Humbingo"); - } - } - - async function restore(data) { - try { - await Patch(dataApi, data["id"], { is_deleted: false }) - .then(() => { - toast.success("Record updated successfully!"); - getData(); - }) - .catch((err) => { - getData(); - toast.error(err || "Error"); - }); - } catch { - getData(); - toast.error("Something Went wrong contact Humbingo"); - } - } - - async function forceDelete(data) { - await Swal.fire({ - title: "Data will be removed permanently! Are you sure?", - icon: "warning", - showCancelButton: true, - confirmButtonColor: "#3085d6", - cancelButtonColor: "#d33", - confirmButtonText: "Yes, delete it!", - }).then(async (result) => { - if (result.isConfirmed) { - try { - await Delete(dataApi, data["id"]) - .then(() => { - toast.success("Record updated successfully!"); - getData(); - }) - .catch((err) => { - getData(); - toast.error(err || "Error"); - }); - } catch { - getData(); - toast.error("Something Went wrong contact Humbingo"); - } - } - }); - } - - const getValueFromUrl = (url, parameterName) => { - try { - const regex = new RegExp(`${parameterName}=([^&]+)`); - const match = url.match(regex); - return match ? match[1] : null; - } catch { - return null; - } - }; - - function getPageUrl(url) { - let urls = ""; - try { - const urlObject = new URL(url); - urls = urlObject.pathname + urlObject.search; - } catch { - return null; - } - return urls; - } - - useEffect(() => { - setMounted(true); - return () => { - setMounted(false); - }; - }, []); - - useEffect(() => { - if (loading && mounted) { - getData(); - } - }, [loading, mounted]); - - const handleSearchInputChange = (event) => { - const query = event.target.value; - makeApiRequest(dataApi + "?search=" + query); - setSearchQuery(query); - }; - - const handleSort = (columnKey) => { - const isAsc = orderBy === columnKey && order === "asc"; - setOrderBy(columnKey); - setOrder(isAsc ? "desc" : "asc"); - setSortedColumn(columnKey); - }; - - const sortedData = stableSort(filteredData, getComparator(order, orderBy)); - const visibleRows = sortedData.slice( - page * rowsPerPage, - page * rowsPerPage + rowsPerPage - ); - - function stableSort(array, comparator) { - const stabilizedThis = array.map((el, index) => [el, index]); - stabilizedThis.sort((a, b) => { - const order = comparator(a[0], b[0]); - if (order !== 0) return order; - return a[1] - b[1]; - }); - return stabilizedThis.map((el) => el[0]); - } - - function getComparator(order, orderBy) { - return order === "desc" - ? (a, b) => descendingComparator(a, b, orderBy) - : (a, b) => -descendingComparator(a, b, orderBy); - } - - function descendingComparator(a, b, orderBy) { - if (b[orderBy] < a[orderBy]) { - return -1; - } - if (b[orderBy] > a[orderBy]) { - return 1; - } - return 0; - } - - const handleMenuClick = (event, rowIndex) => { - setAnchorEls((prev) => ({ - ...prev, - [rowIndex]: event.currentTarget, - })); - }; - - const handleMenuClose = (rowIndex) => { - setAnchorEls((prev) => ({ - ...prev, - [rowIndex]: null, - })); - }; - - return ( - <> - {loading ? ( -
- Loading -
- ) : ( -
- - - {createRequired && ( - getData()} - buttonStyle={{ margin: "10px", backgroundColor: "#17202A" }} - /> - )} - {searchRequired && ( -
- -
- )} -
-
- - - - - {showField.map((th, index) => { - const isSorted = orderBy === th.key; - const isAsc = orderBy === th.key && order === "asc"; - return ( - handleSort(th.key)} - > - {th.label} {isSorted && (isAsc ? "▲" : "▼")} - - ); - })} - {manageRecord && ( - - Action - - )} - - - - {visibleRows.map((data, rowIndex) => ( - - {showField.map((field, i) => ( - {data[field.key]} - ))} - {manageRecord && ( - - {editRequired && ( - handleMenuClose(rowIndex)} - refreshData={() => getData()} - buttonStyle={{ fontSize: "12px", padding: "5px" }} - buttonVarient="outlined" - updateFormTitle={updateFormTitle} - submitBtnTitle="Update Data" - /> - )} - - - handleMenuClose(rowIndex)} - TransitionComponent={Fade} - > - {data.is_deleted ? ( - restore(data)}> - Show Record - - ) : ( - softDelete(data)}> - Hide Record - - )} - forceDelete(data)}> - Remove Record - - - - )} - - ))} - -
- -
-
- )} - - ); -} - -export default CrudManager; diff --git a/src/api-manager/DynamicForm/Autocomplete.js b/src/api-manager/DynamicForm/Autocomplete.js deleted file mode 100644 index 314eb0c..0000000 --- a/src/api-manager/DynamicForm/Autocomplete.js +++ /dev/null @@ -1,87 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import PropTypes from 'prop-types'; - -import TextField from "@mui/material/TextField"; -import Autocomplete from "@mui/material/Autocomplete"; -import CircularProgress from '@mui/material/CircularProgress'; -import axios from 'axios'; - - -const CustomAutocomplete = ({ apiUrl, displayKey, valueKey, onValueChange, inputName, variant , label, sameAsSeen}) => { - - const [options, setOptions] = useState([]); - const [loading, setLoading] = useState(false); - const [inputValue, setInputValue] = useState(''); - const [selectedOption, setSelectedOption] = useState(null); - - useEffect(() => { - setLoading(true); - axios.get(apiUrl) - .then(response => { - setOptions(response.data); - }) - .catch(error => { - console.error('Error fetching data:', error); - }) - .finally(() => { - setLoading(false); - }); - }, [apiUrl]); - - const handleInputChange = (event, newValue) => { - setInputValue(newValue); - }; - - const handleOptionSelect = (event, newValue) => { - // console.log("Selected value:"); - // console.log(newValue); - setSelectedOption(newValue); - setInputValue(newValue ? newValue[displayKey] : ''); - onValueChange(newValue, inputName); // Pass the name attribute value along with the value - }; - - return ( - <> - option ? option[displayKey] : ''} - renderInput={(params) => ( - - {loading ? : null} - {params.InputProps.endAdornment} - - ), - }} - /> - - )} - - /> - - {(sameAsSeen)?:""} - - - ); -}; - -CustomAutocomplete.propTypes = { - apiUrl: PropTypes.string.isRequired, - displayKey: PropTypes.string.isRequired, - valueKey: PropTypes.string.isRequired, - onValueChange: PropTypes.func.isRequired, - inputName: PropTypes.string.isRequired, // Accept inputName prop -}; - -export default CustomAutocomplete; diff --git a/src/api-manager/DynamicForm/DynamicAutocomplete.js b/src/api-manager/DynamicForm/DynamicAutocomplete.js deleted file mode 100644 index f5456c7..0000000 --- a/src/api-manager/DynamicForm/DynamicAutocomplete.js +++ /dev/null @@ -1,112 +0,0 @@ -import React, { useState } from 'react'; -import CustomAutocomplete from './Autocomplete'; -import _Autocomplete from './_Autocomplete'; -const DynamicAutocomplete = (props) => { - // [ - // { - // "apiUrl": 'https://api.udaymotors.in/api/v1/user/', - // "displayKey": 'phone_no', - // "valueKey": 'id', - // "name": "user", - // "label":"User" - // }, - // { - // "apiUrl": 'https://api.udaymotors.in/api/v1/getInvestmentsByUserId/', - // "displayKey": 'investment_id', - // "valueKey": 'id', - // "name": "investment", - // "parent": "user", - // "parent_value_key": "id", - // "label":"Investments" - // }, - // { - // "apiUrl": 'https://api.udaymotors.in/api/v1/transaction/', - // "displayKey": 'description', - // "name": "transaction", - // "valueKey": 'id', - // "parent": "investment", - // "parent_value_key": "user_id", - // "label":"Transactions" - // }, - // ] - const [selectedValues, setSelectedValues] = useState([]); - const [currentFieldIndex, setCurrentFieldIndex] = useState(0); - const [fields, setFields] = useState(props.fields); - - const handleValueChange = (value, name) => { - const updatedValues = [...selectedValues]; - const existingIndex = updatedValues.findIndex(item => item.name === name); - if (existingIndex !== -1) { - updatedValues[existingIndex] = { value, name }; - } else { - updatedValues.push({ value, name }); - } - - setSelectedValues(updatedValues); - - // Update the API URL of the next field - const nextFieldIndex = currentFieldIndex + 1; - if (nextFieldIndex < fields.length) { - const nextField = fields[nextFieldIndex]; - const parentValue = updatedValues.find(item => item.name === nextField.parent)?.value[nextField.parent_value_key]; - if (parentValue) { - const updatedFields = [...fields]; - updatedFields[nextFieldIndex] = { - ...nextField, - apiUrl: `${nextField.apiUrl}${parentValue}/` - }; - setFields(updatedFields); - } - } - - setCurrentFieldIndex(nextFieldIndex); - }; - - const handleParentValueChange = (parentName, parentValue) => { - // Find the index of the parent field - const parentFieldIndex = fields.findIndex(field => field.name === parentName); - - // Reset the selected values and fields configurations for the subsequent fields - setSelectedValues(selectedValues.slice(0, parentFieldIndex + 1)); - setFields(fields.slice(0, parentFieldIndex + 1)); - setCurrentFieldIndex(parentFieldIndex); - }; - - return ( - fields.slice(0, currentFieldIndex + 1).map((field, index) => ( -
- { - (field.advance)? - <_Autocomplete - apiUrl={field.apiUrl} - displayKey={field.displayKey} - valueKey={field.valueKey} - inputName={field.name} - onValueChange={handleValueChange} - onParentValueChange={handleParentValueChange} - variant={field.variant} - label={field.label} - sameAsSeen={field.sameAsSeen} - - defaultObj={(field.defaultObj)?field.defaultObj:""} - /> - - : - } - -
- )) - ); -} - -export default DynamicAutocomplete; diff --git a/src/api-manager/DynamicForm/_Autocomplete.js b/src/api-manager/DynamicForm/_Autocomplete.js deleted file mode 100644 index 1db8203..0000000 --- a/src/api-manager/DynamicForm/_Autocomplete.js +++ /dev/null @@ -1,109 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import PropTypes from 'prop-types'; - -import TextField from "@mui/material/TextField"; -import Autocomplete from "@mui/material/Autocomplete"; -import CircularProgress from '@mui/material/CircularProgress'; -import useAPIManager from '../useAPIManager'; - - -const _Autocomplete = (props) => { - const { - apiUrl, - displayKey, - valueKey, - onValueChange, - inputName, - variant, - label, - sameAsSeen, - defaultObj, - onBlur, - onFocus, - options: propOptions - } = props; - - - const [options, setOptions] = useState(propOptions || []); - const [loading, setLoading] = useState(false); - const [inputValue, setInputValue] = useState(''); - const [selectedOption, setSelectedOption] = useState(defaultObj); - const {Get, Post} =useAPIManager(props.globalConfig, props.token); - useEffect(() => { - setLoading(true); - getSearchData(apiUrl) - }, [apiUrl]); - - const handleInputChange = (event, newValue) => { - getSearchData(apiUrl+"?search="+newValue) - setInputValue(newValue); - }; - - const getSearchData = async (api) =>{ - await Get(api) - .then(response => { - (response.results)?setOptions(response.results):setOptions(response) - - }) - .catch(error => { - console.error('Error fetching data:', error); - }) - .finally(() => { - setLoading(false); - }); - } - - const handleOptionSelect = (event, newValue) => { - setSelectedOption(newValue); - setInputValue(newValue ? newValue[displayKey] : ''); - onValueChange(newValue, inputName); // Pass the name attribute value along with the value - }; - - return ( - <> - option ? option[displayKey] : ''} - defaultValue= { defaultObj} - renderInput={(params) => ( - - {loading ? : null} - {params.InputProps.endAdornment} - - ), - }} - /> - - )} - - /> - {/* {console.log(selectedOption)} */} - - {(sameAsSeen)?:""} - - - ); -}; - -_Autocomplete.propTypes = { - apiUrl: PropTypes.string.isRequired, - displayKey: PropTypes.string.isRequired, - valueKey: PropTypes.string.isRequired, - onValueChange: PropTypes.func.isRequired, - inputName: PropTypes.string.isRequired, // Accept inputName prop -}; - -export default _Autocomplete; diff --git a/src/api-manager/EditRow.js b/src/api-manager/EditRow.js deleted file mode 100644 index d5d36ee..0000000 --- a/src/api-manager/EditRow.js +++ /dev/null @@ -1,84 +0,0 @@ -import React, { useState } from "react"; -import Drawer from "@mui/material/Drawer"; -import { Button, TextField } from "@mui/material"; -import { firstUpperCase } from "./helper.js"; -function EditRow(props) { - const editBlock = props.editBlock ? props.editBlock : []; - const [state, setState] = React.useState({ - top: false, - left: false, - bottom: false, - right: false, - }); - const toggleDrawer = (anchor, open) => (event) => { - if ( - event.type === "keydown" && - (event.key === "Tab" || event.key === "Shift") - ) { - return; - } - setState({ ...state, [anchor]: open }); - }; - const [formFields, setFormFields] = useState(props.data); - var fields = Object.keys(formFields); - const handleSubmit = (e) => { - e.preventDefault(); - }; - function doChange(fieldName, value) { - setFormFields((prevData) => ({ - ...prevData, - [fieldName]: value, - })); - localStorage.setItem(props.data.id + "_" + fieldName, value); - } - - return ( - <> - {/* {formFields} */} - {["right"].map((anchor) => ( - - - -
-
-

Edit Details

-
- {fields.map((field, index) => { - return ( -
- {!Object.values(editBlock).includes(field) ? ( - <> - {" "} - doChange(field, e.target.value)} - label={firstUpperCase(field)} - /> -
{" "} - - ) : ( - "" - )} -
- ); - })} - - -
-
-
-
-
- ))} - - ); -} -export default EditRow; diff --git a/src/api-manager/Example.js b/src/api-manager/Example.js deleted file mode 100644 index 4179693..0000000 --- a/src/api-manager/Example.js +++ /dev/null @@ -1,17 +0,0 @@ -import React from 'react' -import CrudManager from './CrudManager' -import schema from './example.json' - -const CrudManagerExample = () => { - - return ( - - <> - - {/* // */} - - - ) -} - -export default CrudManagerExample \ No newline at end of file diff --git a/src/api-manager/Form.js b/src/api-manager/Form.js deleted file mode 100644 index 747b59d..0000000 --- a/src/api-manager/Form.js +++ /dev/null @@ -1,148 +0,0 @@ -import React,{useState} from "react"; -import { Button } from "@mui/material"; -import FormField, { validateField } from "./FormField"; -import "./style.css"; -import { toast } from "react-toastify"; -import useAPIManager from "./useAPIManager"; - -const Form = (props) => { - const inputFields = props.inputFields; - const fieldDefault = props.data ? props.data : []; - const submitBtnTitle = props.submitBtnTitle ? props.submitBtnTitle : "Submit"; - const [externalErrors, setExternalErrors] = useState({}); - - const { Get, Delete, Patch, Post, getHost } = useAPIManager( - props.globalConfig, - props.token - ); - - async function handleSubmit(e) { - e.preventDefault(); - let isFormValid = true; - const newExternalErrors = {}; - inputFields.forEach((field) => { - const fieldName = field.name; - const value = e.target.elements[fieldName].value; - const validationError = validateField(value, field.type, field.label); - - - if (field.required) { // Check if the field is required - const validationError = validateField(value, field.type, field.label); - if (validationError) { - newExternalErrors[fieldName] = validationError; - toast.error(validationError); - isFormValid = false; - } - } - }); - - setExternalErrors(newExternalErrors); - - if (!isFormValid) { - return; // Don't submit if form is invalid - } - - var data = new FormData(e.target); - let formData = Object.fromEntries(data.entries()); - // console.log(formData); - - if (fieldDefault["id"]) { - - try{ - await Patch(props.api,fieldDefault["id"], formData).then(()=>{ - props.closeDrawer(); - props.refreshData(); - toast.success("Record updated successfully!"); - }) - .catch((err) => { - // console.error(err); - toast.error(err || "Error"); - }); - }catch{ - toast.error("Something Went wrong contact Humbingo"); - } - - // axios - // .patch(props.api + `${fieldDefault["id"]}` + "/", formData) - // .then((response) => { - // props.closeDrawer(); - // props.refreshData(); - // toast.success("Record updated successfully!"); - // }) - // .catch((err) => { - // // console.error(err); - // toast.error(err.response?.data?.error || "An error occurred"); - // }); - } else { - - - try{ - await Post(props.api, formData).then(()=>{ - props.closeDrawer(); - props.refreshData(); - - toast.success("Record created successfully!"); - }) - .catch((err) => { - // console.error(err); - toast.error(err.response?.data?.error || "Error"); - }); - }catch{ - toast.error("Something Went wrong contact Humbingo"); - } - // axios - // .post(props.api, formData) - // .then((response) => { - // props.closeDrawer(); - // props.refreshData(); - - // toast.success("Record created successfully!"); - // }) - // .catch((err) => { - // // console.error(err); - // toast.error(err.response?.data?.error || "An error occurred"); - // }); - } - } - return ( -
- {inputFields.map((field, index) => { - const fieldName = field["name"]; - if (props.grid) { - return ( -
-
- -
-
- ); - } else { - return ( -
- -
- ); - } - })} -
- -
- ); -}; -export default Form; diff --git a/src/api-manager/FormField.js b/src/api-manager/FormField.js deleted file mode 100644 index be7eaef..0000000 --- a/src/api-manager/FormField.js +++ /dev/null @@ -1,314 +0,0 @@ -import React, { useEffect, useState } from "react"; -import { TextField, FormHelperText } from "@mui/material"; -import { firstUpperCase ,validateEmail,validatePassword} from "./helper.js"; -import "./style.css"; -import FormControlLabel from "@mui/material/FormControlLabel"; -import Checkbox from "@mui/material/Checkbox"; -import CustomAutocomplete from "./DynamicForm/Autocomplete.js"; -import _Autocomplete from "./DynamicForm/_Autocomplete.js"; - -import useAPIManager from './useAPIManager.js'; -export const validateField = (value, type, label) => { - let errorMessage = ""; - if (label) { - switch (type) { - case "text": - if (!value) { - errorMessage = ` ${label} is required`; - } - break; - case "select": - if (!value) { - errorMessage = ` ${label} Please Select Value`; - } - break; - case "simple-select": - if (!value) { - errorMessage = ` ${label} Please Select`; - } - break; - case "advance-select": - if (!value) { - errorMessage = ` ${label} Please Select`; - } - break; - case "datetime-local": - if (!value) { - errorMessage = `${label} Please Select `; - } - break; - case "checkbox": - if (!value) { - errorMessage = `${label} Must be Checked`; - } - break; - case "email": - if (!value || !validateEmail(value)) { - errorMessage = `${label} must be a valid email address`; - } - break; - case "password": - if (!value || !validatePassword(value)) { - errorMessage = `${label} must be at least 8 characters long`; - } - break; - case "phone": - if (!value || value.length !== 10) { - errorMessage = `${label} must be exactly 10 characters`; - } - break; - default: - if (!value || !value.trim()) { - errorMessage = `${label} Is Required`; - } - } - } - return errorMessage; -}; - -const FormField = (props) => { - const { Get, Delete, Patch, Post, getAPI } = useAPIManager( - props.globalConfig, - props.token - ); - - - const required = props.field.required; - const label = firstUpperCase(props.field.label); - let fieldLabel = required ? ( - - * {label} - - ) : ( - label - ); - const type = props.field.type; - const varient = props.field.varient; - const placeholder = props.field.placeholder; - const isDynamic = props.field.dynamic; - const hook = props.field.hook; - const defaultObj = props.field.defaultObj; - const dafaultValue = props.field.defaultValue - ? props.field.defaultValue - : props.defaultValue; - const name = props.field.name; - - let optionKey = ""; - let searchApi = ""; - let searchOptionHook = ""; - - if (props.field.search) { - searchApi = props.field.search.api ? props.field.search.api : ""; - // console.log("My Search APu 1", searchApi); - searchApi = searchApi.length > 0 ? getAPI(searchApi) : ""; - - searchOptionHook = props.field.search.label ? props.field.search.label : ""; - optionKey = props.field.search.key ? props.field.search.key : "id"; - } - const [value, setValue] = useState(dafaultValue); - const [isChecked, setIsChecked] = useState(dafaultValue); - const [storageData, setStorageData] = useState([]); - - const [error, setError] = useState( - props.field.error ? props.field.error : "" - ); - const [blurred, setBlurred] = useState(false); - const [simpleSelectOptions, setSimpleSelectOptions] = useState( - props.field.options - ); - - useEffect(() => { - const storedData = localStorage.getItem("dynamicField"); - if (storedData) { - setStorageData(JSON.parse(storedData)); - } - }, []); - - const updateKey = (name, newKey, newLabel) => { - const newData = [...storageData]; - - const dataIndex = newData.findIndex((item) => item.name === name); - - if (dataIndex !== -1) { - newData[dataIndex].key = newKey; - newData[dataIndex].label = newLabel; - } else { - newData.push({ name, key: newKey, label: newLabel }); - } - - setStorageData(newData); - // Update local storage with the new data - localStorage.setItem("dynamicField", JSON.stringify(newData)); - }; - - const changeField = async (e) => { - if (e != undefined && e != null) { - updateKey(name, e.key, e.label); - window.location.reload(); - } - }; - - let handleOnChange = (e) => { - setValue(e.target.value); - if (blurred) { - setError(validateField(e.target.value, type, label)); - } - }; - const handleChange = () => { - const newChecked = !isChecked; - setIsChecked(newChecked); - if (blurred) { - setError(validateField(newChecked, type, label)); - } - }; - const handleaAutocompleteChange = (newValue, inputName) => { - setValue(newValue); - if (blurred) { - setError(validateField(newValue.target.value, type, label)); - } - }; - const handleBlur = (e) => { - setBlurred(true); - setError(validateField(value, type, label)); - setError( - validateField(type === "checkbox" ? isChecked : value, type, label) - ); - - // Validate the field when blurred - }; - - const handleFocus = () => { - setBlurred(false); - }; - - const renderError = () => { - // Check if validation is required for this field - const isValidationRequired = required || false; - - if (isValidationRequired && error && blurred) { - return {error}; - } - return null; - }; - - function formatDate(inputDate) { - const date = new Date(inputDate); - const year = date.getFullYear(); - const month = String(date.getMonth() + 1).padStart(2, "0"); - const day = String(date.getDate()).padStart(2, "0"); - const hours = String(date.getHours()).padStart(2, "0"); - const minutes = String(date.getMinutes()).padStart(2, "0"); - - return `${year}-${month}-${day}T${hours}:${minutes}`; - } - - switch (type) { - case "select": - return ( - <> - {}} - variant={varient} - label={fieldLabel} - onBlur={handleBlur} - onFocus={handleFocus} - /> - {renderError()} - - ); - case "simple-select": - return ( - <> - <_Autocomplete - globalConfig={props.globalConfig} - token={props.token} - apiUrl="" - displayKey="label" - valueKey="type" - inputName={name} - onValueChange={handleaAutocompleteChange} - variant={varient} - label={label} - defaultObj={defaultObj} - options={simpleSelectOptions} - onBlur={handleBlur} - onFocus={handleFocus} - /> - {renderError()} - - ); - case "advance-select": - return ( -
- <_Autocomplete - globalConfig={props.globalConfig} - token={props.token} - apiUrl={searchApi} - displayKey={searchOptionHook} - valueKey={optionKey} - inputName={name} - onValueChange={handleaAutocompleteChange} - variant={varient} - label={fieldLabel} - onBlur={handleBlur} - onFocus={handleFocus} - defaultObj={defaultObj} - /> - {renderError()} -
- ); - case "checkbox": - return ( -
- } - label={fieldLabel} - name={name} - /> - {renderError()} -
- ); - case "datetime-local": - return ( -
- - {renderError()} -
- ); - default: - return ( -
- - {renderError()} -
- ); - } -}; - -export default FormField; diff --git a/src/api-manager/FormWithDrawer.js b/src/api-manager/FormWithDrawer.js deleted file mode 100644 index 1cfcb1d..0000000 --- a/src/api-manager/FormWithDrawer.js +++ /dev/null @@ -1,77 +0,0 @@ -import React from "react"; -import { Button } from "@mui/material"; -import Drawer from "@mui/material/Drawer"; -import Form from "./Form"; - -const FormWithDrawer = (props) => { - const [state, setState] = React.useState({ - top: false, - left: false, - bottom: false, - right: false, - }); - const toggleDrawer = (anchor, open) => (event) => { - if ( - event.type === "keydown" && - (event.key === "Tab" || event.key === "Shift") - ) { - - return; - } - setState({ ...state, [anchor]: open }); - }; - - const anchor = props.anchor ? props.anchor : "right"; - const actionBtnName = props.actionBtnName; - const data = props.data; - const buttonVarient = props.buttonVarient ? props.buttonVarient : "contained"; - const updateFormTitle = props.updateFormTitle ? props.updateFormTitle : ""; - const createFormTitle = props.createFormTitle ? props.createFormTitle : ""; - const submitBtnTitle = props.submitBtnTitle ? props.submitBtnTitle : "Submit"; - const handleCloseDrawer = () => { - setState({ ...state, [anchor]: false }); - }; - - return ( - - - - -
-
-

{createFormTitle}

-

{updateFormTitle}

-
-
-
props.refreshData()} - submitBtnTitle={submitBtnTitle} - inputFields={props.inputFields} - api={props.api} - data={data} - /> -
-
-
-
-
- ); -}; - -export default FormWithDrawer; diff --git a/src/api-manager/MultiSelect.js b/src/api-manager/MultiSelect.js deleted file mode 100644 index d474818..0000000 --- a/src/api-manager/MultiSelect.js +++ /dev/null @@ -1,57 +0,0 @@ -import React, { useEffect, useState } from "react"; -import AutoCompleteField from "./AutoCompleteField"; -import FormField from "./FormField"; - -const MultiSelect = (props) => { - const [hookObj, setHookObj] = useState([]); - - let handleOnChange = (key, value) => { - let obj = []; - console.log("Field Changed sfsdfds", key, value); - localStorage.setItem(key, value); - // setHookObj(hookObj => [...hookObj,{"name":key, "value":value}]); - console.log("Multi Dtaa", hookObj); - - }; - - let loadWithUpdatedApi = (field)=>{ - // field.search.api=localStorage.getItem(field.search.hook) ; - console.log("Sub Search Hook",field.search.hook); - field.search.api = `http://127.0.0.1:8000/api/v1/getAllGroupsJoinedByUser/${localStorage.getItem(field.search.hook)}/`; - return( handleOnChange(name, value)} - field={field} - />) - } - - useEffect(()=>{ - - },[]) - let updateRefresh = (refresh)=>{ -console.log(refresh); - } - return ( -
- {JSON.stringify(props.field)} - - {props.field.map((f) => { - return f.search.hook ? ( - loadWithUpdatedApi(f) - - ) : ( - handleOnChange(name, value)} - refresh={(refresh) => updateRefresh(refresh)} - field={f} - /> - ); - })} -
- ); -}; - - - -export default MultiSelect; diff --git a/src/api-manager/Pagination.js b/src/api-manager/Pagination.js deleted file mode 100644 index 3caaae0..0000000 --- a/src/api-manager/Pagination.js +++ /dev/null @@ -1,98 +0,0 @@ -import React from "react"; -import { Button } from "@mui/material"; -import "./style.css"; - -function Pagination({ - nextPage, - previousPage, - makeApiRequest, - getValueFromUrl, - totalCount, - rowsPerPage, - currentPage, - setCurrentPage, - dataApi, -}) { - const totalPages = Math.ceil(totalCount / rowsPerPage); - - const generatePageNumbers = () => { - const pages = []; - const maxPages = 4; - const currentPageIndex = currentPage; - - let startPage = Math.max(1, currentPageIndex - Math.floor(maxPages / 2)); - let endPage = Math.min(totalPages, startPage + maxPages - 1); - - if (endPage === totalPages) { - startPage = Math.max(1, endPage - maxPages + 1); - } else if (startPage === 1) { - endPage = Math.min(totalPages, startPage + maxPages - 1); - } - - for (let i = startPage; i <= endPage; i++) { - pages.push(i); - } - - return pages; - }; - - const handlePreviousClick = () => { - if (previousPage) { - const previousPageNumber = currentPage - 1; - setCurrentPage(previousPageNumber); - makeApiRequest(previousPage); - } - }; - - const handleNextClick = () => { - if (nextPage) { - const nextPageNumber = currentPage + 1; - setCurrentPage(nextPageNumber); - makeApiRequest(nextPage); - } - }; - - return ( -
- - {generatePageNumbers().map((page) => ( - - ))} - -
- ); -} - -export default Pagination; diff --git a/src/api-manager/Radiobutton.js b/src/api-manager/Radiobutton.js deleted file mode 100644 index 313b5e5..0000000 --- a/src/api-manager/Radiobutton.js +++ /dev/null @@ -1,33 +0,0 @@ -import * as React from "react"; -import Radio from "@mui/material/Radio"; -import RadioGroup from "@mui/material/RadioGroup"; -import FormControlLabel from "@mui/material/FormControlLabel"; -import FormControl from "@mui/material/FormControl"; -import FormLabel from "@mui/material/FormLabel"; - -export default function RadioButtonsGroup() { - return ( - - Payment In For - - } - label="Subscription" - /> - {/* } label="Penalty" /> */} - } - label="Draw Winner" - /> - {/* } label="Custom Amount" /> */} - - - ); -} diff --git a/src/api-manager/TableRow.js b/src/api-manager/TableRow.js deleted file mode 100644 index e45f020..0000000 --- a/src/api-manager/TableRow.js +++ /dev/null @@ -1,52 +0,0 @@ -import { Button } from '@mui/material'; -import React from 'react' -import EditRow from './EditRow'; -import FormWithDrawer from './FormWithDrawer'; -function TableRow(props) { - var row = []; - const readBlock = (props.readBlock) ? props.readBlock : []; - - - - function getCellArray() { - Object.keys(props.data).forEach((key) => { - console.log(readBlock); - if (!Object.values(readBlock).includes(key)) { - Object.entries(props.data).forEach((entry) => { - if (key === entry[0]) { - row.push(entry[1]); - } - }) - } - }) - } - - - function removeRow() { } - getCellArray(); - - - return ( - - { - row.map((data, index) => { - return {data} - }) - } - {(props.manage) ? <> - - - - - - - {/* */} - - : "" - } - - - - ) -} -export default TableRow \ No newline at end of file diff --git a/src/api-manager/example.json b/src/api-manager/example.json deleted file mode 100644 index 574b236..0000000 --- a/src/api-manager/example.json +++ /dev/null @@ -1,105 +0,0 @@ -{ - "api":"https://api.udaymotors.in/api/v1/group/" - , - "showField":[ - { "label": "Group Name", "key": "title" }, - { "label": "Description", "key": "description" }, - { "label": "Subscription Amount", "key": "subscription_amt" }, - { "label": "Max Allowed Users", "key": "max_users" }, - { "label": "Penalty Amount", "key": "penalty_amt" }, - { "label": "Start Date", "key": "start_date" }, - { "label": "End Date", "key": "end_date" } - ], - "createField":[ - - { - "label": "Group name", - "type": "text", - "variant": "standard", - "name": "title" - }, - { - "label": "Group Description", - "type": "text", - "variant": "standard", - "name": "description" - }, - { - "label": "Start Date", - "type": "datetime-local", - "variant": "standard", - "name": "start_date" - }, - { - "label": "End Date", - "type": "datetime-local", - "variant": "standard", - "name": "end_date" - }, - { - "label": "Max Users", - "type": "text", - "variant": "standard", - "name": "max_users" - }, - { - "label": "Subscription Amount", - "type": "text", - "variant": "standard", - "name": "subscription_amt" - }, - { - "label": "Panelty Amount", - "type": "text", - "variant": "standard", - "name": "penalty_amt" - } - - ], - "editField":[ - - { - "label": "Group name", - "type": "text", - "variant": "standard", - "name": "title" - }, - { - "label": "Group Description", - "type": "text", - "variant": "standard", - "name": "description" - }, - { - "label": "Start Date", - "type": "datetime-local", - "variant": "standard", - "name": "start_date" - }, - { - "label": "End Date", - "type": "datetime-local", - "variant": "standard", - "name": "end_date" - }, - { - "label": "Max Users", - "type": "text", - "variant": "standard", - "name": "max_users" - }, - { - "label": "Subscription Amount", - "type": "text", - "variant": "standard", - "name": "subscription_amt" - }, - { - "label": "Panelty Amount", - "type": "text", - "variant": "standard", - "name": "penalty_amt" - } - - ] -} \ No newline at end of file diff --git a/src/api-manager/helper.js b/src/api-manager/helper.js deleted file mode 100644 index e00acb1..0000000 --- a/src/api-manager/helper.js +++ /dev/null @@ -1,16 +0,0 @@ -export function camelCase(str) { - // Using replace method with regEx - return str.replace(/(?:^\w|[A-Z]|\b\w)/g, function (word, index) { - return index === 0 ? word.toLowerCase() : word.toUpperCase(); - }).replace(/\s+/g, ''); -} -export function firstUpperCase(str) { - return str.charAt(0).toUpperCase() + str.slice(1); -} -export const validateEmail = (email) => { - const emailRegex = /^[\w\.-]+@[a-zA-Z\d\.-]+\.[a-zA-Z]{2,}$/; - return emailRegex.test(email); - }; - export const validatePassword = (password) => { - return password.length >= 8; - }; \ No newline at end of file diff --git a/src/api-manager/style.css b/src/api-manager/style.css deleted file mode 100644 index a6408f4..0000000 --- a/src/api-manager/style.css +++ /dev/null @@ -1,46 +0,0 @@ -.dynamic-form-element { - display: block; - margin-bottom: 10px; - width: 100%; -} - -.search-table { - display: flex; - align-items: center; - padding-top: 15px; - padding-bottom: 15px; - width: 100%; -} - -.search-input-table { - padding: 8px; - border: none; /* Remove border */ - border-radius: 15px; - outline: none; - box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1); - - font-size: 16px; - width: 100%; - height: 30px; -} - -.search-input-table:focus { - background-color: #f0f0f0; /* Optional: Change background color on focus */ -} -/* pagination */ -.pagination-container { - display: flex; - justify-content: center; - align-items: center; - margin: 20px 0; -} - -.pagination-button { - margin: 0 5px; -} - -.pagination-button.active-page { - background-color: #6c757d; - color: rgb(73, 198, 207); - -} diff --git a/src/api-manager/useAPIManager.js b/src/api-manager/useAPIManager.js deleted file mode 100644 index 3d9ffd5..0000000 --- a/src/api-manager/useAPIManager.js +++ /dev/null @@ -1,77 +0,0 @@ -import axios from "axios"; - -const useAPIManager = (globalConfig, _token) => { - const authToken = _token; - const global = globalConfig; - - let token = authToken.access; - let authorization = _token - ? { - headers: { - Authorization: `Bearer ${token}`, - }, - } - : {}; - - const getAPI = (API_NAME) => global.api.host + global.api[API_NAME]; - - const getHost = () => global.api.host; - - const Post = async (api, payload) => { - let _api = getAPI(api).includes("undefined") ? api : getAPI(api); - try { - const response = await axios.post(_api, payload, authorization); - return response; - } catch (err) { - throw err; - } - }; - - const Put = async (api, id, payload) => { - let _api = getAPI(api).includes("undefined") ? api : getAPI(api); - try { - const response = await axios.put(`${_api}${id}/`, payload, authorization); - return response; - } catch (err) { - throw err; - } - }; - - const Patch = async (api, id, payload) => { - let _api = getAPI(api).includes("undefined") ? api : getAPI(api); - try { - const response = await axios.patch( - `${_api}${id}/`, - payload, - authorization - ); - return response; - } catch (err) { - throw err; - } - }; - - const Get = async (api) => { - let _api = getAPI(api).includes("undefined") ? api : getAPI(api); - try { - const response = await axios.get(_api, authorization); - return response.data; - } catch (err) { - throw err; - } - }; - - const Delete = async (api, id) => { - let _api = getAPI(api).includes("undefined") ? api : getAPI(api); - try { - const response = await axios.delete(`${_api}${id}/`, authorization); - return response; - } catch (err) { - throw err; - } - }; - - return { Post, Put, Patch, Get, Delete, getAPI, getHost }; -}; - -export default useAPIManager; diff --git a/src/api-manager/useApi.js b/src/api-manager/useApi.js deleted file mode 100644 index 357ea00..0000000 --- a/src/api-manager/useApi.js +++ /dev/null @@ -1,89 +0,0 @@ -// useApi.js -import { useContext } from 'react'; -import axios from 'axios'; -import AuthContext from '../auth/AuthContext'; -import global from '../global/GlobalJSON.json'; - - -const useApi = () => { - const { authToken } = useContext(AuthContext); - - const getAPI = (API_NAME) => global.api.host + global.api[API_NAME]; - - const getHost = () => global.api.host; - let token = authToken.access; - - const Post = async (api, payload) => { - let _api =(getAPI(api).includes('undefined'))?api:getAPI(api); - try { - const response = await axios.post(_api, payload, { - headers: { - Authorization: `Bearer ${token}`, - }, - }); - return response; - } catch (err) { - throw err; - } - }; - - const Put = async (api, id, payload) => { - let _api =(getAPI(api).includes('undefined'))?api:getAPI(api); - try { - const response = await axios.put(`${_api}${id}/`, payload, { - headers: { - Authorization: `Bearer ${token}`, - }, - }); - return response; - } catch (err) { - throw err; - } - }; - - const Patch = async (api, id, payload) => { - let _api =(getAPI(api).includes('undefined'))?api:getAPI(api); - try { - const response = await axios.patch(`${_api}${id}/`, payload, { - headers: { - Authorization: `Bearer ${token}`, - }, - }); - return response; - } catch (err) { - throw err; - } - }; - - const Get = async (api) => { - let _api =(getAPI(api).includes('undefined'))?api:getAPI(api); - try { - const response = await axios.get(_api, { - headers: { - Authorization: `Bearer ${token}`, - }, - }); - return response.data; - } catch (err) { - throw err; - } - }; - - const Delete = async (api, id) => { - let _api =(getAPI(api).includes('undefined'))?api:getAPI(api); - try { - const response = await axios.delete(`${_api}${id}/`, { - headers: { - Authorization: `Bearer ${token}`, - }, - }); - return response; - } catch (err) { - throw err; - } - }; - - return { Post, Put, Patch, Get, Delete, getAPI, getHost }; -}; - -export default useApi; diff --git a/src/assets/bg.png b/src/assets/bg.png deleted file mode 100644 index cf6efb1..0000000 Binary files a/src/assets/bg.png and /dev/null differ diff --git a/src/logo.png b/src/assets/img/logo.png similarity index 100% rename from src/logo.png rename to src/assets/img/logo.png diff --git a/src/components/footer.js b/src/components/common/Footer.js similarity index 95% rename from src/components/footer.js rename to src/components/common/Footer.js index f5e783a..99fe2cc 100644 --- a/src/components/footer.js +++ b/src/components/common/Footer.js @@ -1,5 +1,5 @@ import React from "react"; -import config from "../global/GlobalJSON.json"; +import config from "../../config/Global.json"; const Footer = () => { const { api: { version }, diff --git a/src/components/header.js b/src/components/common/Header.js similarity index 93% rename from src/components/header.js rename to src/components/common/Header.js index b223ad9..d5f54f8 100644 --- a/src/components/header.js +++ b/src/components/common/Header.js @@ -1,4 +1,7 @@ import React, { useContext, useState } from 'react'; +import { Link, useLocation } from 'react-router-dom'; + + import { AppBar, Toolbar, @@ -14,8 +17,8 @@ import { Collapse, Divider, } from '@mui/material'; -import { Link, useLocation } from 'react-router-dom'; -import AuthContext from '../auth/AuthContext'; + + import { Menu as MenuIcon, ChevronLeft as ChevronLeftIcon, @@ -24,11 +27,7 @@ import { ExpandMore, Home as HomeIcon, People as PeopleIcon, - CalendarToday as CalendarTodayIcon, AccountBalance as AccountBalanceIcon, - Receipt as ReceiptIcon, - Paid as PaidIcon, - TimeToLeave as LeaveIcon, Settings as SettingsIcon, Help as HelpIcon, } from '@mui/icons-material'; @@ -36,6 +35,10 @@ import { styled, useTheme } from '@mui/material/styles'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faUserCircle } from '@fortawesome/free-solid-svg-icons'; + +import AuthContext from '../../utils/auth/AuthContext'; + + const drawerWidth = 240; const Main = styled('main', { shouldForwardProp: (prop) => prop !== 'open' })( @@ -141,7 +144,7 @@ const Header = () => { - HbaseApp + React-Placeholder @@ -195,13 +198,13 @@ const Header = () => { - + { to="/department" onClick={handleNavClick} sx={{ pl: 4 }} - className={location.pathname === '/department' ? 'active' : ''} + className={location.pathname === '/page2' ? 'active' : ''} > - + { to="/employee" onClick={handleNavClick} sx={{ pl: 4 }} - className={location.pathname === '/employee' ? 'active' : ''} + className={location.pathname === '/page3' ? 'active' : ''} > - + diff --git a/src/components/header copy.js b/src/components/header copy.js deleted file mode 100644 index cdd59b8..0000000 --- a/src/components/header copy.js +++ /dev/null @@ -1,216 +0,0 @@ -// import React, { useState, useContext, useEffect } from "react"; -// import { -// AppBar, -// Toolbar, -// Typography, -// Box, -// IconButton, -// Menu, -// MenuItem, -// useMediaQuery, -// Drawer, -// List, -// ListItem, -// ListItemText, -// } from "@mui/material"; -// import { Link } from "react-router-dom"; -// import AccountCircle from "@mui/icons-material/AccountCircle"; -// import MenuIcon from "@mui/icons-material/Menu"; -// import AuthContext from "../auth/AuthContext"; -// import useApi from "../api-manager/useApi"; -// import UserTypeUpdatePassword from "../utils/userTypePassword"; - - -// const Header = () => { -// const { user, logOutUser } = useContext(AuthContext); -// const [profile, setProfile] = useState(null); -// const [userType, setUserType] = useState(null); -// const [companyName, setCompanyName] = useState(""); -// const [companyId, setCompanyId] = useState(null); -// const [dialogOpen, setDialogOpen] = useState(false); -// const { Get, Post, getHost } = useApi(); -// const isMobile = useMediaQuery("(max-width:600px)"); -// const [drawerOpen, setDrawerOpen] = useState(false); - -// const handleClose = () => { -// setProfile(null); -// }; - -// const handleMenu = (event) => { -// setProfile(event.currentTarget); -// }; - -// const toggleDrawer = (open) => (event) => { -// if ( -// event.type === "keydown" && -// (event.key === "Tab" || event.key === "Shift") -// ) { -// return; -// } -// setDrawerOpen(open); -// }; - -// const getUserType = async () => { -// try { -// const userTypeData = await Get("checkUserType"); -// setUserType(userTypeData.user_type); - -// const compId = await Get( -// `${getHost()}/api/v1/getCompanyByUserOrDeptId?user_id=${user.user_id}` -// ); -// setCompanyName(compId.company_name); -// setCompanyId(compId.company_id); -// } catch (error) { -// setCompanyName("Hey Admin"); -// } -// }; - -// useEffect(() => { -// getUserType(); -// }, []); - -// const renderLinks = () => { -// switch (userType) { -// case "department user": -// return [ -// { path: "/", label: "Home" }, -// { path: "/cheque-form", label: "Print Cheque" }, -// { path: "/history", label: "Cheque History" }, -// ]; -// case "company user": -// return [ -// { path: "/", label: "Home" }, -// { path: "/cheque-form", label: "Print Cheque" }, -// { path: "/history", label: "Cheque History" }, -// { path: "/department", label: "Departments" }, -// ]; -// case "superuser": -// return [ -// { path: "/", label: "Humbingo Home" }, -// { path: "/company", label: "Company" }, -// { path: "/AdminDepartment", label: "Departments" }, -// { path: "/licence", label: "Licence" }, -// { path: "/registree", label: "Registree" }, -// { path: "/user", label: "User" }, -// { path: "/role", label: "Role" }, -// { path: "/history", label: "Cheque History" }, -// ]; -// default: -// return []; -// } -// }; - -// const linkStyle = { -// color: "inherit", -// textDecoration: "none", -// margin: "0 10px", -// }; - -// const drawerLinks = ( -// -// -// {renderLinks().map((link, index) => ( -// -// -// -// ))} -// -// -// ); - -// const handlePasswordSubmit = async (newPassword) => { -// try { -// await Post( -// `${getHost()}/api/v1/updatePassword/company/${companyId}/`, -// { password: newPassword } -// ); -// alert("Password updated successfully"); // Replace with a better toast notification if needed -// } catch (error) { -// console.error("Error changing password:", error); -// alert("Failed to update password"); // Replace with a better toast notification if needed -// } -// setDialogOpen(false); -// }; - -// return ( -// -// -// -// -// -// -// Logo -// {!isMobile && ( -// {companyName} -// )} -// -// {!isMobile && ( -// -// {renderLinks().map((link, index) => ( -// -// {link.label} -// -// ))} -// -// )} -// -// -// -// -// {/* {`Hello, ${user.user_id}`} */} -// setDialogOpen(true)}>Change Password -// Logout -// -// -// -// {drawerLinks} -// -// setDialogOpen(false)} -// onSubmit={handlePasswordSubmit} -// userType={userType} -// companyId={companyId} -// /> -// -// ); -// }; - -// export default Header; diff --git a/src/components/pages/APIManagerStarter.js b/src/components/pages/APIManagerStarter.js new file mode 100644 index 0000000..95def7f --- /dev/null +++ b/src/components/pages/APIManagerStarter.js @@ -0,0 +1,21 @@ +import React, { useContext } from "react"; +import APIManager from "../external/api-manager/APIManager"; +import global from "../../config/Global.json"; +import AuthContext from "../../utils/auth/AuthContext"; +import schema from "./Schema/APIManagerStarter.json"; +const APIManagerStarter = () => { + let { authToken } = useContext(AuthContext); + return ( +
+ +
+ ) +} + +export default APIManagerStarter diff --git a/src/pages/UI/home/home.js b/src/components/pages/Home.js similarity index 100% rename from src/pages/UI/home/home.js rename to src/components/pages/Home.js diff --git a/src/pages/UI/login/login.js b/src/components/pages/Login.js similarity index 96% rename from src/pages/UI/login/login.js rename to src/components/pages/Login.js index e88de12..58a63e5 100644 --- a/src/pages/UI/login/login.js +++ b/src/components/pages/Login.js @@ -1,6 +1,7 @@ import React, { useContext, useEffect, useState } from "react"; -import AuthContext from "../../../auth/AuthContext"; import { Link, useNavigate } from "react-router-dom"; +import AuthContext from "../../utils/auth/AuthContext"; + import { Container, TextField, @@ -12,7 +13,7 @@ import { InputAdornment, } from "@mui/material"; import { Visibility, VisibilityOff } from "@mui/icons-material"; -import logo from "../../../logo.png" +import logo from "../../assets/img/logo.png" const LoginPage = () => { let { loginUser } = useContext(AuthContext); diff --git a/src/components/pages/Schema/APIManagerStarter.json b/src/components/pages/Schema/APIManagerStarter.json new file mode 100644 index 0000000..42c18c0 --- /dev/null +++ b/src/components/pages/Schema/APIManagerStarter.json @@ -0,0 +1,79 @@ +{ + "api": "company", + "showField": [ + { "label": "Name", "key": "name" }, + { "label": "Address", "key": "address" }, + { "label": "Contact Number", "key": "contact_no" }, + { "label": "Email", "key": "email" }, + { "label": "Website", "key": "website" } + ], + "createField": [ + { + "label": "Name", + "type": "text", + "varient": "standard", + "name": "name", + "required":true + }, + { + "label": "Address", + "type": "text", + "varient": "standard", + "name": "address", + "required":true + }, + { + "label": "Contact Number", + "type": "number", + "varient": "standard", + "name": "contact_no", + "required":true + }, + { + "label": "Email", + "type": "email", + "varient": "standard", + "name": "email", + "required":true + }, + { + "label": "Website", + "type": "text", + "varient": "standard", + "name": "website" + } + ], + "editField": [ + { + "label": "Name", + "type": "text", + "varient": "standard", + "name": "name" + }, + { + "label": "Address", + "type": "text", + "varient": "standard", + "name": "address" + }, + { + "label": "Contact Number", + "type": "number", + "varient": "standard", + "name": "contact_no" + }, + { + "label": "Email", + "type": "email", + "varient": "standard", + "name": "email" + }, + { + "label": "Website", + "type": "text", + "varient": "standard", + "name": "website" + } + ] + } + \ No newline at end of file diff --git a/src/global/Global.js b/src/config/Global.js similarity index 75% rename from src/global/Global.js rename to src/config/Global.js index 5fa3db2..8de0a02 100644 --- a/src/global/Global.js +++ b/src/config/Global.js @@ -1,4 +1,4 @@ -import global from "../global/GlobalJSON.json" +import global from "./Global.json" export function getAPI(API_NAME) { return global.api.host + global.api[API_NAME]; diff --git a/src/global/GlobalJSON.json b/src/config/Global.json similarity index 71% rename from src/global/GlobalJSON.json rename to src/config/Global.json index fbc983c..3c5c990 100644 --- a/src/global/GlobalJSON.json +++ b/src/config/Global.json @@ -1,12 +1,15 @@ { "api": { - "host": "https://cheque-api.humbingo.in", + "host": "https://dev_api_cheque.humbingo.in", "token": "/auth/token/", "refreshToken": "/auth/token/refresh/", "user": "/api/v1/user/", "role": "/api/v1/role/", "permission": "/api/v1/permission/", "checkUserType": "/api/v1/checkUserType", + "company":"/api/v1/company", + "test":"api/v1/test/", + "version": "1.0" }, "debug": true diff --git a/src/index.css b/src/index.css deleted file mode 100644 index ec2585e..0000000 --- a/src/index.css +++ /dev/null @@ -1,13 +0,0 @@ -body { - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', - 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', - sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -code { - font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', - monospace; -} diff --git a/src/index.js b/src/index.js index d563c0f..6338704 100644 --- a/src/index.js +++ b/src/index.js @@ -1,17 +1,9 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; -import './index.css'; import App from './App'; -import reportWebVitals from './reportWebVitals'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( - - - + ); -// If you want to start measuring performance in your app, pass a function -// to log results (for example: reportWebVitals(console.log)) -// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals -reportWebVitals(); diff --git a/src/logo.svg b/src/logo.svg deleted file mode 100644 index 9dfc1c0..0000000 --- a/src/logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/reportWebVitals.js b/src/reportWebVitals.js deleted file mode 100644 index 5253d3a..0000000 --- a/src/reportWebVitals.js +++ /dev/null @@ -1,13 +0,0 @@ -const reportWebVitals = onPerfEntry => { - if (onPerfEntry && onPerfEntry instanceof Function) { - import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { - getCLS(onPerfEntry); - getFID(onPerfEntry); - getFCP(onPerfEntry); - getLCP(onPerfEntry); - getTTFB(onPerfEntry); - }); - } -}; - -export default reportWebVitals; diff --git a/src/setupTests.js b/src/setupTests.js deleted file mode 100644 index 8f2609b..0000000 --- a/src/setupTests.js +++ /dev/null @@ -1,5 +0,0 @@ -// jest-dom adds custom jest matchers for asserting on DOM nodes. -// allows you to do things like: -// expect(element).toHaveTextContent(/react/i) -// learn more: https://github.com/testing-library/jest-dom -import '@testing-library/jest-dom'; diff --git a/src/auth/AuthContext.js b/src/utils/auth/AuthContext.js similarity index 97% rename from src/auth/AuthContext.js rename to src/utils/auth/AuthContext.js index 4fd7a05..f16defe 100644 --- a/src/auth/AuthContext.js +++ b/src/utils/auth/AuthContext.js @@ -1,9 +1,12 @@ import { createContext, useEffect, useState } from "react"; -import axios from "axios"; import { useNavigate } from "react-router-dom"; -import {jwtDecode} from "jwt-decode"; // Make sure jwt-decode is imported correctly -import { getAPI } from "../global/Global"; // Make sure this function is properly defined + +import axios from "axios"; import { toast } from "react-toastify"; +import {jwtDecode} from "jwt-decode"; // Make sure jwt-decode is imported correctly + +import { getAPI } from "../../config/Global"; // Make sure this function is properly defined + const AuthContext = createContext(); diff --git a/src/auth/auth.js b/src/utils/auth/auth.js similarity index 62% rename from src/auth/auth.js rename to src/utils/auth/auth.js index cb01b4a..7ac31a0 100644 --- a/src/auth/auth.js +++ b/src/utils/auth/auth.js @@ -1,9 +1,9 @@ import {useContext } from "react" import React from 'react' -import AuthContext from "../auth/AuthContext"; -import LoginPage from "../pages/UI/login/login"; -import Header from "../components/header"; +import AuthContext from "./AuthContext"; +import LoginPage from "../../components/pages/Login"; +import Header from "../../components/common/Header";