From ebb56198ad8c04cd42f9afc8620a6e47252cf6a7 Mon Sep 17 00:00:00 2001 From: Reed Vogt Date: Sun, 5 May 2024 02:01:37 -0700 Subject: [PATCH] significant changes to folder structure and also fixes for updating/adding features --- .eslintrc.json | 17 +- package.json | 9 +- src/App.js | 34 +- src/assets/themes/base/colors.jsx | 1 + src/assets/themes/components/tabs/index.jsx | 3 +- src/assets/themes/components/tabs/tab.jsx | 15 +- src/context/hooks/useBreakPoint.jsx | 7 + src/context/hooks/useFetchWrapper.jsx | 60 ++-- src/context/hooks/useFormSubmission.jsx | 3 +- src/context/hooks/useLoading.jsx | 16 +- src/context/hooks/useRCFormHook.jsx | 14 +- src/context/hooks/useSelectorActions.jsx | 9 +- src/context/state/useAuthManager.jsx | 3 +- src/context/state/useCardStore.jsx | 1 + src/context/state/useManager.jsx | 85 +++-- src/data/formsConfig.jsx | 3 +- src/data/index.jsx | 7 +- src/data/prepareTableData.jsx | 3 +- src/data/route-config.jsx | 83 +++-- src/index.js | 59 ++-- .../Configurator/ConfiguratorRoot.jsx | 5 +- .../Configurator/index.jsx | 14 +- .../GenericActionButtons.jsx | 105 +++--- .../RCLOADINGBUTTON/RCLoadingButtonRoot.jsx | 1 + .../RCLOADINGBUTTON/index.jsx | 5 +- .../RCTYPOGRAPHY/RCTypographyRoot.jsx | 2 +- .../RC_FORMS/RCDynamicForm.jsx | 182 +++++----- .../REUSABLE_COMPONENTS/RC_FORMS/RCInput.jsx | 43 ++- .../REUSABLE_COMPONENTS/RC_FORMS/RCSwitch.jsx | 2 +- .../RC_OTHER/RCInfoItem.jsx | 5 +- .../RC_OTHER/RCLogoSection.jsx | 5 +- src/layout/REUSABLE_COMPONENTS/index.jsx | 27 +- .../utils/layout-utils/BoxHeader.jsx | 2 +- .../utils/layout-utils/DashBoardLayout.jsx | 2 +- .../utils/layout-utils/PageHeader.jsx | 8 +- .../utils/layout-utils/PageLayout.jsx | 11 +- .../layout-utils/SimpleSectionHeader.jsx | 9 +- .../utils/layout-utils/StatBox.jsx | 2 +- .../utils/system-utils/ErrorFallback.jsx | 326 +++++++++--------- .../utils/system-utils/LoadingOverlay.jsx | 3 +- .../utils/system-utils/SkeletonVariants.jsx | 3 +- src/layout/cards/CardMediaSection.js | 10 +- src/layout/cards/GenericCard.jsx | 17 +- .../cart/cartPageContainers/Checkout.jsx | 5 +- src/layout/cart/cartPageContainers/Review.jsx | 8 +- src/layout/cart/index.jsx | 7 +- .../CollectionListItem.jsx | 36 +- .../CollectionsViewLayout/StatBoard.jsx | 8 +- .../CollectionsViewLayout/index.jsx | 82 +++-- .../CollectionsViewLayout/stats/PriceList.jsx | 9 +- .../CollectionsViewLayout/stats/StatBoxes.jsx | 8 +- .../stats/ValueCircle.jsx | 9 +- .../CollectionPortfolioHeader.jsx | 12 +- .../MyPortfolioLineChart.jsx | 14 +- .../PortfolioViewLayout/TopCardsSwiper.jsx | 23 +- .../collection/PortfolioViewLayout/index.jsx | 122 +++---- src/layout/collection/index.jsx | 79 +++-- src/layout/deck/DeckListItem.jsx | 44 +-- src/layout/deck/index.jsx | 71 +++- src/layout/dialogs/CollectionDialog.jsx | 26 +- src/layout/dialogs/DeckDialog.jsx | 10 +- src/layout/dialogs/DetailsModal.jsx | 5 +- src/layout/dialogs/GenericCardDialog.jsx | 9 +- src/layout/dialogs/LoginDialog.jsx | 3 +- src/layout/home/FeatureCardsSection.jsx | 26 +- src/layout/home/HeroChartSection.jsx | 29 +- src/layout/home/HeroIconSection.jsx | 11 +- src/layout/home/HeroSwiper.jsx | 13 +- src/layout/home/HeroTextSection.jsx | 7 +- src/layout/home/index.jsx | 49 ++- src/layout/navigation/index.jsx | 15 +- .../NotificationList.jsx | 6 +- src/layout/profile/index.jsx | 7 +- src/layout/profile/sub-components/Header.jsx | 29 +- .../sub-components/ProfileInfoCard.jsx | 3 +- .../profile/sub-components/Settings.jsx | 7 +- src/layout/search/PaginationComponent.jsx | 1 + src/layout/search/SearchComponent.jsx | 16 +- src/layout/search/SearchResults.jsx | 8 +- src/layout/store/index.jsx | 3 +- src/pages/CartPage.js | 22 +- src/pages/CollectionPage.js | 18 +- src/pages/DeckBuilderPage.js | 2 +- src/pages/HomePage.js | 7 +- src/pages/LoginPage.jsx | 9 +- src/pages/ProfilePage.js | 30 +- src/pages/StorePage.js | 7 +- 87 files changed, 1141 insertions(+), 995 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index b025b6a..7473a73 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,14 +1,15 @@ { "env": { "browser": true, - "es6": true, + "es2021": true, "jest": true, "node": true }, "extends": [ "eslint:recommended", - "plugin:@typescript-eslint/recommended", "plugin:react/recommended", + "plugin:@typescript-eslint/recommended", + // "plugin:react-hooks/recommended", "plugin:prettier/recommended" ], "parser": "@typescript-eslint/parser", @@ -16,10 +17,15 @@ "ecmaFeatures": { "jsx": true }, - "ecmaVersion": 2020, + "ecmaVersion": 2021, "sourceType": "module" }, - "plugins": ["react", "@typescript-eslint", "prettier"], + "plugins": [ + "react", + // "react-hooks", + "@typescript-eslint", + "prettier" + ], "rules": { "no-console": "off", "@typescript-eslint/indent": ["error", 2], @@ -32,6 +38,8 @@ ], "react/react-in-jsx-scope": "off", "react/prop-types": "off", + // "react-hooks/rules-of-hooks": "error", + // "react-hooks/exhaustive-deps": "warn", "eol-last": ["error", "always"], "object-curly-spacing": ["error", "always"], "array-bracket-spacing": ["error", "never"], @@ -43,6 +51,7 @@ "error", { "singleQuote": true, + "tabWidth": 2, "endOfLine": "lf" } ] diff --git a/package.json b/package.json index 2c95987..ca1f9a0 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,6 @@ "@stripe/stripe-js": "^1.54.2", "axios": "^1.4.0", "chroma-js": "^2.4.2", - "date-fns": "^2.30.0", "jwt-decode": "^3.1.2", "lodash": "^4.17.21", "mathjs": "^12.4.1", @@ -33,18 +32,16 @@ "react-device-detect": "^2.2.3", "react-dom": "^18.3.1", "react-error-boundary": "^4.0.13", - "react-helmet": "^6.1.0", "react-helmet-async": "^2.0.4", "react-hook-form": "^7.50.0", "react-icons": "^4.10.1", "react-perfect-scrollbar": "^1.5.8", - "react-router-dom": "^6.17.0", + "react-router-dom": "^6.23.0", "react-scroll-parallax": "^3.4.5", "react-spring": "^9.7.3", "react-stripe-checkout": "^2.6.3", "react-table": "^7.8.0", "react-transition-group": "^4.4.5", - "react-virtualized": "^9.22.5", "recharts": "^2.12.3", "sass": "^1.69.7", "stripe": "^12.14.0", @@ -58,7 +55,8 @@ "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", - "eject": "react-scripts eject" + "eject": "react-scripts eject", + "lint": "eslint src --ext .js,.jsx,.ts,.tsx" }, "eslintConfig": { "extends": [ @@ -84,6 +82,7 @@ "eslint": "^8.46.0", "eslint-config-prettier": "^8.9.0", "eslint-plugin-prettier": "^5.0.0", + "eslint-plugin-react-hooks": "^4.6.2", "http-proxy-middleware": "^2.0.6", "prettier": "^3.0.0", "react-scripts": "5.0.1" diff --git a/src/App.js b/src/App.js index a51e866..f804cba 100644 --- a/src/App.js +++ b/src/App.js @@ -1,14 +1,15 @@ // App.js import React, { Suspense, lazy, useEffect } from 'react'; -import { Route, Routes, useNavigate } from 'react-router-dom'; - -import './assets/css/index.css'; -import './assets/css/card.css'; -import './assets/css/page.css'; +import { + Route, + Routes, + useNavigate, + BrowserRouter as Router, +} from 'react-router-dom'; import { CSSTransition, TransitionGroup } from 'react-transition-group'; import LoginDialog from 'layout/dialogs/LoginDialog'; import Navigation from 'layout/navigation'; -import { ROUTE_CONFIG } from 'data'; +import { HelmetMetaData, ROUTES } from 'data'; import { Configurator, LoadingOverlay, @@ -21,7 +22,7 @@ import { useMode, } from 'context'; import { ThemeProvider } from 'styled-components'; -import { CssBaseline } from '@mui/material'; +import { CssBaseline, GlobalStyles } from '@mui/material'; // ==============================|| APP ||============================== // @@ -48,31 +49,28 @@ const App = () => { const { isConfiguratorOpen } = useConfigurator(); return ( - - {/* */} - + + + + {isConfiguratorOpen && } }> - {ROUTE_CONFIG.routes.map( - ({ path, componentName, isPrivate }, index) => ( + {ROUTES.map( + ({ path, component: Component, isPrivate }, index) => ( - + ) : ( - + ) } /> diff --git a/src/assets/themes/base/colors.jsx b/src/assets/themes/base/colors.jsx index ac21358..511cf74 100644 --- a/src/assets/themes/base/colors.jsx +++ b/src/assets/themes/base/colors.jsx @@ -36,6 +36,7 @@ const success = { dark: '#3da58a', darkest: '#2e7c67', // '#70d8bd', contrastText: '#dbf5ee', + contrastText2: '#ecfdf9', hoverContrastText: colorTextForDark, }; const info = { diff --git a/src/assets/themes/components/tabs/index.jsx b/src/assets/themes/components/tabs/index.jsx index a348c88..a9fc506 100644 --- a/src/assets/themes/components/tabs/index.jsx +++ b/src/assets/themes/components/tabs/index.jsx @@ -11,7 +11,8 @@ export default { styleOverrides: { root: { position: 'relative', - backgroundColor: '#f8f9fa', + // backgroundColor: `${success.contrastText2} !important`, + backgroundColor: '#f6fefc', borderRadius: borderRadius.lg, minHeight: 'unset', padding: pxToRem(12), diff --git a/src/assets/themes/components/tabs/tab.jsx b/src/assets/themes/components/tabs/tab.jsx index 8dd4705..308d50f 100644 --- a/src/assets/themes/components/tabs/tab.jsx +++ b/src/assets/themes/components/tabs/tab.jsx @@ -2,8 +2,9 @@ import typography from 'assets/themes/base/typography'; import borders from 'assets/themes/base/borders'; import colors from 'assets/themes/base/colors'; import pxToRem from 'assets/themes/functions/pxToRem'; +import { rgba } from 'assets/themes'; -const { size, fontWeightMedium } = typography; +const { size, fontWeightBold } = typography; const { borderRadius } = borders; const { dark, grey, success, text } = colors; @@ -20,12 +21,13 @@ export default { minHeight: 'unset !important', height: 'auto', fontSize: size.lg, - fontWeight: fontWeightMedium, + fontWeight: fontWeightBold, textTransform: 'none', lineHeight: 'inherit', - padding: pxToRem(4), + py: pxToRem(12), borderRadius: borderRadius.md, - color: `${text.primary} !important`, + color: `${success.darkest} !important`, + transition: 'background-color 300ms ease, color 300ms ease', // smooth transition for background and color // color: `${dark.main} !important`, opacity: '1 !important', @@ -37,8 +39,13 @@ export default { marginBottom: '0 !important', marginRight: pxToRem(6), }, + '&:hover': { + backgroundColor: `${rgba(success.light, 0.2)} !important`, // change background color on hover + color: `${dark.main} !important`, // change text color on hover + }, '&:selected': { color: `${success.main} !important`, + backgroundColor: rgba(success.main, 0.5), }, 'span.MuiTab-wrapper': { color: `${success.main} !important`, diff --git a/src/context/hooks/useBreakPoint.jsx b/src/context/hooks/useBreakPoint.jsx index 5ab6142..2eb1f01 100644 --- a/src/context/hooks/useBreakPoint.jsx +++ b/src/context/hooks/useBreakPoint.jsx @@ -9,6 +9,10 @@ const useBreakpoint = () => { const isTablet = useMediaQuery(theme.breakpoints.down('md')); const isLaptop = useMediaQuery(theme.breakpoints.down('lg')); const isDesktop = useMediaQuery(theme.breakpoints.up('xl')); + + // Checks for specific breakpoints + const isMobileUp = useMediaQuery(theme.breakpoints.up('sm')); + const matchesXS = useMediaQuery(theme.breakpoints.only('xs')); const matchesSM = useMediaQuery(theme.breakpoints.only('sm')); const matchesMD = useMediaQuery(theme.breakpoints.only('md')); @@ -37,6 +41,9 @@ const useBreakpoint = () => { isLg: isLaptop, isXl: isDesktop, + // Checks for points above + isMobileUp: isMobileUp, + // Checks for ranges isBetweenXsAndSm: matchesXSBetweenSM, isBetweenSmAndMd: matchesSMBetweenMD, diff --git a/src/context/hooks/useFetchWrapper.jsx b/src/context/hooks/useFetchWrapper.jsx index ba26e2d..02bd686 100644 --- a/src/context/hooks/useFetchWrapper.jsx +++ b/src/context/hooks/useFetchWrapper.jsx @@ -30,14 +30,14 @@ const FETCH_STATUSES = { const useFetchWrapper = () => { const [status, setStatus] = useState(FETCH_STATUSES.IDLE); const [data, setData] = useState(null); + const [activeLoadingIDs, setActiveLoadingIDs] = useState(new Set()); + const [responseCache, setResponseCache] = useLocalStorage('apiResponses', {}); const [errorResponse, setErrorResponse] = useLocalStorage('apiErrors', {}); - // const { logEvent } = useLogger('useFetchWrapper'); const { startLoading, stopLoading, isLoading } = useLoading(); const { enqueueSnackbar } = useSnackbar(); const showNotification = useCallback( (message, variant) => { - // const showNotification = useCallback(message, variant) => { enqueueSnackbar(message, { variant: variant, anchorOrigin: { @@ -49,19 +49,18 @@ const useFetchWrapper = () => { [enqueueSnackbar] ); - // useEffect to log status changes - // useEffect(() => { - // console.log('Status Change', { status }); - // }, [status]); const fetchWrapper = useCallback( async (url, method = 'GET', body = null, loadingID) => { - // setStatus('loading'); - // startLoading(loadingID); - // showNotification(`Loading ${loadingID}...`, 'info'); + if (activeLoadingIDs.has(loadingID)) { + console.log(`Fetch already in progress for: ${loadingID}`); + return; + } + setActiveLoadingIDs((prev) => new Set(prev).add(loadingID)); + setStatus(FETCH_STATUSES.LOADING); + startLoading(loadingID); + showNotification(`[LOADING][${loadingID}]`, 'info'); + try { - setStatus(FETCH_STATUSES.LOADING); - startLoading(loadingID); - showNotification(`[LOADING][${loadingID}]`, 'info'); const headers = { 'Content-Type': 'application/json' }; const options = { method, @@ -78,8 +77,10 @@ const useFetchWrapper = () => { responseData = await response.json(); } if (!response.ok) { - const errorInfo = `Error: ${response.statusText} (status: ${response.status})`; - console.error('[ERROR B]', responseData); // Log the detailed error message + // const error = new Error(response.statusText || 'Unknown error'); + // error.status = response.status; + // error.responseData = responseData; + // throw error; const parsed = JSON.parse(responseData); const errorDetails = { message: parsed.message || 'Unknown error', @@ -92,6 +93,7 @@ const useFetchWrapper = () => { ...prevErrors, [loadingID]: errorDetails, })); + setStatus(FETCH_STATUSES.ERROR); throw new Error(responseData); } @@ -107,31 +109,22 @@ const useFetchWrapper = () => { ); return responseData; } catch (error) { - // const errorDetails = { - // message: error.message || 'Unknown error', - // name: error.name || 'Error', - // status: error.status || 'No status', - // detail: error.stack || 'No additional details', - // }; - // setErrorResponse((prevErrors) => ({ - // ...prevErrors, - // [loadingID]: errorDetails, - // })); - // setErrorResponse((prevErrors) => ({ - // ...prevErrors, - // [loadingID]: { - // message: error.message || 'Unknown error', - // status: error.status || 'No status', - // detail: error.responseData || 'No additional details', - // name: error.name || 'No name', - // }, - // })); setStatus(FETCH_STATUSES.ERROR); + setErrorResponse((prev) => ({ + ...prev, + [loadingID]: serializeError(error), + })); + showNotification(`[Error][${loadingID}] ${error.message}`, 'error'); throw error; // return Promise.reject(err); } finally { stopLoading(loadingID); + setActiveLoadingIDs((prev) => { + const newIDs = new Set(prev); + newIDs.delete(loadingID); + return newIDs; + }); } }, [ @@ -142,6 +135,7 @@ const useFetchWrapper = () => { showNotification, startLoading, stopLoading, + activeLoadingIDs, ] ); diff --git a/src/context/hooks/useFormSubmission.jsx b/src/context/hooks/useFormSubmission.jsx index a37bd40..62261f2 100644 --- a/src/context/hooks/useFormSubmission.jsx +++ b/src/context/hooks/useFormSubmission.jsx @@ -1,12 +1,11 @@ import { useCallback, useState } from 'react'; -import { handleValidation, zodSchemas } from '../../data/formsConfig'; +import { handleValidation, zodSchemas } from 'data'; const useFormSubmission = (formHandlers, formKey) => { const [isSubmitting, setIsSubmitting] = useState(false); const activeSchema = zodSchemas[formKey]; const onSubmit = useCallback( async (formData) => { - // handleValidation setIsSubmitting(true); console.log('[ACTIVE FORM]', formKey); console.log('[FORM DATA]', formData); diff --git a/src/context/hooks/useLoading.jsx b/src/context/hooks/useLoading.jsx index bc79de5..96e74f0 100644 --- a/src/context/hooks/useLoading.jsx +++ b/src/context/hooks/useLoading.jsx @@ -38,16 +38,16 @@ const LOADING_IDS = { logout: 'signout', }, decks: { - fetchingDecks: 'fetchDecks', - addingDeck: 'createNewDeck', - updatingDeck: 'updateDeckDetails', - deletingDeck: 'deleteDeck', - addingCardsToDeck: 'addCardsToDeck', - removingCardsFromDeck: 'removeCardsFromDeck', + fetchingDecks: 'FETCH_ALL_DECKS', + addingDeck: 'ADD_DECKS', + updatingDeck: 'UPDATE_DECKS', + deletingDeck: 'DELETE_DECKS', + addingCardsToDeck: 'ADD_CARDS_TO_DECK', + removingCardsFromDeck: 'REMOVE_CARDS_FROM_DECK', }, collections: { - fetchingCollections: 'fetchCollections', - addingCollection: 'createNewCollection', + fetchingCollections: 'FETCH_ALL_COLLECTIONS', + addingCollection: 'ADD_COLLECTIONS', updatingCollection: 'updateCollection', deletingCollection: 'deleteCollection', addingCardsToCollection: 'addCardsToCollection', diff --git a/src/context/hooks/useRCFormHook.jsx b/src/context/hooks/useRCFormHook.jsx index 1f664b0..dda478f 100644 --- a/src/context/hooks/useRCFormHook.jsx +++ b/src/context/hooks/useRCFormHook.jsx @@ -1,10 +1,9 @@ import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { useEffect } from 'react'; -import { formFields, zodSchemas } from '../../data/formsConfig'; +import { formFields, zodSchemas } from 'data'; const useRCFormHook = (schemaKey, initialData) => { - // console.log('SCHEMA KEY', schemaKey); const schema = zodSchemas[schemaKey]; const defaultValues = Object.keys(schema.shape).reduce((acc, key) => { const fieldDefinition = schema.shape[key]; @@ -23,10 +22,13 @@ const useRCFormHook = (schemaKey, initialData) => { defaultValues: !initialData ? defaultValues : null, }); - useEffect(() => { - console.log('[1] FORMSTATE: ', methods.getValues()); - console.log(`[2] ${schemaKey} SCHEMA REGISTERED: `, schema); - }, [methods, schemaKey, schema]); + // useEffect(() => { + // console.log( + // // `[1] ${schemaKey} SCHEMA REGISTERED: ${schema}`, + // // `[2] FORMSTATE REGISTERED: ${JSON.stringify(methods.formState)}`, + // `[3] VALUES: ${JSON.stringify(methods.getValues())}` + // ); + // }, [methods.formState]); return methods; }; diff --git a/src/context/hooks/useSelectorActions.jsx b/src/context/hooks/useSelectorActions.jsx index b187883..ea9b32c 100644 --- a/src/context/hooks/useSelectorActions.jsx +++ b/src/context/hooks/useSelectorActions.jsx @@ -97,9 +97,16 @@ function useSelectorActions() { const newTag = { id: nanoid(), label: e.target.value }; const updatedTags = [...tags, newTag]; console.log('NEW TAG', updatedTags); + const { name, description, color } = selected; // selectedDeck.tags = updatedTags; setTags(updatedTags); // Update local state - updateEntityField('decks', selectedDeckId, ['tags'], [updatedTags]); // Persist tags update + updateEntityField( + 'decks', + selectedDeckId, + ['tags', 'name', 'description', 'color'], + [updatedTags, name, description, color] + ); // Persist tags update + handleSelectDeck(selectedDeck); e.target.value = ''; // Clear the input after adding a tag diff --git a/src/context/state/useAuthManager.jsx b/src/context/state/useAuthManager.jsx index 4c8c4a0..90d3afc 100644 --- a/src/context/state/useAuthManager.jsx +++ b/src/context/state/useAuthManager.jsx @@ -1,8 +1,7 @@ import { useCallback, useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; -import useUserData from './useUserData'; import jwt_decode from 'jwt-decode'; -import { useFetchWrapper, useManageCookies } from 'context/hooks'; +import { useFetchWrapper, useManageCookies, useUserData } from 'context'; function useAuthManager() { const navigate = useNavigate(); diff --git a/src/context/state/useCardStore.jsx b/src/context/state/useCardStore.jsx index f827240..c95c804 100644 --- a/src/context/state/useCardStore.jsx +++ b/src/context/state/useCardStore.jsx @@ -109,6 +109,7 @@ const useCardStore = () => { setIsDataValid, clearSearchData, loadingSearchResults: isLoading('isSearchLoading'), + loadingRandomCards: isLoading('fetchRandomCardsAndSet'), setLoadingSearchResults: () => { startLoading('isSearchLoading'); }, diff --git a/src/context/state/useManager.jsx b/src/context/state/useManager.jsx index e6eff9f..357367d 100644 --- a/src/context/state/useManager.jsx +++ b/src/context/state/useManager.jsx @@ -9,21 +9,21 @@ import { } from '../hooks'; const useManager = () => { - const { fetchWrapper } = useFetchWrapper(); + const { fetchWrapper, status } = useFetchWrapper(); const { getCookie } = useManageCookies(); const { isLoggedIn, userId } = getCookie(['isLoggedIn', 'userId']); const logger = useLogger('CollectionManager'); const [customError, setCustomError] = useState(''); const baseUrl = `${process.env.REACT_APP_SERVER}/api/users/${userId}`; const { selectedContext } = useSelectedContext(); - const createApiUrl = (entity, action) => `${baseUrl}/${entity}/${action}`; + // DECKS const [decks, setDecks] = useState([]); - const [selectedDeck, setSelectedDeck] = useLocalStorage('selectedDeck', null); + const [selectedDeck, setSelectedDeck] = useLocalStorage('selectedDeck', {}); const [selectedDeckId, setSelectedDeckId] = useLocalStorage( 'selectedDeckId', - '' + null ); const [hasFetchedDecks, setHasFetchedDecks] = useState(false); const [hasUpdatedDecks, setHasUpdatedDecks] = useState(false); @@ -33,11 +33,11 @@ const useManager = () => { const [collections, setCollections] = useState([]); const [selectedCollection, setSelectedCollection] = useLocalStorage( 'selectedCollection', - null + {} ); const [selectedCollectionId, setSelectedCollectionId] = useLocalStorage( 'selectedCollectionId', - '' + null ); const [hasFetchedCollections, setHasFetchedCollections] = useState(false); @@ -59,6 +59,7 @@ const useManager = () => { selectedCollectionId: null, selectedDeckId: null, }); + // DATA const [collectionMetaData, setCollectionMetaData] = useLocalStorage( 'collectionMetaData', @@ -177,14 +178,14 @@ const useManager = () => { // FETCHING ENTITIES const handleSelectEntity = useCallback( (entityName, entityData) => { - if (entityName === 'collection') { + if (entityName === 'collection' && entityData) { setSelectedCollection(entityData); setSelectedCollectionId(entityData?._id); setSelectedIds((state) => ({ ...state, selectedCollectionId: entityData?._id, })); - } else if (entityName === 'deck') { + } else if (entityName === 'deck' && entityData) { setSelectedDeck(entityData); // setSelectedDeck((state) => ({ ...state, entityData })); setSelectedDeckId(entityData?._id); @@ -198,12 +199,14 @@ const useManager = () => { ); const fetchEntities = useCallback( async (entity) => { + const loadingID = `FETCH_ALL_${entity.toUpperCase()}`; + console.log('LOADING ID:', loadingID); try { const response = await fetchWrapper( createApiUrl(entity, 'all'), 'GET', null, - `fetchAll${entity}`.toLocaleUpperCase() + loadingID ); if (entity === 'cart') { setCart(response.data); @@ -217,26 +220,6 @@ const useManager = () => { setHasFetchedCollections(true); setHasFetched((state) => ({ ...state, collections: true })); compileCardsWithQuantities(response.data, null, null); - const selectedId = localStorage.getItem('selectedCollectionId'); - console.log('SELECTED ID', selectedId); - if (selectedId) { - // const collection = response.data.find((col) => { - // console.log('ID', JSON.stringify(col._id)); - // return JSON.stringify(col._id) === JSON.stringify(selectedId); // Ensure both IDs are compared as strings - // }); - const collection = response.data.find( - (col) => col._id === selectedId - ); - - console.log('SELECTED COLLECTION', collection); - console.log('RESPONSE DATA', response.data); - if (collection) { - setSelectedCollection(collection); - } else { - console.log('Selected collection not found'); - // setSelectedCollection(null); // or handle the absence of the selected collection appropriately - } - } return response.data; } else { setDecks(response.data); @@ -273,7 +256,7 @@ const useManager = () => { null, `fetch${entity}`.toLocaleUpperCase() ); - // handleSelectEntity(entity, response.data); + handleSelectEntity(entity, response.data); return response.data; } catch (error) { logger.logError('Fetch Error:', error); @@ -386,6 +369,7 @@ const useManager = () => { case 'collections': const selectedId = localStorage.getItem('selectedCollectionId'); setCollections(response.data); + break; case 'decks': setDecks((prev) => @@ -403,6 +387,7 @@ const useManager = () => { throw new Error(`Unhandled entity type: ${entity}`); } } + // return response.data; } catch (error) { console.error(`Error updating ${entity} fields:`, error); setCustomError(`Failed to update ${entity} fields`); @@ -411,23 +396,22 @@ const useManager = () => { [isLoggedIn, fetchWrapper, logger, setCart, setCollections, setDecks, cart] ); const addEntity = useCallback( - (entity, data) => - handleEntityOperation(entity, 'create', `add${entity}`, data), + (entity, data) => handleEntityOperation(entity, 'create', 'add_', data), [handleEntityOperation] ); const updateEntity = useCallback( - (entity, data) => { + async (entity, data) => { const localEntity = entity === 'decks' ? 'Deck' : 'Collection'; const id = localStorage.getItem('selected' + localEntity + 'Id'); const cleanedId = encodeURIComponent(id.replace(/"/g, '')); console.log('UPDAtING', entity, data); - handleEntityOperation(entity, `update/${cleanedId}`, 'update', data); + handleEntityOperation(entity, `update/${cleanedId}`, 'update_', data); }, [handleEntityOperation] ); const deleteEntity = useCallback( (entity, id) => - handleEntityOperation(entity, `delete/${id}`, 'delete', { + handleEntityOperation(entity, `delete/${id}`, 'delete_', { id: id, }), [handleEntityOperation] @@ -442,7 +426,7 @@ const useManager = () => { } else { type = 'addNew'; } - return handleEntityOperation(entity, 'cards/add', 'addCardTo', { + return handleEntityOperation(entity, 'cards/add', 'add_cards_to_', { cards: [card], type: type, }); @@ -458,10 +442,15 @@ const useManager = () => { } else { type = 'addNew'; } - handleEntityOperation(entity, `${selectEntVal}/cards/add`, 'addCardTo', { - cards: [card], - type: type, - }); + handleEntityOperation( + entity, + `${selectEntVal}/cards/add`, + 'add_cards_to_', + { + cards: [card], + type: type, + } + ); }, [handleEntityOperation] ); @@ -475,10 +464,10 @@ const useManager = () => { if (cardExists) { type = 'decrement'; - action = 'removeCardFrom'; + action = 'remove_cards_from_'; } else { type = 'delete'; - action = 'deleteCardFrom'; + action = 'delete_cards_from_'; } handleEntityOperation( entity, @@ -504,10 +493,10 @@ const useManager = () => { const existingCard = selectedEntity?.cards?.find((c) => c.id === item.id); if (cardExists && existingCard.quantity > 1) { type = 'decrement'; - action = 'removeCardFrom'; + action = 'remove_cards_from_'; } else { type = 'delete'; - action = 'deleteCardFrom'; + action = 'delete_cards_from_'; } handleEntityOperation( entity, @@ -566,6 +555,9 @@ const useManager = () => { handleSelectCollection: (data) => handleSelectEntity('collection', data), handleSelectDeck: (data) => handleSelectEntity('deck', data), + setHasFetchedCollections, + setHasFetchedDecks, + setHasFetchedCart, checkForCardInContext: isCardInContext, compileCardsWithQuantities, fetchEntities, @@ -578,6 +570,7 @@ const useManager = () => { collectionMetaData, selectedCollection, selectedDeck, + status, }), [ collections, @@ -590,9 +583,13 @@ const useManager = () => { hasFetchedCards, hasUpdatedCards, collectionMetaData, + status, compileCollectionMetaData, setHasUpdatedCards, + setHasFetchedCollections, + setHasFetchedDecks, + setHasFetchedCart, setHasFetchedCards, fetchEntities, addEntity, diff --git a/src/data/formsConfig.jsx b/src/data/formsConfig.jsx index 7918ce6..004bce4 100644 --- a/src/data/formsConfig.jsx +++ b/src/data/formsConfig.jsx @@ -323,10 +323,11 @@ const statRangeFormFields = { statRange: { context: 'Collection', name: 'statRange', - label: 'Statistics Range', + label: 'Stat Range', type: 'select', placeholder: 'Select statistics range', // Optional for a select, used if you have a default empty option defaultValue: 'highPoint', + defaultLabel: 'High Point', selected: 'highPoint', rules: { required: 'Statistics range is required', // Assuming you want to enforce a selection diff --git a/src/data/index.jsx b/src/data/index.jsx index 5bb11d8..5d9a3ec 100644 --- a/src/data/index.jsx +++ b/src/data/index.jsx @@ -1,9 +1,10 @@ import heroData from './heroData'; -import ROUTE_CONFIG from './route-config'; import collectionPortfolioHeaderItems from './collectionPortfolioHeaderItems'; import baseMenuItems from './baseMenuItems'; import prepareTableData from './prepareTableData'; import HelmetMetaData from './HelmetMetaData'; +import DeckBuilderIcon from './DeckBuilderIcon'; +import { ROUTES } from './route-config.jsx'; import { formFields, zodSchemas, @@ -13,7 +14,8 @@ import { } from './formsConfig'; export { heroData, - ROUTE_CONFIG, + ROUTES, + // ROUTE_CONFIG, HelmetMetaData, collectionPortfolioHeaderItems, baseMenuItems, @@ -22,6 +24,7 @@ export { formFields, zodSchemas, configOptions, + DeckBuilderIcon, handleValidation, getFormFieldHandlers, }; diff --git a/src/data/prepareTableData.jsx b/src/data/prepareTableData.jsx index 850a896..62b307a 100644 --- a/src/data/prepareTableData.jsx +++ b/src/data/prepareTableData.jsx @@ -1,7 +1,6 @@ import React from 'react'; -import RCTypography from 'layout/REUSABLE_COMPONENTS/RCTYPOGRAPHY'; import { roundToNearestTenth } from 'context/Helpers'; -import GenericActionButtons from 'layout/REUSABLE_COMPONENTS/GenericActionButtons'; +import { GenericActionButtons, RCTypography } from 'layout/REUSABLE_COMPONENTS'; // Note: No changes needed for these components const Name = ({ name, color }) => ( ({ +// path, +// componentName, +// isPrivate, +// })), +// }; -const ROUTE_CONFIG = { - defaultPath: '/', - routes: ROUTES.map(({ path, componentName, isPrivate }) => ({ - path, - componentName, - isPrivate, - })), -}; +// export { ROUTES, ROUTE_CONFIG }; +// First, import all the necessary components + +// Then, refactor the ROUTES to use component references directly +const ROUTES = [ + { path: '/', component: HomePage, isPrivate: false }, + { path: '/home', component: HomePage, isPrivate: false }, + { path: '/deckbuilder', component: DeckBuilderPage, isPrivate: false }, + { path: '/store', component: StorePage, isPrivate: false }, + { path: '/cart', component: CartPage, isPrivate: true }, + { path: '/collection', component: CollectionPage, isPrivate: true }, + { path: '/profile', component: ProfilePage, isPrivate: true }, + { path: '/login', component: LoginPage, isPrivate: false }, + // { path: '/signup', component: SignupPage, isPrivate: false }, + { path: '*', component: NotFoundPage, isPrivate: false }, +]; -export default ROUTE_CONFIG; +// Export ROUTES and the refactored ROUTE_CONFIG +export { ROUTES }; diff --git a/src/index.js b/src/index.js index 543ff7c..e8569a4 100644 --- a/src/index.js +++ b/src/index.js @@ -1,50 +1,41 @@ import React, { StrictMode } from 'react'; -// import ReactDOM from 'react-dom/client'; -import { createRoot } from 'react-dom/client'; - +import ReactDOM from 'react-dom/client'; +import './assets/css/index.css'; +import './assets/css/card.css'; +import './assets/css/page.css'; import { BrowserRouter as Router } from 'react-router-dom'; +import { ParallaxProvider } from 'react-scroll-parallax'; +// import reportWebVitals from './reportWebVitals'; + import App from './App'; import { register, unregister } from './serviceWorker'; -// ==============================|| REACT DOM RENDER ||============================== // - -import { ColorModeProvider } from './context'; -import { SnackbarProvider, enqueueSnackbar } from 'notistack'; +import { SnackbarProvider } from 'notistack'; import { ErrorBoundary } from 'react-error-boundary'; -import { ParallaxProvider } from 'react-scroll-parallax'; -import { HelmetMetaData } from 'data'; import { ErrorFallback } from 'layout/REUSABLE_COMPONENTS'; +import { ColorModeProvider } from 'context'; -const root = createRoot(document.getElementById('root')); +// ==============================|| REACT DOM RENDER ||============================== // -// ==============================|| APP WRAPPER ||============================== // +const root = ReactDOM.createRoot(document.getElementById('root')); -const AppWrapper = () => { - const errorHandler = (error, errorInfo) => { - console.error('Error:', error, 'Info:', errorInfo); - enqueueSnackbar('An unexpected error occurred, please try again later.', { - variant: 'error', - }); - }; - return ( - +root.render( + + - - - - - - - - - - + + + + + + + - - ); -}; + + +); -root.render(); // Use the root to render the AppWrapper. +// reportWebVitals(); if (process.env.NODE_ENV === 'production') { register(); // Only register the service worker in production diff --git a/src/layout/REUSABLE_COMPONENTS/Configurator/ConfiguratorRoot.jsx b/src/layout/REUSABLE_COMPONENTS/Configurator/ConfiguratorRoot.jsx index 0e1d801..ea6854d 100644 --- a/src/layout/REUSABLE_COMPONENTS/Configurator/ConfiguratorRoot.jsx +++ b/src/layout/REUSABLE_COMPONENTS/Configurator/ConfiguratorRoot.jsx @@ -1,7 +1,6 @@ import Drawer from '@mui/material/Drawer'; -import { styled } from '@mui/material/styles'; -import { useMode } from 'context'; -import useConfigurator from 'context/hooks/useConfigurator'; +import { useMode, useConfigurator } from 'context'; +import styled from 'styled-components'; export default styled(Drawer)(({ ownerState }) => { const { theme } = useMode(); diff --git a/src/layout/REUSABLE_COMPONENTS/Configurator/index.jsx b/src/layout/REUSABLE_COMPONENTS/Configurator/index.jsx index 1c27122..6b9d6d0 100644 --- a/src/layout/REUSABLE_COMPONENTS/Configurator/index.jsx +++ b/src/layout/REUSABLE_COMPONENTS/Configurator/index.jsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React from 'react'; import { Divider, Switch, @@ -8,19 +8,17 @@ import { OutlinedInput, Select, Slide, + TextField, + InputLabel, } from '@mui/material'; import ConfiguratorRoot from './ConfiguratorRoot'; import searchData from 'data/json-data/search.json'; -import { formFields } from 'data/formsConfig'; -import { TextField, InputLabel } from '@mui/material'; import { StyledFormControl } from 'layout/REUSABLE_STYLED_COMPONENTS/ReusableStyledComponents'; -import RCButton from 'layout/REUSABLE_COMPONENTS/RCBUTTON'; -import useConfigurator from 'context/hooks/useConfigurator'; -import MDBox from 'layout/REUSABLE_COMPONENTS/MDBOX'; -import RCTypography from 'layout/REUSABLE_COMPONENTS/RCTYPOGRAPHY'; import { Controller, useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; -import { useMode } from 'context'; +import { useMode, useConfigurator } from 'context'; +import { formFields } from 'data'; +import { MDBox, RCButton, RCTypography } from '..'; const SearchSettingsForm = ({ searchSettings, diff --git a/src/layout/REUSABLE_COMPONENTS/GenericActionButtons.jsx b/src/layout/REUSABLE_COMPONENTS/GenericActionButtons.jsx index 45d4d90..ecdedfc 100644 --- a/src/layout/REUSABLE_COMPONENTS/GenericActionButtons.jsx +++ b/src/layout/REUSABLE_COMPONENTS/GenericActionButtons.jsx @@ -1,13 +1,11 @@ -import React, { useState, useEffect, useCallback, useMemo } from 'react'; +import React, { useState, useEffect, useCallback } from 'react'; import { Box } from '@mui/material'; -import { useSnackbar } from 'notistack'; -import LoadingOverlay from './utils/system-utils/LoadingOverlay'; import AddCircleOutlineOutlined from '@mui/icons-material/AddCircleOutlineOutlined'; import RemoveCircleOutlineOutlined from '@mui/icons-material/RemoveCircleOutlineOutlined'; -import { useMode } from 'context'; -import useLoading from 'context/hooks/useLoading'; +import { useSnackbar } from 'notistack'; +import { useMode, useManager, useLoading } from 'context'; import { LoadingButton } from '@mui/lab'; -import useManager from 'context/state/useManager'; +import { LoadingOverlay } from '.'; const buttonSizeMap = { xs: 'extraSmall', @@ -88,57 +86,62 @@ const GenericActionButtons = ({ const { theme } = useMode(); const { enqueueSnackbar } = useSnackbar(); // Add this line to use Notistack const manager = useManager(); - if (!manager) { - return ; - } - const { - addItemToCart, - removeItemFromCart, - addItemToCollection, - removeItemFromCollection, - addItemToDeck, - removeItemFromDeck, - setHasUpdatedCards, - selectedCollectionId, - selectedDeckId, - selectedCartId, - } = manager; + // if (!manager) { + // return ; + // } + + // const { + // addItemToCart, + // removeItemFromCart, + // addItemToCollection, + // removeItemFromCollection, + // addItemToDeck, + // removeItemFromDeck, + // setHasUpdatedCards, + // } = manager; + + const [buttonSize, setButtonSize] = useState( + buttonSizeMap[cardSize] || 'medium' + ); + + useEffect(() => { + setButtonSize(buttonSizeMap[cardSize] || 'medium'); + }, [cardSize]); + // if (!manager) { + // return ; + // } const handleAction = useCallback( (actionType) => { try { switch (context) { case 'Collection': if (actionType === 'add') { - addItemToCollection(card); + manager.addItemToCollection(card); } else { - removeItemFromCollection(card); + manager.removeItemFromCollection(card); } - setHasUpdatedCards(true); - break; case 'Deck': if (actionType === 'add') { console.log(card); - addItemToDeck(card); + manager.addItemToDeck(card); } else { - removeItemFromDeck(card); + manager.removeItemFromDeck(card); } - setHasUpdatedCards(true); - break; case 'Cart': if (actionType === 'add') { - addItemToCart(card); + manager.addItemToCart(card); } else { - removeItemFromCart(card); + manager.removeItemFromCart(card); } - setHasUpdatedCards(true); - break; default: throw new Error('Invalid context'); } + manager.setHasUpdatedCards(true); + enqueueSnackbar(`Card ${actionType}ed in ${context}`, { variant: 'success', }); @@ -149,33 +152,17 @@ const GenericActionButtons = ({ }); } }, - [ - enqueueSnackbar, - context, - card, - addItemToCollection, - removeItemFromCollection, - addItemToDeck, - removeItemFromDeck, - addItemToCart, - removeItemFromCart, - selectedCollectionId, - selectedDeckId, - selectedCartId, - addItemToCart, - removeItemFromCart, - addItemToCollection, - removeItemFromCollection, - addItemToDeck, - removeItemFromDeck, - ] - ); - const [buttonSize, setButtonSize] = useState( - buttonSizeMap[cardSize] || 'medium' + [enqueueSnackbar, context, card, manager] ); - useEffect(() => { - setButtonSize(buttonSizeMap[cardSize] || 'medium'); - }, [cardSize]); + if (!manager) { + return ; + } + // const [buttonSize, setButtonSize] = useState( + // buttonSizeMap[cardSize] || 'medium' + // ); + // useEffect(() => { + // setButtonSize(buttonSizeMap[cardSize] || 'medium'); + // }, [cardSize]); return ( { alignItems: 'center', justifyContent: 'center', width: '100%', + my: pxToRem(10), borderRadius: theme.borderRadius, transitionProperty: 'color, background, box-shadow', transitionDuration: '0.35s', diff --git a/src/layout/REUSABLE_COMPONENTS/RCLOADINGBUTTON/index.jsx b/src/layout/REUSABLE_COMPONENTS/RCLOADINGBUTTON/index.jsx index bd7dfab..6161dd7 100644 --- a/src/layout/REUSABLE_COMPONENTS/RCLOADINGBUTTON/index.jsx +++ b/src/layout/REUSABLE_COMPONENTS/RCLOADINGBUTTON/index.jsx @@ -57,7 +57,7 @@ const RCLoadingButton = React.forwardRef( color={color} variant={variant} size={size} - ownerState={{ color, variant, size, circular }} + ownerState={{ color, variant, size, circular, sx }} // label={ // loading ? ( // @@ -87,7 +87,8 @@ const RCLoadingButton = React.forwardRef( } ); -RCLoadingButton.displayName = 'RCButton'; +RCLoadingButton.displayName = 'RCLoadingButton'; + RCLoadingButton.propTypes = { size: PropTypes.oneOf(['small', 'medium', 'large']), variant: PropTypes.oneOf(['contained', 'holo', 'outline']), diff --git a/src/layout/REUSABLE_COMPONENTS/RCTYPOGRAPHY/RCTypographyRoot.jsx b/src/layout/REUSABLE_COMPONENTS/RCTYPOGRAPHY/RCTypographyRoot.jsx index 2ff73db..0562614 100644 --- a/src/layout/REUSABLE_COMPONENTS/RCTYPOGRAPHY/RCTypographyRoot.jsx +++ b/src/layout/REUSABLE_COMPONENTS/RCTYPOGRAPHY/RCTypographyRoot.jsx @@ -1,6 +1,6 @@ import Typography from '@mui/material/Typography'; -import styled from 'styled-components'; import { useMode } from 'context'; +import styled from 'styled-components'; export default styled(Typography)(({ ownerstate }) => { // const { palette, typography, functions } = theme; diff --git a/src/layout/REUSABLE_COMPONENTS/RC_FORMS/RCDynamicForm.jsx b/src/layout/REUSABLE_COMPONENTS/RC_FORMS/RCDynamicForm.jsx index d587be9..424ae3c 100644 --- a/src/layout/REUSABLE_COMPONENTS/RC_FORMS/RCDynamicForm.jsx +++ b/src/layout/REUSABLE_COMPONENTS/RC_FORMS/RCDynamicForm.jsx @@ -2,17 +2,21 @@ import React, { useEffect, useState } from 'react'; import { Box, InputAdornment, Tooltip } from '@mui/material'; -import RCInput from './RCInput'; -import { Controller } from 'react-hook-form'; -import { useMode } from 'context'; import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline'; -import RCLoadingButton from 'layout/REUSABLE_COMPONENTS/RCLOADINGBUTTON'; + +import { Controller } from 'react-hook-form'; import { FormBox, FormFieldBox, } from 'layout/REUSABLE_STYLED_COMPONENTS/ReusableStyledComponents'; -import { useBreakpoint, useFormSubmission, useRCFormHook } from 'context/hooks'; +import { + useBreakpoint, + useFormSubmission, + useRCFormHook, + useMode, +} from 'context'; import { getFormFieldHandlers } from 'data'; +import { RCInput, RCLoadingButton } from '..'; const RCDynamicForm = ({ formKey, @@ -22,34 +26,38 @@ const RCDynamicForm = ({ updatedData, additonalData, }) => { - if (!inputs || typeof inputs !== 'object') { - console.error('Invalid inputs provided to RCDynamicForm:', inputs); - return null; // Or some fallback UI - } const { theme } = useMode(); const { isMobile } = useBreakpoint(); - const methods = useRCFormHook(formKey); - const { - control, - handleSubmit, - formState: { isSubmitting }, - reset, - } = methods; + const methods = useRCFormHook(formKey, initialData); + const { onSubmit } = useFormSubmission(getFormFieldHandlers(), formKey); + // State and Effects const [isMounted, setIsMounted] = useState(false); + const [formData, setFormData] = useState(initialData); + useEffect(() => { - console.log('MOUNTED', isMounted); setIsMounted(true); return () => { setIsMounted(false); }; }, []); - const [formData, setFormData] = useState(initialData); + useEffect(() => { - setFormData(updatedData || initialData); - reset(updatedData || initialData); // Reset form with new initial data - }, [updatedData, initialData, reset]); - const { onSubmit } = useFormSubmission(getFormFieldHandlers(), formKey); + setFormData(initialData); + methods.reset(initialData); // Reset form with new initial data + }, [initialData, methods]); + const optionsForUi = userInterfaceOptions ? userInterfaceOptions : {}; + + if (!inputs || typeof inputs !== 'object') { + console.error('Invalid inputs provided to RCDynamicForm:', inputs); + return null; // Or some fallback UI + } + const { + control, + handleSubmit, + formState: { isSubmitting }, + reset, + } = methods; return ( ( ))} - - {optionsForUi && optionsForUi.submitButton && ( - - - {optionsForUi.startIcon} - - ) : ( - - {} - - ) - } - variant="holo" - color="info" - label={optionsForUi.submitButtonLabel} - size="large" - /> - - )} - {optionsForUi && optionsForUi.deleteButton && ( - - - {optionsForUi.startIcon} - - ) : ( - - {} - - ) - } - variant="holo" - color="error" - label={optionsForUi.deleteButtonLabel} - size="large" - /> - - )} + + {optionsForUi && optionsForUi.submitButton && ( + + + {optionsForUi.startIcon} + + ) : ( + + {} + + ) + } + variant="holo" + color="info" + label={optionsForUi.submitButtonLabel} + size="large" + /> + + )} + {optionsForUi && optionsForUi.deleteButton && ( + + + {optionsForUi.startIcon} + + ) : ( + + {} + + ) + } + variant="holo" + color="error" + label={optionsForUi.deleteButtonLabel} + size="large" + /> + + )} + ); }; diff --git a/src/layout/REUSABLE_COMPONENTS/RC_FORMS/RCInput.jsx b/src/layout/REUSABLE_COMPONENTS/RC_FORMS/RCInput.jsx index 1024213..c2c6292 100644 --- a/src/layout/REUSABLE_COMPONENTS/RC_FORMS/RCInput.jsx +++ b/src/layout/REUSABLE_COMPONENTS/RC_FORMS/RCInput.jsx @@ -26,7 +26,7 @@ import { useMode, useSelectorActions, } from 'context'; -import RCSwitch from './RCSwitch'; +import { RCSwitch } from '..'; const RCInput = React.forwardRef( ( @@ -39,6 +39,11 @@ const RCInput = React.forwardRef( placeholder = '', error = false, helperText = '', + label = '', + name = '', + context = '', + InputProps = {}, + withContainer = false, // Default value for withContainer prop ...rest }, ref @@ -139,9 +144,7 @@ const RCInput = React.forwardRef( case 'select': return ( - - {rest?.label} - + {label}