| "version": "0.1.0", | "version": "0.1.0", | ||||
| "private": true, | "private": true, | ||||
| "dependencies": { | "dependencies": { | ||||
| "@emotion/react": "^11.10.5", | |||||
| "@emotion/styled": "^11.10.5", | |||||
| "@faker-js/faker": "^7.6.0", | "@faker-js/faker": "^7.6.0", | ||||
| "@mui/material": "^5.10.12", | |||||
| "@testing-library/jest-dom": "^5.14.1", | "@testing-library/jest-dom": "^5.14.1", | ||||
| "@testing-library/react": "^13.0.0", | "@testing-library/react": "^13.0.0", | ||||
| "@testing-library/user-event": "^13.2.1", | "@testing-library/user-event": "^13.2.1", | ||||
| "axios": "^1.1.3", | "axios": "^1.1.3", | ||||
| "date-fns": "^2.29.3", | "date-fns": "^2.29.3", | ||||
| "i18next": "^22.0.4", | "i18next": "^22.0.4", | ||||
| "qs": "^6.11.0", | |||||
| "react": "^18.2.0", | "react": "^18.2.0", | ||||
| "react-dom": "^18.2.0", | "react-dom": "^18.2.0", | ||||
| "react-helmet-async": "^1.3.0", | |||||
| "react-i18next": "^12.0.0", | "react-i18next": "^12.0.0", | ||||
| "react-scripts": "5.0.1", | "react-scripts": "5.0.1", | ||||
| "scss": "^0.2.4", | "scss": "^0.2.4", |
| import { createContext, FC, ReactNode } from "react"; | |||||
| import { ThemeProvider } from "@mui/material/styles"; | |||||
| import useToggleColorMode from "../hooks/useToggleColorMode"; | |||||
| export const ColorModeContext = createContext({ | |||||
| toggleColorMode: () => {}, | |||||
| }); | |||||
| const ColorModeProvider = ({ children }) => { | |||||
| const [toggleColorMode, theme] = useToggleColorMode(); | |||||
| return ( | |||||
| <ColorModeContext.Provider value={toggleColorMode}> | |||||
| <ThemeProvider theme={theme}> {children} </ThemeProvider> | |||||
| </ColorModeContext.Provider> | |||||
| ); | |||||
| }; | |||||
| export default ColorModeProvider; |
| import { useEffect, useState } from 'react'; | |||||
| function useDebounce<T>(value: T, delay?: number) { | |||||
| const [debouncedValue, setDebouncedValue] = useState<T>(value); | |||||
| useEffect(() => { | |||||
| const timer = setTimeout(() => setDebouncedValue(value), delay || 500); | |||||
| return () => { | |||||
| clearTimeout(timer); | |||||
| }; | |||||
| }, [value, delay]); | |||||
| return debouncedValue; | |||||
| }; | |||||
| export default useDebounce; |
| import { useState, useMemo } from 'react'; | |||||
| import { createTheme } from '@mui/material/styles'; | |||||
| import { | |||||
| authScopeSetHelper, | |||||
| authScopeStringGetHelper, | |||||
| } from '../util/helpers/authScopeHelpers'; | |||||
| import { PaletteMode } from '@mui/material'; | |||||
| const useToggleColorMode = () => { | |||||
| const currentColorMode = authScopeStringGetHelper('colorMode') || 'light'; | |||||
| const [mode, setMode] = useState<PaletteMode>(currentColorMode); | |||||
| const toggleColorMode = () => { | |||||
| const nextMode = mode === 'light' ? 'dark' : 'light'; | |||||
| setMode(nextMode); | |||||
| authScopeSetHelper('colorMode', nextMode); | |||||
| }; | |||||
| const theme = useMemo( | |||||
| () => | |||||
| createTheme({ | |||||
| palette: { | |||||
| mode | |||||
| } | |||||
| }), | |||||
| [mode] | |||||
| ); | |||||
| return [toggleColorMode, theme]; | |||||
| }; | |||||
| export default useToggleColorMode; |
| import React from 'react'; | import React from 'react'; | ||||
| import ReactDOM from 'react-dom/client'; | import ReactDOM from 'react-dom/client'; | ||||
| import './index.css'; | |||||
| import "./main.scss"; | |||||
| import App from './App'; | import App from './App'; | ||||
| import reportWebVitals from './reportWebVitals'; | |||||
| import { HelmetProvider } from 'react-helmet-async'; | |||||
| import './i18n'; | |||||
| import ColorModeProvider from './context/ColorModeContext'; | |||||
| const root = ReactDOM.createRoot( | const root = ReactDOM.createRoot( | ||||
| document.getElementById('root') as HTMLElement | document.getElementById('root') as HTMLElement | ||||
| ); | ); | ||||
| root.render( | root.render( | ||||
| <React.StrictMode> | |||||
| <App /> | |||||
| </React.StrictMode> | |||||
| <HelmetProvider> | |||||
| <React.StrictMode> | |||||
| <ColorModeProvider> | |||||
| <App /> | |||||
| </ColorModeProvider> | |||||
| </React.StrictMode> | |||||
| </HelmetProvider> | |||||
| ); | ); | ||||
| // 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(); |
| import { | |||||
| deleteRequest, | |||||
| getRequest, | |||||
| patchRequest, | |||||
| replaceInUrl, | |||||
| postRequest, | |||||
| } from './index'; | |||||
| import apiEndpoints from './apiEndpoints'; | |||||
| export const getAccount = (accountUid: string) => | |||||
| getRequest(replaceInUrl(apiEndpoints.accounts.get, { accountUid })); | |||||
| export const getAccountUsers = (accountUid: string) => | |||||
| getRequest(replaceInUrl(apiEndpoints.accounts.getUsers, { accountUid })); | |||||
| export const getUserPermissions = (currentAccountUid: string, currentUserUid: string) => | |||||
| getRequest( | |||||
| replaceInUrl(apiEndpoints.accounts.getCurrentUserPermissions, { | |||||
| currentAccountUid, | |||||
| currentUserUid, | |||||
| }), | |||||
| ); | |||||
| export const getAccountAddresses = (accountUid: string) => | |||||
| getRequest(replaceInUrl(apiEndpoints.accounts.getAddresses, { accountUid })); | |||||
| export const getAccountSettingsRequest = (accountUid: string) => | |||||
| getRequest(replaceInUrl(apiEndpoints.accounts.getSettings, { accountUid })); | |||||
| export const updateAccountAddressRequest = (accountUid: string, addressUid: string, data: any) => | |||||
| patchRequest( | |||||
| replaceInUrl(apiEndpoints.accounts.updateAddress, { | |||||
| accountUid, | |||||
| addressUid, | |||||
| }), | |||||
| data, | |||||
| ); | |||||
| export const deleteAccountAddressRequest = (accountUid: string, addressUid: string) => | |||||
| deleteRequest( | |||||
| replaceInUrl(apiEndpoints.accounts.deleteAddress, { | |||||
| accountUid, | |||||
| addressUid, | |||||
| }), | |||||
| ); | |||||
| export const postNewAccountUserRequest = (accountUid: string, data: any) => | |||||
| postRequest( | |||||
| replaceInUrl(apiEndpoints.accounts.createUser, { | |||||
| accountUid, | |||||
| }), | |||||
| data, | |||||
| ); | |||||
| export const updateAccountUserRequest = ( | |||||
| accountUid: string, | |||||
| userUid: string, | |||||
| actionType: string, | |||||
| data: any, | |||||
| ) => | |||||
| patchRequest( | |||||
| replaceInUrl(apiEndpoints.accounts.updateUser, { | |||||
| accountUid, | |||||
| userUid, | |||||
| actionType, | |||||
| }), | |||||
| data, | |||||
| ); | |||||
| export const postAgreementRequest = (data: any) => | |||||
| postRequest(apiEndpoints.accounts.agreement, data); |
| export default { | |||||
| accounts: { | |||||
| get: 'accounts/{accountUid}', | |||||
| getCurrentUserPermissions: | |||||
| 'accounts/{currentAccountUid}/users/{currentUserUid}/permissions', | |||||
| getAddresses: 'accounts/{accountUid}/addresses', | |||||
| updateAddress: 'account/{accountUid}/addresses/{addressUid}', | |||||
| deleteAddress: 'accounts/{accountUid}/addresses/{addressUid}', | |||||
| getUsers: 'accounts/{accountUid}/users', | |||||
| createUser: 'accounts/{accountUid}/users', | |||||
| updateUser: 'account/{accountUid}/users/{userUid}?actionType={actionType}', | |||||
| deleteUser: 'accounts/{accountUid}/users/{userUid}', | |||||
| getSettings: 'accounts/{accountUid}/settings', | |||||
| getIraSettings: 'accounts/{accountUid}/iraSettings', | |||||
| getSettingsRegistration: 'application/settings', | |||||
| agreement: 'accounts/agreement', | |||||
| }, | |||||
| authentications: { | |||||
| getUsernames: 'authenticate/usernames', | |||||
| login: 'authenticate', | |||||
| getUserSecurityQuestion: 'users/username/securityquestion', | |||||
| confirmSecurityQuestion: 'authenticate/confirm', | |||||
| confirmForgotPassword: 'users/passwords/reset_token', | |||||
| resetPassword: 'users/passwords', | |||||
| refreshToken: '/authenticate/refresh', | |||||
| generateToken: '/authenticate/generate', | |||||
| authenticate: | |||||
| '/authenticate?fp={fp}&offer={offer}&landingPageUrl={landingPageUrl}®istrationFlowType={registrationFlowType}', | |||||
| confirmAuthentication: | |||||
| '/authenticate/confirm?fp={fp}&offer={offer}&landingPageUrl={landingPageUrl}®istrationFlowType={registrationFlowType}', | |||||
| }, | |||||
| bankAccounts: { | |||||
| get: 'accounts/{accountUid}/bankaccounts', | |||||
| getBankAccount: | |||||
| 'accounts/{accountUid}/bankaccounts/{bankAccountUid}?type={type}', | |||||
| getBankAccountsByType: | |||||
| 'accounts/{accountUid}/bankaccounts?type={type}&active=true', | |||||
| getBankDetailsByRoutingNumber: 'banks/{routingNumber}', | |||||
| newAccount: 'accounts/{accountUid}/bankaccounts', | |||||
| deleteAccount: | |||||
| 'accounts/{accountUid}/bankaccounts/{bankAccountUid}?type={type}', | |||||
| verify: '/accounts/{accountUid}/bankaccountverification/{bankAccountUid}', | |||||
| postBankAccountRegistration: '/accounts/{applicationUid}/bankaccounts', | |||||
| getRegistration: 'banks/{applicationUid}/bankaccounts', | |||||
| }, | |||||
| documents: { | |||||
| getDocuments: 'accounts/{accountUid}/documents?year={year}', | |||||
| getDocument: 'accounts/{accountUid}/documents/{documentType}', | |||||
| }, | |||||
| countries: '/countries', | |||||
| metalStream: { | |||||
| getMetalStreamSettings: 'accounts/{accountUid}/metalstream', | |||||
| getMetalStreamFundings: 'applications/{applicationUid}/metalStreamFunding', | |||||
| }, | |||||
| orders: { | |||||
| buyForStorage: '/accounts/{accountUid}/orders/buyForStorage', | |||||
| buyForDelivery: '/accounts/{accountUid}/orders/buyForDelivery', | |||||
| verifyBuyForDelivery: '/accounts/{accountUid}/orders/buyForDelivery/verify', | |||||
| sellFromStorage: '/accounts/{accountUid}/orders/sellFromStorage', | |||||
| fractionalConversion: '/accounts/{accountUid}/orders/fractionalConversion', | |||||
| deliverFromStorageVerify: | |||||
| '/accounts/{accountUid}/orders/deliverFromStorage/verify', | |||||
| deliverFromStorage: '/accounts/{accountUid}/orders/deliverFromStorage', | |||||
| iraCashDistribution: '/accounts/{accountUid}/orders/iraCashDistribution', | |||||
| iraCashTransfer: '/accounts/{accountUid}/orders/iraCashTransfer', | |||||
| iraFeeWithdrawal: 'accounts/{accountUid}/orders/iraFeeWithdrawal', | |||||
| achDeposit: 'accounts/{accountUid}/orders/achDeposit', | |||||
| wireWithdrawal: '/accounts/{accountUid}/orders/wireWithdrawal', | |||||
| checkWithdrawal: '/accounts/{accountUid}/orders/checkWithdrawal', | |||||
| }, | |||||
| portfolio: { | |||||
| getPortfolioValuations: 'accounts/{accountUid}/portfolio/valuations', | |||||
| getPortfolioMetalPrices: 'marketprices', | |||||
| getPortfolioHoldings: | |||||
| 'accounts/{accountUid}/portfolio/products?valuation=true', | |||||
| getPortfolioProductCodes: '/accounts/{accountUid}/portfolio/productcodes', | |||||
| getPortfolioBalances: '/accounts/{accountUid}/portfolio/balances', | |||||
| getPortfolioProductBySymbol: | |||||
| '/accounts/{accountUid}/portfolio/products/{symbol}', | |||||
| getPortfolioTransactions: '/accounts/{accountUid}/transactions', | |||||
| getPortfolioSingleTransaction: | |||||
| '/accounts/{accountUid}/transactions/{transactionUid}', | |||||
| getProductPortoflioTransactions: 'accounts/{accountUid}/transactions', | |||||
| getRecentPortfolioTransactions: | |||||
| 'accounts/{accountUid}/transactions?content=Recent', | |||||
| getFinancialPortfolioTransactions: 'accounts/{accountUid}/transactions', | |||||
| getFinancialPortfolioPendingTransactions: | |||||
| 'accounts/{accountUid}/transactions/fundinghistory', | |||||
| patchFinancialPortfolioPendingTransactions: | |||||
| '/accounts/{accountUid}/transactions/fundinghistory/{depositKey}', | |||||
| }, | |||||
| products: { | |||||
| getPrices: '/accounts/{accountUid}/products/prices', | |||||
| prices: 'accounts/{accountUid}/products/prices?side={side}', | |||||
| tiers: | |||||
| '/accounts/{accountUid}/products/prices/{symbol}/tiers?side={side}&location={location}', | |||||
| symbolPrices: '/accounts/{accountUid}/products/{symbol}/prices?side={side}', | |||||
| getPricesRegistration: 'applications/{applicationUid}/products/prices', | |||||
| }, | |||||
| settings: { | |||||
| get: 'settings', | |||||
| }, | |||||
| taxForms: { | |||||
| getTaxForms: 'settings/taxForms/{applicationType}', | |||||
| }, | |||||
| users: { | |||||
| getAccounts: '/users/{userUid}/accounts', | |||||
| getRegistrationAccounts: '/users/{userUid}/accounts', | |||||
| updateUser: '/users/{userUid}?updateUserActionType={actionType}', | |||||
| updateUserPassword: '/users/{userUid}/passwords', | |||||
| logout: '/users/{userUid}/logout', | |||||
| getUsernames: '/users/email', | |||||
| createUser: | |||||
| '/users?fp={fp}&offer={offer}&landingPageUrl={landingPageUrl}®istrationFlowType={registrationFlowType}', | |||||
| updateUserRegistration: '/users/{userUid}', | |||||
| invite: '/users/invite', | |||||
| }, | |||||
| applications: { | |||||
| application: '/applications/{applicationUid}', | |||||
| addPerson: '/applications/{applicationUid}/persons', | |||||
| updatePerson: '/applications/{applicationUid}/persons/{personUid}', | |||||
| addPersonWithGiftState: | |||||
| '/applications/{applicationUid}/UTMA/persons?giftState={giftState}', | |||||
| updatePersonWithGiftState: | |||||
| '/applications/{applicationUid}/UTMA/persons/{personUid}?giftState={giftState}', | |||||
| addPersonWithCompanyName: | |||||
| '/applications/{applicationUid}/IRA/persons?companyName={companyName}', | |||||
| updatePersonWithCompanyName: | |||||
| '/applications/{applicationUid}/IRA/persons/{personUid}?companyName={companyName}', | |||||
| submitLegalEntity: '/applications/{applicationUid}/legalEntities', | |||||
| updateLegalEntity: | |||||
| '/applications/{applicationUid}/legalEntities/{personUid}', | |||||
| postNonIraFunding: '/applications/{applicationUid}/funding', | |||||
| postIraFunding: '/applications/{applicationUid}/iraFunding', | |||||
| postMSFunding: '/applications/{applicationUid}/metalStreamFunding', | |||||
| consent: '/applications/{applicationUid}/consents', | |||||
| updateConsent: `/applications/{applicationUid}/consents/{agreementConsentUid}`, | |||||
| submitMetalStreamRegistration: | |||||
| '/applications/{applicationUid}/metalStreamFunding', | |||||
| }, | |||||
| common: { | |||||
| getCountries: '/countries/', | |||||
| getTaxForms: '/taxForms/', | |||||
| getContributionYears: 'contributionYears', | |||||
| getCountryStates: '/countries/{iso3CountryCode}/states/', | |||||
| getSecurityQuestions: '/registration/securityQuestions/', | |||||
| getPortalSecurityQuestions: '/securityQuestions', | |||||
| }, | |||||
| plaid: { | |||||
| getToken: '/bankaccounts/createplaidlinktoken', | |||||
| }, | |||||
| affiliate: { | |||||
| setCookie: '/affiliate/picture', | |||||
| setFingerprint: '/affiliate/fingerprint', | |||||
| }, | |||||
| }; |
| import axios, { AxiosError, AxiosResponse } from 'axios'; | |||||
| import queryString from 'qs'; | |||||
| const request = axios.create({ | |||||
| baseURL: process.env.REACT_APP_BASE_API_URL, | |||||
| headers: { | |||||
| 'Content-Type': 'application/json', | |||||
| }, | |||||
| withCredentials: true, | |||||
| paramsSerializer: { | |||||
| encode: (params) => queryString.stringify(params, { arrayFormat: 'comma' }) | |||||
| } | |||||
| }); | |||||
| export const getRequest = (url: string, params = {}, options = {}) => | |||||
| request.get(url, { params, ...options }); | |||||
| export const postRequest = (url: string, data?: any, params = null, options = {}) => | |||||
| request.post(url, data, { params, ...options }); | |||||
| export const putRequest = (url: string, data: any, params = null, options = {}) => | |||||
| request.put(url, data, { params, ...options }); | |||||
| export const patchRequest = (url: string, data: any, params = null, options = {}) => | |||||
| request.patch(url, data, { params, ...options }); | |||||
| export const deleteRequest = (url: string, params = null, options = {}) => | |||||
| request.delete(url, { params, ...options }); | |||||
| export const downloadRequest = (url: string, params = null, options = {}) => | |||||
| request.get(url, { params, ...options, responseType: 'blob' }); | |||||
| export const replaceInUrl = (url: string, pathVariables: any = {}) => { | |||||
| const keys = Object.keys(pathVariables); | |||||
| if (!keys.length) { | |||||
| return url; | |||||
| } | |||||
| return keys.reduce( | |||||
| (acc, key) => acc.replace(`{${key}}`, pathVariables[`${key}`]), | |||||
| url, | |||||
| ); | |||||
| }; | |||||
| export const addHeaderToken = (token: string) => { | |||||
| request.defaults.headers.Authorization = `Bearer ${token}`; | |||||
| }; | |||||
| export const addHeaderCookie = (key: string, value: string) => { | |||||
| request.defaults.headers[`${key}`] = value; | |||||
| }; | |||||
| export const removeHeaderToken = () => { | |||||
| delete request.defaults.headers.Authorization; | |||||
| }; | |||||
| const onResponse = (response: AxiosResponse): AxiosResponse => | |||||
| response; | |||||
| export const attachPostRequestListener = (postRequestListener: (response: AxiosError) => void) => { | |||||
| request.interceptors.response.use( | |||||
| onResponse, | |||||
| (response) => postRequestListener(response) | |||||
| ); | |||||
| }; | |||||
| export const apiDefaultUrl = request.defaults.baseURL; |
| import axios from 'axios'; | |||||
| const JSON_SERVER_ENDPOINT = 'http://localhost:4000'; | |||||
| const request = axios.create({ | |||||
| baseURL: JSON_SERVER_ENDPOINT, | |||||
| headers: { | |||||
| 'Content-Type': 'application/json', | |||||
| }, | |||||
| }); | |||||
| export const getRequest = (url: string, params = null, options = {}) => | |||||
| request.get(url, { params, ...options }); |
| import { getRequest, postRequest, replaceInUrl } from './index'; | |||||
| import apiEndpoints from './apiEndpoints'; | |||||
| export const getUsernames = (emailorusername: string) => | |||||
| getRequest(apiEndpoints.authentications.getUsernames, { | |||||
| emailorusername, | |||||
| }); | |||||
| export const attemptLogin = (payload: string) => | |||||
| postRequest(apiEndpoints.authentications.login, payload); | |||||
| export const updateSecurityAnswer = (payload: any) => | |||||
| postRequest(apiEndpoints.authentications.confirmSecurityQuestion, payload); | |||||
| export const refreshTokenRequest = (payload: any) => | |||||
| postRequest(apiEndpoints.authentications.refreshToken, payload); | |||||
| export const logoutUserRequest = (userUid: string) => | |||||
| postRequest( | |||||
| replaceInUrl(apiEndpoints.users.logout, { | |||||
| userUid, | |||||
| }), | |||||
| ); | |||||
| export const generateTokenRequest = (payload: any) => | |||||
| postRequest(apiEndpoints.authentications.generateToken, payload); |