Skip to content

Develop -> Main - #13

Open
hasanihendrix1 wants to merge 127 commits into
mainfrom
develop
Open

Develop -> Main#13
hasanihendrix1 wants to merge 127 commits into
mainfrom
develop

Conversation

@hasanihendrix1

@hasanihendrix1 hasanihendrix1 commented Apr 6, 2024

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Transformed application into KontraX, a real estate wholesaling platform.
    • Added comprehensive user authentication, data visualization, and lead management features.
    • Introduced Amplify functions for email processing, API interactions, and skip tracing.
    • Implemented custom React contexts and hooks for enhanced state management.
    • New pages for authentication, dashboard, leads, and prospects with improved UI/UX.
  • Enhancements

    • Updated project configuration for ESLint, .gitignore, and VSCode settings.
    • Enhanced CSS for responsive design and typography.
    • Improved application's entry point setup and global state management.
  • Documentation

    • Updated README.md with project details and development stages.
    • Added TODO.md outlining development tasks.
    • Provided guidance on configuring environment variables for AWS Lambda functions.
    • Introduced Command Hooks in Amplify for running custom scripts during CLI events.
  • Bug Fixes

    • Addressed UI/UX issues across the application for a smoother user experience.
  • Chores

    • Cleaned up CSS files to ensure a tidy project structure.

hasanihendrix1 and others added 14 commits March 28, 2024 23:40
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Apr 6, 2024

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

The project has undergone a significant transformation, evolving into KontraX, a specialized real estate wholesaling application. This metamorphosis involved updates across various files to enhance functionality, UI/UX, and integration with backend services. Key updates include setting up ESLint for React, refining .gitignore and VSCode settings for better development experience, comprehensive changes in the src directory to introduce new features and components, and leveraging AWS Amplify for backend functions. The aim is to provide a robust platform for real estate wholesaling needs.

Changes

Files Change Summary
.eslintrc.json Configured ESLint for React projects.
.gitignore Updated rules to exclude node_modules, .env, build artifacts, and specific config files.
.vscode/settings.json Configured file exclusions and custom spell checker words.
README.md Updated for KontraX, detailing its purpose, tech stack, features, and development stages.
TODO.md Outlined development tasks across UI elements, API integration, and data visualization.
amplify/.../project-config.json, amplify/README.md, amplify/backend/function/*, amplify/backend/types/..., amplify/hooks/README.md Enhanced AWS Amplify configuration for backend services and functions.
clean-css.js, public/index.html, public/robots.txt Implemented utilities for CSS management and set up the public-facing HTML structure.
src/*, src/context/*, src/hooks/*, src/pages/*, src/utils/* Comprehensive updates to React components, contexts, hooks, pages, and utilities for KontraX.
src/index.css, src/index.js, src/reportWebVitals.js, src/setupTests.js, src/tests/App.test.js Updated styles, React app entry point, and test setup.

"In the realm of code, where rabbits dare to tread,
🐾 A project shifts, KontraX is bred.
With React in heart, and Amplify in hand,
A real estate dream, across the digital land.
🏡 From .gitignore to src, changes flow,
As seeds of tomorrow, in today we sow."
🌱🚀


🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@hasanihendrix1

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 37

Review Status

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between a305424 and d461f55.
Files ignored due to path filters (47)
  • amplify.yml is excluded by !**/*.yml
  • amplify/backend/amplify-meta.json is excluded by !**/*.json
  • amplify/backend/api/APIGatewayAuthStack.json is excluded by !**/*.json
  • amplify/backend/api/emailing/cli-inputs.json is excluded by !**/*.json
  • amplify/backend/api/prospecting/cli-inputs.json is excluded by !**/*.json
  • amplify/backend/auth/kontrax/cli-inputs.json is excluded by !**/*.json
  • amplify/backend/backend-config.json is excluded by !**/*.json
  • amplify/backend/function/emailApiProcessor/custom-policies.json is excluded by !**/*.json
  • amplify/backend/function/emailApiProcessor/emailApiProcessor-cloudformation-template.json is excluded by !**/*.json
  • amplify/backend/function/emailApiProcessor/function-parameters.json is excluded by !**/*.json
  • amplify/backend/function/emailApiProcessor/parameters.json is excluded by !**/*.json
  • amplify/backend/function/emailApiProcessor/src/event.json is excluded by !**/*.json
  • amplify/backend/function/emailApiProcessor/src/package-lock.json is excluded by !**/package-lock.json, !**/*.json
  • amplify/backend/function/emailApiProcessor/src/package.json is excluded by !**/*.json
  • amplify/backend/function/kontraxCommonLibsLayerDev/kontraxCommonLibsLayerDev-awscloudformation-template.json is excluded by !**/*.json
  • amplify/backend/function/kontraxCommonLibsLayerDev/layer-configuration.json is excluded by !**/*.json
  • amplify/backend/function/kontraxCommonLibsLayerDev/lib/nodejs/package-lock.json is excluded by !**/package-lock.json, !**/*.json
  • amplify/backend/function/kontraxCommonLibsLayerDev/lib/nodejs/package.json is excluded by !**/*.json
  • amplify/backend/function/kontraxCommonLibsLayerDev/parameters.json is excluded by !**/*.json
  • amplify/backend/function/prospectsApiProcessor/custom-policies.json is excluded by !**/*.json
  • amplify/backend/function/prospectsApiProcessor/function-parameters.json is excluded by !**/*.json
  • amplify/backend/function/prospectsApiProcessor/parameters.json is excluded by !**/*.json
  • amplify/backend/function/prospectsApiProcessor/prospectsApiProcessor-cloudformation-template.json is excluded by !**/*.json
  • amplify/backend/function/prospectsApiProcessor/src/event.json is excluded by !**/*.json
  • amplify/backend/function/prospectsApiProcessor/src/event2.json is excluded by !**/*.json
  • amplify/backend/function/prospectsApiProcessor/src/package-lock.json is excluded by !**/package-lock.json, !**/*.json
  • amplify/backend/function/prospectsApiProcessor/src/package.json is excluded by !**/*.json
  • amplify/backend/function/skiptraceApiProcessor/custom-policies.json is excluded by !**/*.json
  • amplify/backend/function/skiptraceApiProcessor/function-parameters.json is excluded by !**/*.json
  • amplify/backend/function/skiptraceApiProcessor/parameters.json is excluded by !**/*.json
  • amplify/backend/function/skiptraceApiProcessor/skiptraceApiProcessor-cloudformation-template.json is excluded by !**/*.json
  • amplify/backend/function/skiptraceApiProcessor/src/event.json is excluded by !**/*.json
  • amplify/backend/function/skiptraceApiProcessor/src/package-lock.json is excluded by !**/package-lock.json, !**/*.json
  • amplify/backend/function/skiptraceApiProcessor/src/package.json is excluded by !**/*.json
  • amplify/backend/tags.json is excluded by !**/*.json
  • amplify/cli.json is excluded by !**/*.json
  • amplify/team-provider-info.json is excluded by !**/*.json
  • obfuscatorConfig.json is excluded by !**/*.json
  • package-lock.json is excluded by !**/package-lock.json, !**/*.json
  • package.json is excluded by !**/*.json
  • public/favicon.ico is excluded by !**/*.ico, !**/*.ico
  • public/logo192.png is excluded by !**/*.png, !**/*.png
  • public/logo512.png is excluded by !**/*.png, !**/*.png
  • public/manifest.json is excluded by !**/*.json
  • src/assets/images/logo.png is excluded by !**/*.png, !**/*.png
  • src/assets/images/propertyAnalysis.png is excluded by !**/*.png, !**/*.png
  • src/assets/images/techProperties.jpg is excluded by !**/*.jpg, !**/*.jpg
Files selected for processing (138)
  • .eslintrc.json (1 hunks)
  • .gitignore (1 hunks)
  • .vscode/settings.json (1 hunks)
  • README.md (1 hunks)
  • TODO.md (1 hunks)
  • amplify/.config/project-config.json (1 hunks)
  • amplify/README.md (1 hunks)
  • amplify/backend/function/emailApiProcessor/amplify.state (1 hunks)
  • amplify/backend/function/emailApiProcessor/src/app.js (1 hunks)
  • amplify/backend/function/emailApiProcessor/src/index.js (1 hunks)
  • amplify/backend/function/kontraxCommonLibsLayerDev/lib/nodejs/README.txt (1 hunks)
  • amplify/backend/function/prospectsApiProcessor/amplify.state (1 hunks)
  • amplify/backend/function/prospectsApiProcessor/src/app.js (1 hunks)
  • amplify/backend/function/prospectsApiProcessor/src/index.js (1 hunks)
  • amplify/backend/function/skiptraceApiProcessor/amplify.state (1 hunks)
  • amplify/backend/function/skiptraceApiProcessor/src/app.js (1 hunks)
  • amplify/backend/function/skiptraceApiProcessor/src/index.js (1 hunks)
  • amplify/backend/types/amplify-dependent-resources-ref.d.ts (1 hunks)
  • amplify/hooks/README.md (1 hunks)
  • clean-css.js (1 hunks)
  • public/index.html (1 hunks)
  • public/robots.txt (1 hunks)
  • src/App.css (1 hunks)
  • src/App.js (1 hunks)
  • src/AppContent.js (1 hunks)
  • src/assets/theme.css (1 hunks)
  • src/components/HeaderMapping/HeaderMapping.css (1 hunks)
  • src/components/HeaderMapping/index.js (1 hunks)
  • src/components/PageHeader/PageHeader.css (1 hunks)
  • src/components/PageHeader/index.js (1 hunks)
  • src/components/ProtectedRoute/index.js (1 hunks)
  • src/components/dataVisualizations/Charts/BubbleChart/index.js (1 hunks)
  • src/components/dataVisualizations/Charts/CustomPieChart/CustomPieChart.css (1 hunks)
  • src/components/dataVisualizations/Charts/CustomPieChart/index.js (1 hunks)
  • src/components/dataVisualizations/Charts/RadarChart/RadarChart.css (1 hunks)
  • src/components/dataVisualizations/Charts/RadarChart/index.js (1 hunks)
  • src/components/dataVisualizations/Charts/StackedBarChart/StackedBarChart.css (1 hunks)
  • src/components/dataVisualizations/Charts/StackedBarChart/index.js (1 hunks)
  • src/components/dataVisualizations/SingleValueCard/SingleValueCard.css (1 hunks)
  • src/components/dataVisualizations/SingleValueCard/index.js (1 hunks)
  • src/components/dataVisualizations/SingleValueCardsGrid/SingleValueCardsGrid.css (1 hunks)
  • src/components/dataVisualizations/SingleValueCardsGrid/index.js (1 hunks)
  • src/components/layout/BottomNav/BottomNav.css (1 hunks)
  • src/components/layout/BottomNav/index.js (1 hunks)
  • src/components/layout/HomePageLayout/HomePageLayout.css (1 hunks)
  • src/components/layout/HomePageLayout/index.js (1 hunks)
  • src/components/layout/LeftNav/LeftNav.css (1 hunks)
  • src/components/layout/LeftNav/NavListItem/index.js (1 hunks)
  • src/components/layout/LeftNav/NavigationDrawer/index.js (1 hunks)
  • src/components/layout/LeftNav/index.js (1 hunks)
  • src/components/layout/Section/Section.css (1 hunks)
  • src/components/layout/Section/index.js (1 hunks)
  • src/components/layout/SignUpLayout/SignUpLayout.css (1 hunks)
  • src/components/layout/SignUpLayout/index.js (1 hunks)
  • src/components/layout/TopNav/TopNav.css (1 hunks)
  • src/components/layout/TopNav/index.js (1 hunks)
  • src/components/modal/HeaderMappingModal/HeaderMappingModal.css (1 hunks)
  • src/components/modal/HeaderMappingModal/index.js (1 hunks)
  • src/components/modal/PropertyInputModal/PropertyInputModal.css (1 hunks)
  • src/components/modal/PropertyInputModal/index.js (1 hunks)
  • src/components/modal/SkiptraceListModal/FileProcessing.js (1 hunks)
  • src/components/modal/SkiptraceListModal/FileUploadArea.js (1 hunks)
  • src/components/modal/SkiptraceListModal/SkiptraceListModal.css (1 hunks)
  • src/components/modal/SkiptraceListModal/index.js (1 hunks)
  • src/components/modal/UserLoginModal/GoogleSignInButton/GoogleSignInButton.css (1 hunks)
  • src/components/modal/UserLoginModal/GoogleSignInButton/index.js (1 hunks)
  • src/components/modal/UserLoginModal/NewAccountModal/NewAccountModal.css (1 hunks)
  • src/components/modal/UserLoginModal/NewAccountModal/index.js (1 hunks)
  • src/components/modal/UserLoginModal/UserLoginModal.css (1 hunks)
  • src/components/modal/UserLoginModal/VerifyAccountModal/VerifyAccountModal.css (1 hunks)
  • src/components/modal/UserLoginModal/VerifyAccountModal/index.js (1 hunks)
  • src/components/modal/UserLoginModal/index.js (1 hunks)
  • src/components/shared/Button/Button.css (1 hunks)
  • src/components/shared/Button/CancelButton.js (1 hunks)
  • src/components/shared/Button/index.js (1 hunks)
  • src/components/shared/ChartToolTip/ChartToolTip.css (1 hunks)
  • src/components/shared/ChartToolTip/index.js (1 hunks)
  • src/components/shared/EmailSentNotification/EmailSentNotification.css (1 hunks)
  • src/components/shared/EmailSentNotification/index.js (1 hunks)
  • src/components/shared/FilterToggleButton/index.js (1 hunks)
  • src/components/shared/InputField/index.js (1 hunks)
  • src/components/shared/LoadingSpinner/LoadingSpinner.css (1 hunks)
  • src/components/shared/LoadingSpinner/index.js (1 hunks)
  • src/components/shared/MessageDisplay/MessageDisplay.css (1 hunks)
  • src/components/shared/MessageDisplay/index.js (1 hunks)
  • src/components/shared/Pagination/Pagination.css (1 hunks)
  • src/components/shared/Pagination/index.js (1 hunks)
  • src/components/shared/SearchBar/SearchBar.css (1 hunks)
  • src/components/shared/SearchBar/index.js (1 hunks)
  • src/components/shared/SmallNotification/SmallNotification.css (1 hunks)
  • src/components/shared/SmallNotification/index.js (1 hunks)
  • src/components/shared/dropdowns/CustomDropdown/CustomDropdown.css (1 hunks)
  • src/components/shared/dropdowns/CustomDropdown/index.js (1 hunks)
  • src/components/shared/dropdowns/FilterBar/FilterBar.css (1 hunks)
  • src/components/shared/dropdowns/FilterBar/index.js (1 hunks)
  • src/components/shared/modal/ErrorModal/ErrorModal.css (1 hunks)
  • src/components/shared/modal/ErrorModal/index.js (1 hunks)
  • src/components/tableCells/AnalyzeOfferCell/AnalyzeOfferCell.css (1 hunks)
  • src/components/tableCells/AnalyzeOfferCell/index.js (1 hunks)
  • src/components/tableCells/ContactDetailsCell/ContactDetailsCell.css (1 hunks)
  • src/components/tableCells/ContactDetailsCell/index.js (1 hunks)
  • src/components/tableCells/FollowUpCell/FollowUpCell.css (1 hunks)
  • src/components/tableCells/FollowUpCell/index.js (1 hunks)
  • src/components/tableCells/MarketCell/MarketCell.css (1 hunks)
  • src/components/tableCells/MarketCell/index.js (1 hunks)
  • src/components/tableCells/OffersSentCell/OffersSentCell.css (1 hunks)
  • src/components/tableCells/OffersSentCell/index.js (1 hunks)
  • src/components/tableCells/StatusLabelCell/StatusLabelCell.css (1 hunks)
  • src/components/tableCells/StatusLabelCell/index.js (1 hunks)
  • src/components/tables/LeadsTable/LeadsTable.css (1 hunks)
  • src/components/tables/LeadsTable/index.js (1 hunks)
  • src/context/global/pageHeader/PageHeaderContext.js (1 hunks)
  • src/context/global/pageHeader/PageHeaderProvider.js (1 hunks)
  • src/context/index.js (1 hunks)
  • src/hooks/useDashboardData.js (1 hunks)
  • src/hooks/useLeadsData.js (1 hunks)
  • src/hooks/usePageHeader.js (1 hunks)
  • src/hooks/useProspectData.js (1 hunks)
  • src/hooks/useSmallNotification.js (1 hunks)
  • src/index.css (1 hunks)
  • src/index.js (1 hunks)
  • src/pages/Auth/Auth.css (1 hunks)
  • src/pages/Auth/index.js (1 hunks)
  • src/pages/Dashboard/Dashboard.css (1 hunks)
  • src/pages/Dashboard/index.js (1 hunks)
  • src/pages/Leads/Leads.css (1 hunks)
  • src/pages/Leads/index.js (1 hunks)
  • src/pages/Prospects/Prospects.css (1 hunks)
  • src/pages/Prospects/index.js (1 hunks)
  • src/reportWebVitals.js (1 hunks)
  • src/setupTests.js (1 hunks)
  • src/tests/App.test.js (1 hunks)
  • src/utils/apiCommonFunctions.js (1 hunks)
  • src/utils/commonFunctions.js (1 hunks)
  • src/utils/constants/apiConstants.js (1 hunks)
  • src/utils/constants/appConstants.js (1 hunks)
  • src/utils/constants/errorConstants.js (1 hunks)
  • src/utils/constants/uiConstants.js (1 hunks)
Files skipped from review due to trivial changes (44)
  • amplify/README.md
  • amplify/backend/function/kontraxCommonLibsLayerDev/lib/nodejs/README.txt
  • amplify/backend/function/prospectsApiProcessor/amplify.state
  • amplify/hooks/README.md
  • public/index.html
  • public/robots.txt
  • src/App.css
  • src/components/HeaderMapping/HeaderMapping.css
  • src/components/PageHeader/PageHeader.css
  • src/components/PageHeader/index.js
  • src/components/dataVisualizations/Charts/CustomPieChart/CustomPieChart.css
  • src/components/dataVisualizations/Charts/CustomPieChart/index.js
  • src/components/dataVisualizations/Charts/RadarChart/RadarChart.css
  • src/components/dataVisualizations/Charts/StackedBarChart/StackedBarChart.css
  • src/components/dataVisualizations/SingleValueCardsGrid/SingleValueCardsGrid.css
  • src/components/layout/LeftNav/LeftNav.css
  • src/components/layout/LeftNav/NavListItem/index.js
  • src/components/layout/Section/Section.css
  • src/components/layout/Section/index.js
  • src/components/layout/SignUpLayout/SignUpLayout.css
  • src/components/modal/HeaderMappingModal/HeaderMappingModal.css
  • src/components/modal/SkiptraceListModal/FileUploadArea.js
  • src/components/modal/UserLoginModal/GoogleSignInButton/index.js
  • src/components/modal/UserLoginModal/VerifyAccountModal/VerifyAccountModal.css
  • src/components/shared/Button/Button.css
  • src/components/shared/ChartToolTip/index.js
  • src/components/shared/EmailSentNotification/EmailSentNotification.css
  • src/components/shared/InputField/index.js
  • src/components/shared/LoadingSpinner/LoadingSpinner.css
  • src/components/shared/MessageDisplay/MessageDisplay.css
  • src/components/shared/SearchBar/SearchBar.css
  • src/components/shared/dropdowns/CustomDropdown/CustomDropdown.css
  • src/components/tableCells/ContactDetailsCell/ContactDetailsCell.css
  • src/components/tableCells/FollowUpCell/FollowUpCell.css
  • src/components/tableCells/MarketCell/MarketCell.css
  • src/components/tableCells/OffersSentCell/OffersSentCell.css
  • src/components/tableCells/OffersSentCell/index.js
  • src/components/tableCells/StatusLabelCell/StatusLabelCell.css
  • src/context/global/pageHeader/PageHeaderContext.js
  • src/pages/Leads/Leads.css
  • src/pages/Prospects/Prospects.css
  • src/utils/constants/apiConstants.js
  • src/utils/constants/errorConstants.js
  • src/utils/constants/uiConstants.js
Additional comments not posted (138)
src/context/index.js (1)

1-1: LGTM!

src/assets/theme.css (2)

3-3: Consider removing the commented-out property or providing an explanation for its presence to avoid confusion.


7-7: Consider removing the commented-out property or providing an explanation for its presence to avoid confusion.

src/hooks/usePageHeader.js (1)

1-6: LGTM!

amplify/backend/function/emailApiProcessor/amplify.state (1)

1-9: LGTM!

amplify/backend/function/skiptraceApiProcessor/amplify.state (1)

1-9: LGTM! Please verify that the duplication of configuration between emailApiProcessor and skiptraceApiProcessor is intentional.

src/components/shared/ChartToolTip/ChartToolTip.css (1)

1-15: LGTM!

src/App.js (1)

1-14: LGTM!

src/components/shared/EmailSentNotification/index.js (1)

1-10: LGTM!

src/components/shared/MessageDisplay/index.js (1)

3-3: Enhance the comment regarding the CSS file to specify the expected styles for .modal-message and its type variations (e.g., .error, .success, .info). This will help ensure consistent styling across the application and provide clearer guidance for developers.

amplify/.config/project-config.json (1)

1-17: Ensure that the specified SourceDir, DistributionDir, BuildCommand, and StartCommand in the Amplify configuration align with the project's structure and requirements. This helps maintain consistency and ensures that the Amplify setup works as expected.

src/reportWebVitals.js (1)

1-13: Verify the integration and usage of the reportWebVitals function within the project to ensure that web vitals are correctly reported and utilized for performance monitoring.

.vscode/settings.json (1)

1-11: The VSCode settings are appropriately configured to exclude internal Amplify files and include project-specific terms in the spell checker. Ensure that all team members are aware of these settings to maintain a consistent development environment.

src/components/tableCells/StatusLabelCell/index.js (1)

1-14: LGTM! The implementation of the StatusCell component is straightforward and follows best practices. Just ensure the corresponding CSS file is created as mentioned in the comment.

amplify/backend/function/emailApiProcessor/src/index.js (2)

13-13: Consider limiting logging in production environments to avoid potential performance issues or excessive logging costs.


1-15: LGTM! The setup for the AWS Lambda function using aws-serverless-express is correctly implemented.

amplify/backend/function/prospectsApiProcessor/src/index.js (2)

13-13: Consider limiting logging in production environments to avoid potential performance issues or excessive logging costs.


1-15: LGTM! The setup for the AWS Lambda function using aws-serverless-express is correctly implemented.

amplify/backend/function/skiptraceApiProcessor/src/index.js (2)

13-13: Consider limiting logging in production environments to avoid potential performance issues or excessive logging costs.


1-15: LGTM! The setup for the AWS Lambda function using aws-serverless-express is correctly implemented.

src/components/shared/FilterToggleButton/index.js (1)

1-17: LGTM! The FilterToggleButton component is well-implemented, following React best practices and utilizing Material-UI components effectively.

src/components/tableCells/MarketCell/index.js (1)

1-18: LGTM! The MarketCell component is implemented correctly, with clear conditional rendering and separation of concerns.

src/context/global/pageHeader/PageHeaderProvider.js (1)

1-16: LGTM! The PageHeaderProvider context provider is well-implemented, following React best practices for state management and context provision.

src/components/shared/SmallNotification/index.js (1)

1-18: LGTM! The SmallNotification component is correctly implemented, making effective use of React Portals and conditional rendering.

src/setupTests.js (1)

7-22: LGTM! The mock implementation for ResizeObserver is a good practice for testing components that depend on it, ensuring tests don't fail due to missing browser APIs in the Jest environment.

src/index.js (1)

1-17: The implementation correctly sets up the React application's entry point, including performance monitoring with reportWebVitals. Using React.StrictMode is a best practice for identifying potential problems in an application.

.gitignore (1)

1-30: The .gitignore file is well-configured for a React and AWS Amplify project, covering common directories and files that should not be tracked by Git. This setup helps maintain a clean repository by avoiding the inclusion of unnecessary or sensitive files.

src/components/shared/SmallNotification/SmallNotification.css (1)

1-21: The CSS for SmallNotification is well-structured, ensuring the notification is visually distinct and appropriately animated. Using high z-index and transition effects for visibility changes are good practices for such UI elements.

src/components/dataVisualizations/SingleValueCard/index.js (1)

4-21: The SingleValueCard component is implemented correctly, with support for conditional rendering of the icon and change elements. Using a variant prop for styling customization is a flexible approach that allows for easy adjustments.

src/components/shared/SearchBar/index.js (1)

4-25: LGTM! The implementation of the SearchBar component with debounced search functionality is efficient and follows React best practices.

src/components/tableCells/FollowUpCell/index.js (1)

5-20: LGTM! The FollowUpCell component is well-implemented, making good use of utility functions for date formatting and maintaining a clear code structure.

src/components/tableCells/AnalyzeOfferCell/AnalyzeOfferCell.css (1)

1-35: LGTM! The CSS for AnalyzeOfferCell is well-structured and follows best practices, including the use of variables for colors and proper implementation of hover effects.

src/components/ProtectedRoute/index.js (1)

6-31: LGTM! The ProtectedRoute component effectively manages authentication state and conditional rendering, following React best practices.

src/components/shared/modal/ErrorModal/index.js (1)

5-31: LGTM! The ErrorModal component is well-implemented, effectively using event propagation handling and modularity to display error messages.

src/components/layout/LeftNav/NavigationDrawer/index.js (1)

8-37: LGTM! The NavigationDrawer component effectively uses Material-UI components and state management to render a navigation drawer.

src/components/shared/dropdowns/CustomDropdown/index.js (1)

8-29: LGTM! The CustomDropdown component is well-implemented, effectively using FontAwesome icons and providing a high degree of reusability.

src/components/tableCells/AnalyzeOfferCell/index.js (1)

3-3: Ensure the corresponding CSS file AnalyzeOfferCell.css exists and contains the necessary styles for .analyze-offer-cell, .action-icon, and .hover-details.

Verification successful

The CSS file AnalyzeOfferCell.css exists in the specified directory, confirming that the review comment's requirement has been met.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Check if the CSS file exists in the project.
fd 'AnalyzeOfferCell.css' src/components/tableCells/AnalyzeOfferCell

Length of output: 132

src/pages/Auth/index.js (1)

18-20: Consider implementing more robust error handling for the checkCurrentUser function beyond console logging, such as displaying an error message to the user.

src/components/layout/LeftNav/index.js (1)

17-19: Consider implementing more robust error handling for the handleSignOut function beyond console logging, such as displaying an error message to the user.

src/components/dataVisualizations/SingleValueCard/SingleValueCard.css (6)

8-8: Consider using a consistent unit for border-radius across the application to ensure a uniform look and feel.


24-24: The font size for .card-title has been reduced. Ensure this change aligns with the design system and accessibility standards.


37-37: Adding margin-top to .card-change improves spacing. Verify that this change is consistent with spacing conventions used elsewhere in the application.


53-53: Using !important on .card-icon-svg font-size may override other styles. Consider alternatives to !important for maintainability.


63-63: The increased border-radius for .card-container.small introduces a variant. Ensure this variant is necessary and documented in the design system.


68-68: Centering the title with .center-title is a good addition. Ensure this class is applied correctly in the JSX.

Verification successful

The .center-title class is correctly applied in the JSX file src/components/dataVisualizations/SingleValueCard/index.js, conditionally based on the variant prop being "small". This confirms the correct implementation as per the review comment.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Search for usage of `.center-title` in JSX files
rg --type js '.center-title'

Length of output: 165

src/components/shared/Pagination/Pagination.css (6)

38-38: The border-radius for pagination buttons has been set to 20px. Ensure this is consistent with the design system's button styles.


47-47: The active and hover states for pagination buttons use the same brand color. Consider differentiating these states for better user experience.


55-55: The hover background color for non-active buttons is set to #e9ecef. Verify this color choice aligns with the application's color scheme.


60-60: The active button style is well-defined. Ensure that this style is applied correctly in the component logic.

Verification successful

The active button style is correctly applied in the Pagination component logic, as indicated by the condition className={currentPage === number ? "active" : ""} in src/components/shared/Pagination/index.js. This confirms that the style is applied based on the current page, ensuring the active page button is visually distinct.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Search for active class application in Pagination component
rg --type js 'className.*active'

Length of output: 414


69-69: The disabled button style uses cursor: not-allowed. This is a good practice for indicating non-interactive elements.


75-75: Removing button appearance with appearance: none is a good practice for custom styling. Ensure cross-browser compatibility.

src/components/modal/UserLoginModal/VerifyAccountModal/index.js (3)

17-17: Logging "Account verified successfully" to the console is helpful for debugging but consider removing it for production builds.


34-34: Ensure that the input field for the verification code is properly validated before submission to prevent invalid requests.


39-39: The "Verify Account" button does not indicate loading state. Consider disabling the button and showing a spinner during the verification process.

src/components/layout/TopNav/TopNav.css (7)

1-11: The pulse animation for the menu button is a creative touch. Ensure that it enhances user experience without causing distractions.


15-15: The fixed positioning of the top navigation ensures it remains accessible. Verify that this does not overlap with any content on smaller screens.

Verification successful

The search results indicate that adjustments have been made to prevent content overlap with the fixed top navigation, notably a margin-top: 70px; rule in TopNav.css. This suggests that the potential issue of content overlap on smaller screens has been considered and addressed.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Search for any CSS rules that might adjust the top margin of the body or main content area
rg --type css 'margin-top'

Length of output: 2145


26-26: Using !important to override padding can be problematic for maintainability. Consider alternative approaches to achieve the desired layout.


30-32: Removing the box-shadow and setting the background color with !important for .MuiAppBar-root may conflict with Material-UI's styles. Ensure this is necessary and test for unintended side effects.


37-37: Adjusting the color and font-weight for visibility is good. Ensure that these changes are consistent with the application's design system.


47-47: The use of animation on .menu-button is innovative. Confirm that the animation loop does not impact the performance on devices with lower specifications.


58-58: Adjusting the top margin of the body to accommodate the top nav is necessary. Ensure this value matches the actual height of the top nav.

src/AppContent.js (3)

13-58: The routing structure is well-organized and uses protected routes for sensitive pages. Ensure that ProtectedRoute correctly handles authentication and redirects unauthenticated users.

Verification successful

The implementation of ProtectedRoute correctly handles authentication by checking the user's authentication state and redirects unauthenticated users to the home page. This confirms the review comment's suggestion to ensure proper authentication handling in ProtectedRoute.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Search for the implementation of ProtectedRoute to ensure it handles authentication correctly
rg --type js 'ProtectedRoute'

Length of output: 542



Script:

#!/bin/bash
# View the implementation of ProtectedRoute to verify its functionality
cat src/components/ProtectedRoute/index.js

Length of output: 819


20-22: Wrapping the SignUp page in a SignUpLayout is a good practice for maintaining consistent layout across different parts of the application. Verify that all necessary layout components are included.


28-32: Using HomePageLayout for the dashboard and other main sections ensures a consistent user experience. Confirm that the layout includes all required elements such as navigation bars and footers.

src/hooks/useDashboardData.js (4)

21-21: Setting isLoading to true at the beginning of the fetch operation is good practice. Ensure that UI components respond appropriately to this state.


23-29: Using an array of API URLs for batch requests is efficient. Verify that all endpoints are secure and authenticated as necessary.


37-43: The structure for setting data after fetching is clear and organized. Ensure that the data structure aligns with the components consuming this hook.


47-47: Resetting isLoading in a finally block ensures that it is always updated regardless of the fetch outcome. This is a good practice.

src/components/layout/BottomNav/index.js (2)

6-50: The dynamic generation of navigation items in BottomNav is innovative. Ensure that the items are accessible, especially the call-to-action and website items.


26-26: Duplicating items for the loop effect is a creative approach. Monitor performance to ensure it does not impact scrolling or rendering on lower-end devices.

src/components/layout/BottomNav/BottomNav.css (5)

2-8: The slide animation for continuous scrolling is a unique feature. Ensure that the animation speed and distance are optimized for usability.


11-13: Bold font weight for label items enhances readability. Confirm that this style is consistent with the overall design system.


23-30: The bottom navigation's fixed positioning and overflow handling are well-implemented. Verify that this does not obscure any content on smaller screens.


55-60: The call-to-action button styling is visually distinct. Ensure that the contrast ratio meets accessibility standards.


66-74: Styling for the website item with a pointer cursor and hover effect is good for user interaction. Verify that the link is correct and functional.

src/index.css (1)

62-63: Consider using a more descriptive variable name than --white-color for text color in .white-text and .button classes, as it might be confused with the --white variable for background colors.

src/components/shared/modal/ErrorModal/ErrorModal.css (1)

55-66: The transition effect on the .error-modal-footer > button hover state is a nice touch for user interaction. Consider applying a similar transition effect to the .error-modal-close and .error-modal-btn for consistency in button interactions.

src/components/modal/HeaderMappingModal/index.js (1)

43-43: Ensure that the click handler on the .mapping-modal-backdrop does not inadvertently close the modal when users click inside the modal content. The current implementation might lead to unexpected modal closure if not handled properly.

src/pages/Dashboard/Dashboard.css (1)

54-56: The use of calc(100vh - var(--top-offset)) for the height of .dashboard-content-container is innovative. Ensure that the --top-offset variable is defined and correctly calculated to avoid layout issues.

src/components/shared/Pagination/index.js (1)

23-24: The calculation for startItem and endItem is well-implemented. Consider adding a check to ensure leadsPerPage and totalLeads are positive numbers to avoid unexpected results.

src/components/tables/LeadsTable/LeadsTable.css (1)

63-77: The .hover-details class is defined but not used in the visible part of the CSS. If this feature is intended for future implementation, consider adding a comment to clarify its purpose. Otherwise, removing unused styles can help maintain code cleanliness.

src/components/modal/UserLoginModal/NewAccountModal/NewAccountModal.css (1)

6-6: The left: -20px; style in .new-account-modal might cause the modal to be slightly off-center. Verify if this is intentional for design purposes or if it should be adjusted for better alignment.

src/hooks/useLeadsData.js (1)

28-31: Ensure that the API URL in the fetchLeads function is correctly configured in the environment variables. A missing or incorrect API URL could lead to fetch operation failures.

src/pages/Auth/Auth.css (1)

1-121: Ensure consistency in the usage of CSS variables for colors and fonts across the application to enhance maintainability and ease of theme changes.

src/components/modal/PropertyInputModal/PropertyInputModal.css (1)

1-88: Ensure that CSS variables are used for all colors and font sizes to maintain consistency and facilitate easier theme changes.

README.md (1)

2-73: LGTM! The updates to the README.md file provide a comprehensive and clear overview of the KontraX project, its purpose, tech stack, features, and development stages. The flagged spelling mistakes appear to be false positives related to technical terms or names, and thus can be disregarded.

src/tests/App.test.js (2)

7-24: The setup for mocking dependencies is correctly implemented, ensuring that the tests for the App component are isolated and controlled. This is a good practice for unit testing components that rely on external modules or services.


44-74: The test cases are well-structured and effectively cover key functionalities of the App component, including handling unauthenticated access and rendering components based on routes. The use of asynchronous utilities from @testing-library/react is correctly applied, ensuring that the tests accurately reflect user interactions.

src/components/modal/UserLoginModal/GoogleSignInButton/GoogleSignInButton.css (1)

1-111: The CSS styles for the GoogleSignInButton component are well-crafted, adhering to material design principles and effectively handling different button states. The use of transitions and pseudo-classes enhances the user experience by providing visual feedback on interaction.

src/components/shared/dropdowns/FilterBar/index.js (1)

58-82: The FilterBar component is well-structured and effectively utilizes props for configuration. Consider improving accessibility by ensuring that labels are correctly associated with their corresponding select elements, which can be achieved by matching the htmlFor attribute of the label with the id of the select element.

src/components/dataVisualizations/Charts/BubbleChart/index.js (1)

26-127: Optimize the BubbleChart component by avoiding the unnecessary destruction and recreation of the chart instance on every render. Consider adding a dependency array to the useEffect hook that includes only the variables that, when changed, should trigger the re-render of the chart. This optimization can significantly improve the component's performance, especially with large datasets.

src/components/modal/UserLoginModal/NewAccountModal/index.js (1)

59-62: Ensure proper error handling in the catch block of the handleSignUp function. It's good practice to log errors for debugging purposes, but consider how these errors are communicated to the user. Providing generic error messages to the user can improve the user experience by not exposing internal implementation details or errors that may not be meaningful to the end-user.

src/components/tables/LeadsTable/index.js (2)

20-47: The sorting logic within useMemo can be optimized by abstracting the comparison logic into separate functions. This will make the code cleaner and more maintainable. Additionally, consider handling the case where sortConfig.key might not be a valid key in the lead objects, which could potentially cause runtime errors.


54-69: The requestSort function correctly handles the sorting direction based on the current state. However, it's important to ensure that the onSort callback (if it's performing any side effects or updates outside this component) is not called when the priority filter is on, as this could lead to unexpected behavior. Consider adding a comment or documentation to clarify the expected behavior and interaction with external state or props.

amplify/backend/function/emailApiProcessor/src/app.js (1)

76-86: The CORS middleware setup is good for controlling access to your API. However, ensure that the list of allowed origins (ALLOWED_ORIGINS) is properly managed, especially in production environments, to prevent unauthorized access. Consider documenting how to update this list as part of your deployment or operational procedures.

src/pages/Dashboard/index.js (1)

18-147: The implementation of the Dashboard component is well-structured, making good use of custom hooks and component composition. However, consider adding error boundaries around individual sections or visual components. This can prevent the entire dashboard from becoming unusable if a single component or data fetch fails.

amplify/backend/function/skiptraceApiProcessor/src/app.js (1)

77-87: The CORS middleware setup is consistent with the email API processor. As mentioned earlier, ensure that the ALLOWED_ORIGINS list is securely managed and documented for operational procedures.

amplify/backend/function/prospectsApiProcessor/src/app.js (7)

20-22: Consider using AWS Secrets Manager for storing sensitive configuration like API keys instead of AWS SSM if they are used within this application. Secrets Manager is specifically designed for managing secrets and provides benefits like automatic rotation.


24-25: Implement a more sophisticated caching mechanism or use existing caching solutions like Redis or Memcached for storing frequently accessed data. The current implementation is a simple in-memory object, which might not scale well and lacks features like eviction policies.


47-74: The error handling in getParameterFromSSM could be improved by distinguishing between different types of errors (e.g., network errors, permission issues, parameter not found) and handling them accordingly. This can help in troubleshooting and providing more accurate error responses.


78-86: The CORS middleware currently allows requests from a predefined list of origins. Ensure that this list is kept up-to-date and does not include any origins that should not be allowed. Consider using a more dynamic approach if the list of allowed origins needs to change frequently.


89-111: When making external API requests with Axios, consider implementing retry logic for transient errors and timeouts. This can improve the reliability of your application by handling temporary issues automatically.


114-158: In the /property/search endpoint, validate the request body schema to ensure required fields are present and have the correct format before proceeding with processing. This can prevent errors later in the processing and improve security by rejecting malformed requests early.


161-163: Consider using an environment variable or configuration file for specifying the port number instead of hardcoding it. This allows for greater flexibility and easier deployment across different environments.

src/components/modal/PropertyInputModal/index.js (6)

36-36: Ensure that the state for email error messages (emailErrorMessage) is updated and used appropriately throughout the component. If this state is intended to display errors related to email sending, verify that it's being set in all relevant error scenarios.


40-49: The custom hook useProspectData is being used to manage data fetching and email sending. Ensure that this hook properly handles all possible states (loading, success, error) and exposes necessary functionalities to the component.


56-68: The effect hook used for handling success and error scenarios could be optimized by separating it into different hooks based on the dependencies. This can improve readability and ensure that the component only re-renders when necessary.


70-79: The fallback value for e.target.name in handleChange might not be appropriate for all cases. Consider explicitly handling each form field or using a more generic approach that doesn't rely on a hardcoded fallback.


81-87: The successActions function directly manipulates the DOM to download a CSV file. While this approach works, consider abstracting this functionality into a reusable utility function or exploring more React-centric ways to handle downloads.


95-98: The handleSubmit function triggers data fetching without validating the form data. Ensure that all required fields are validated before making the request to prevent unnecessary errors and improve user experience.

src/utils/commonFunctions.js (8)

27-35: The decodeBase64Content function assumes the base64 content always includes a data URI scheme. While this may be true for your use cases, consider adding a comment or documentation specifying this assumption for clarity.


38-40: The formatPhoneNumberToE164 function relies on libphonenumber-js for parsing and formatting. Ensure that this library's version is kept up-to-date and review its handling of edge cases for phone numbers from various regions.


71-75: The areValuesUnique function is a utility for checking the uniqueness of values in an object. Consider adding a brief comment explaining its purpose and usage, as the function name alone might not be immediately clear to all developers.


77-91: The validateRequiredFields function checks for required fields based on a mapping. Ensure that this function is used in all relevant parts of the application where such validation is necessary to maintain data integrity.


93-99: The formatPhoneNumber function formats a phone number into a specific pattern. Consider handling international phone numbers more explicitly if your application supports users from multiple countries.


102-103: The truncateEmail function truncates emails longer than 13 characters. This specific length might not be suitable for all use cases. Consider making the truncation length configurable or documenting the reasoning behind this choice.


106-108: The isValidDate function uses new Date() and isNaN() to check for valid dates. This approach might not catch all invalid date formats. Consider using a more robust date handling library like moment.js or date-fns for date validations.


111-112: The formatDate function uses moment.js for formatting dates. Ensure that the date format string "MMM Do, YYYY" meets your application's localization and formatting requirements.

src/components/modal/SkiptraceListModal/FileProcessing.js (5)

50-63: The handleProcessing function directly manipulates the DOM to trigger downloads and potentially other side effects. Consider encapsulating DOM manipulations within React's lifecycle or using state to trigger these actions to maintain React's declarative nature.


66-78: The effect hook used for handling success and error scenarios could be optimized by separating it into different hooks based on the dependencies. This can improve readability and ensure that the component only re-renders when necessary.


100-119: The initiateHeaderMapping function within the effect hook extracts headers from the selected file. Ensure that this process is robust and handles various CSV formats and potential errors gracefully.


151-164: The conditional rendering logic for displaying the "Skiptrace File" button is complex and might be simplified for readability. Consider breaking down the condition into smaller, named variables that describe each part of the condition.


166-176: The HeaderMappingModal component is used for mapping file headers. Ensure that the modal properly handles all possible user actions, including cancellation, to prevent any unintended state changes or side effects.

src/pages/Leads/index.js (9)

20-23: The Leads component manages and displays leads with various functionalities. Ensure that all dependencies, such as custom hooks and utility functions, are correctly implemented and tested to support these features.


53-56: The effect hook for setting the page header and fetching leads runs on component mount. Verify that the fetchLeads function handles loading states and errors appropriately to ensure a smooth user experience.


65-72: When toggling the priority filter, the component recalculates top priority leads. Ensure that the getPriorityLeads function accurately identifies and sorts priority leads according to the application's requirements.


74-92: The search functionality filters leads based on a search term. Consider debouncing the search input to reduce the number of computations and improve performance, especially for large datasets.


94-103: The handleFilterChange function resets the priority filter when other filters are applied. Ensure that this behavior is consistent with the user's expectations and clearly communicated in the UI.


105-116: Toggling the priority leads filter resets other filters to their default values. This might not be intuitive for users. Consider maintaining the state of other filters or providing a clear indication of this behavior in the UI.


128-133: The getSortValue function extracts a value for sorting based on a key. Ensure that this function handles all possible keys and formats correctly to prevent sorting errors.


137-179: The handleSort function sorts leads based on a given key and direction. Verify that sorting works correctly for all data types and consider edge cases, such as null or undefined values.


188-190: The handleSearch function updates the search term state. Consider implementing input validation or sanitization to prevent potential security issues, such as XSS attacks, if user input is displayed elsewhere in the application.

src/utils/apiCommonFunctions.js (6)

5-30: The generateProspectsCSV function transforms API response data into CSV format. Ensure that all fields extracted from the API response are correctly mapped and that the API response structure matches the expected format.


33-68: The generateSkiptraceCSV function similarly transforms API response data for skiptrace results into CSV format. Verify that the data mapping is accurate and consider edge cases, such as missing fields or arrays with no elements.


71-80: The downloadProspectsCSV function creates a Blob from CSV content and triggers a download. Ensure that this function is compatible with all target browsers, especially regarding the use of Blob and URL.createObjectURL.


82-158: The PROSPECTS_NICHE_REQUEST and PROSPECTS_ABSENTEE_REQUEST functions construct API request bodies for different types of prospect data. Verify that the request structures align with the API's expected schema and that all necessary fields are included.


250-254: The getProspectApiRequest function selects the appropriate API request structure based on the data type. Ensure that the dataType parameter is validated and that the function handles unexpected or invalid data types gracefully.


256-280: The transformCsvToSkiptraceApiRequestBody function parses CSV content and transforms it into a JSON structure for API requests. Ensure that the CSV parsing is robust and handles various CSV formats and potential parsing errors.

Comment on lines +4 to +20
export const useSmallNotification = () => {
const [smallNotification, setSmallNotification] = useState({
message: "",
show: false,
});

const showSmallNotification = (message, duration = 2000) => {
setSmallNotification({ message, show: true });
setTimeout(() => {
setSmallNotification({ message: "", show: false });
}, duration);
};

return {
smallNotification,
showSmallNotification,
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using useEffect to clean up the setTimeout to prevent potential memory leaks if the component unmounts before the timeout completes.

+ import { useState, useEffect } from "react";
...
+ useEffect(() => {
+   const timer = setTimeout(() => {
+     setSmallNotification({ message: "", show: false });
+   }, duration);
+
+   return () => clearTimeout(timer);
+ }, [smallNotification, duration]);

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
export const useSmallNotification = () => {
const [smallNotification, setSmallNotification] = useState({
message: "",
show: false,
});
const showSmallNotification = (message, duration = 2000) => {
setSmallNotification({ message, show: true });
setTimeout(() => {
setSmallNotification({ message: "", show: false });
}, duration);
};
return {
smallNotification,
showSmallNotification,
};
import { useState, useEffect } from "react";
export const useSmallNotification = () => {
const [smallNotification, setSmallNotification] = useState({
message: "",
show: false,
});
const showSmallNotification = (message, duration = 2000) => {
setSmallNotification({ message, show: true });
useEffect(() => {
const timer = setTimeout(() => {
setSmallNotification({ message: "", show: false });
}, duration);
return () => clearTimeout(timer);
}, [smallNotification, duration]);
};
return {
smallNotification,
showSmallNotification,
};

Comment on lines +5 to +7
const MessageDisplay = ({ message, type }) => {
return <div className={`modal-message ${type}`}>{message}</div>;
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding PropTypes to validate the message and type props for better type safety and documentation.

+ import PropTypes from 'prop-types';
+
+ MessageDisplay.propTypes = {
+   message: PropTypes.string.isRequired,
+   type: PropTypes.oneOf(['error', 'success', 'info']).isRequired,
+ };

This ensures that the component is used correctly throughout the application and provides documentation for other developers.


Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
const MessageDisplay = ({ message, type }) => {
return <div className={`modal-message ${type}`}>{message}</div>;
};
import PropTypes from 'prop-types';
const MessageDisplay = ({ message, type }) => {
return <div className={`modal-message ${type}`}>{message}</div>;
};
MessageDisplay.propTypes = {
message: PropTypes.string.isRequired,
type: PropTypes.oneOf(['error', 'success', 'info']).isRequired,
};

Comment on lines +5 to +22
const SingleValueCardsGrid = ({ kpis, variant }) => {
return (
<div className="cards-grid">
{kpis.map((kpi, index) => (
<SingleValueCard
key={index}
title={kpi.name}
value={kpi.value}
change={kpi.change}
icon={kpi.icon}
variant={variant}
/>
))}
</div>
);
};

export default SingleValueCardsGrid;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the array index as a key in React list rendering is not recommended if the list can change. If KPI objects have unique identifiers, use those as keys instead to improve React's ability to re-render efficiently.

-          key={index}
+          key={kpi.id || index}

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
const SingleValueCardsGrid = ({ kpis, variant }) => {
return (
<div className="cards-grid">
{kpis.map((kpi, index) => (
<SingleValueCard
key={index}
title={kpi.name}
value={kpi.value}
change={kpi.change}
icon={kpi.icon}
variant={variant}
/>
))}
</div>
);
};
export default SingleValueCardsGrid;
const SingleValueCardsGrid = ({ kpis, variant }) => {
return (
<div className="cards-grid">
{kpis.map((kpi, index) => (
<SingleValueCard
key={kpi.id || index}
title={kpi.name}
value={kpi.value}
change={kpi.change}
icon={kpi.icon}
variant={variant}
/>
))}
</div>
);
};
export default SingleValueCardsGrid;

Comment thread clean-css.js
Comment on lines +20 to +26
fs.unlink(filePath, (err) => {
if (err) {
console.error(`Error deleting file: ${file}`, err);
} else {
console.log(`Deleted: ${file}`);
}
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider enhancing error handling during file deletion to include more detailed logging. Additionally, using async/await syntax could improve readability.

- fs.unlink(filePath, (err) => {
+ fs.unlink(filePath, (error) => {
-   if (err) {
+   if (error) {
-     console.error(`Error deleting file: ${file}`, err);
+     console.error(`Failed to delete ${filePath}:`, error);
    } else {

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
fs.unlink(filePath, (err) => {
if (err) {
console.error(`Error deleting file: ${file}`, err);
} else {
console.log(`Deleted: ${file}`);
}
});
fs.unlink(filePath, (error) => {
if (error) {
console.error(`Failed to delete ${filePath}:`, error);
} else {
console.log(`Deleted: ${file}`);
}
});

Comment on lines +11 to +24
const SignUpLayout = ({ children }) => {
return (
<div className="signup-layout">
{children} {/* This is where your SignUp component will be rendered */}
{/* <BottomNav
navItems={NAV_ITEMS}
callToActionItems={CTA_ITEMS}
websiteItem={WEBSITE_ITEM}
/> */}
</div>
);
};

export default SignUpLayout;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider removing or clarifying the purpose of the commented-out BottomNav component. If it's meant for future use, add a TODO comment explaining its intended purpose or conditions for uncommenting.

+ // TODO: Uncomment and use BottomNav when XYZ feature is implemented
-      {/* <BottomNav
+      <BottomNav
        navItems={NAV_ITEMS}
        callToActionItems={CTA_ITEMS}
        websiteItem={WEBSITE_ITEM}
-      /> */}
+      />

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
const SignUpLayout = ({ children }) => {
return (
<div className="signup-layout">
{children} {/* This is where your SignUp component will be rendered */}
{/* <BottomNav
navItems={NAV_ITEMS}
callToActionItems={CTA_ITEMS}
websiteItem={WEBSITE_ITEM}
/> */}
</div>
);
};
export default SignUpLayout;
const SignUpLayout = ({ children }) => {
return (
<div className="signup-layout">
{children} {/* This is where your SignUp component will be rendered */}
// TODO: Uncomment and use BottomNav when XYZ feature is implemented
<BottomNav
navItems={NAV_ITEMS}
callToActionItems={CTA_ITEMS}
websiteItem={WEBSITE_ITEM}
/>
</div>
);
};
export default SignUpLayout;

Comment on lines +1 to +157
/* FilterBar.css */

.filter-bar {
padding: 10px;
display: flex;
gap: 10px; /* Space between filter controls */
background-color: var(--background-color);
overflow: hidden;
border-radius: 10px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
width: 100%; /* Use full width */
max-width: 82%;
margin: 0 auto 20px;
}

.filter-control {
display: flex;
align-items: center;
}

.filter-control,
.filter-bar .search-bar {
flex-grow: 1;
flex-basis: auto;
}
.filter-bar .offer-toggle .MuiToggleButton-root {
margin-left: auto;
}

.filter-control label {
font-size: 0.9rem;
margin-right: 10px; /* Adjust the right margin to add space between the label and the select */
background-color: #f0f0f0; /* Restore the label background color */
padding: 6px 10px; /* Padding inside the label */
border: 1px solid #ccc; /* Restore the label border */
border-radius: 5px; /* Border radius for the label */
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); /* Restore the label shadow */
color: #333; /* Text color for the label */
}

.filter-control select {
padding: 8px 10px; /* Adjust padding for a cleaner look */
border: 1px solid #ccd6f6; /* Soften the border color */
border-radius: 5px; /* Border radius for the select */
cursor: pointer;
outline: none;
-webkit-appearance: none; /* Remove default styling */
-moz-appearance: none; /* Remove default styling */
appearance: none;
background-color: #fff; /* Background color for the select */
transition: all 0.3s ease; /* Smooth transition for interaction states */
font-size: 0.9rem; /* Adjust font size for readability */
color: #333; /* Text color */
text-align-last: center; /* This centers the text in the dropdown */
text-align: center; /* This attempts to center the option text, but may not work in all browsers */
-moz-text-align-last: center; /* This is for Firefox specifically */
}

.filter-control .custom-select-wrapper {
position: relative;
display: flex;
align-items: center;
}

.filter-control select {
padding: 8px 30px 8px 10px; /* Padding to make room for the icon */
border: 1px solid #ccc; /* Border for the select */
border-radius: 5px; /* Border radius for the select */
cursor: pointer;
outline: none;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background-color: #fff; /* Background color for the select */
transition: border-color 0.3s ease;
}

.filterbar-dropdown-icon {
position: absolute;
right: 8px;
top: 53%;
transform: translateY(-50%);
color: #555;
pointer-events: none;
transition: color 0.3s ease;
}

.filter-control:hover select {
border-color: #8892b0; /* Darker border on hover for emphasis */
}

.filter-control:hover .dropdown-icon {
color: #8892b0; /* Icon color changes on hover */
}

.filter-control select:focus {
border-color: #8892b0; /* Focus state border color */
box-shadow: 0 0 0 2px rgba(136, 146, 176, 0.5); /* Subtle focus shadow */
}

.filter-control .MuiToggleButton-root {
height: 38px; /* Adjust this value to match your select elements */
margin: 0; /* Adjust margin as necessary */
padding: 6px 12px; /* Adjust padding to center the content */
display: flex; /* Use flexbox to center the content */
justify-content: center; /* Center content horizontally */
align-items: center; /* Center content vertically */
border-radius: 10px; /* Rounded corners */
transition: background-color 0.3s, transform 0.3s; /* Smooth transitions for hover and click */
}

/* When the toggle button is off, use a more muted color */
.filter-control .MuiToggleButton-root {
background-color: var(--brand-color-2); /* Off state color */
color: #757575; /* Muted icon color for off state */
}

/* When the toggle button is on, use the primary brand color */
.filter-control .MuiToggleButton-root.Mui-selected {
background-color: var(--brand-color-light); /* On state color */
color: #fff; /* White icon color for on state */
}

/* Style for the icon inside the toggle button */
.filter-control .MuiToggleButton-root .MuiSvgIcon-root {
color: #fff; /* Color of the icon */
}

.filter-control .MuiToggleButton-root:hover {
background-color: rgba(
213,
181,
163,
0.7
); /* Slightly darker for hover on off state */
}

.filter-control .MuiToggleButton-root.Mui-selected:hover {
background-color: rgba(
30,
58,
95,
0.6
); /* Lighten the on state color on hover */
}

@media (max-width: 768px) {
.filter-bar {
flex-direction: column; /* Stack filters on smaller screens */
}
.filter-control {
width: 100%; /* Full width for mobile */
}
.filter-control .MuiToggleButton-root {
margin-left: 0; /* Adjust margin for smaller screens */
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using CSS variables for colors, spacings, and other reusable values to enhance maintainability and theme consistency. This is especially useful for projects that may require theme switching or have a design system in place.

-  background-color: var(--background-color);
+  background-color: var(--filter-bar-background-color, var(--background-color));

-  border: 1px solid #ccd6f6;
+  border: 1px solid var(--filter-bar-border-color, #ccd6f6);

-  color: #333;
+  color: var(--filter-bar-text-color, #333);

-  background-color: #fff;
+  background-color: var(--filter-bar-select-background-color, #fff);

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
/* FilterBar.css */
.filter-bar {
padding: 10px;
display: flex;
gap: 10px; /* Space between filter controls */
background-color: var(--background-color);
overflow: hidden;
border-radius: 10px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
width: 100%; /* Use full width */
max-width: 82%;
margin: 0 auto 20px;
}
.filter-control {
display: flex;
align-items: center;
}
.filter-control,
.filter-bar .search-bar {
flex-grow: 1;
flex-basis: auto;
}
.filter-bar .offer-toggle .MuiToggleButton-root {
margin-left: auto;
}
.filter-control label {
font-size: 0.9rem;
margin-right: 10px; /* Adjust the right margin to add space between the label and the select */
background-color: #f0f0f0; /* Restore the label background color */
padding: 6px 10px; /* Padding inside the label */
border: 1px solid #ccc; /* Restore the label border */
border-radius: 5px; /* Border radius for the label */
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); /* Restore the label shadow */
color: #333; /* Text color for the label */
}
.filter-control select {
padding: 8px 10px; /* Adjust padding for a cleaner look */
border: 1px solid #ccd6f6; /* Soften the border color */
border-radius: 5px; /* Border radius for the select */
cursor: pointer;
outline: none;
-webkit-appearance: none; /* Remove default styling */
-moz-appearance: none; /* Remove default styling */
appearance: none;
background-color: #fff; /* Background color for the select */
transition: all 0.3s ease; /* Smooth transition for interaction states */
font-size: 0.9rem; /* Adjust font size for readability */
color: #333; /* Text color */
text-align-last: center; /* This centers the text in the dropdown */
text-align: center; /* This attempts to center the option text, but may not work in all browsers */
-moz-text-align-last: center; /* This is for Firefox specifically */
}
.filter-control .custom-select-wrapper {
position: relative;
display: flex;
align-items: center;
}
.filter-control select {
padding: 8px 30px 8px 10px; /* Padding to make room for the icon */
border: 1px solid #ccc; /* Border for the select */
border-radius: 5px; /* Border radius for the select */
cursor: pointer;
outline: none;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background-color: #fff; /* Background color for the select */
transition: border-color 0.3s ease;
}
.filterbar-dropdown-icon {
position: absolute;
right: 8px;
top: 53%;
transform: translateY(-50%);
color: #555;
pointer-events: none;
transition: color 0.3s ease;
}
.filter-control:hover select {
border-color: #8892b0; /* Darker border on hover for emphasis */
}
.filter-control:hover .dropdown-icon {
color: #8892b0; /* Icon color changes on hover */
}
.filter-control select:focus {
border-color: #8892b0; /* Focus state border color */
box-shadow: 0 0 0 2px rgba(136, 146, 176, 0.5); /* Subtle focus shadow */
}
.filter-control .MuiToggleButton-root {
height: 38px; /* Adjust this value to match your select elements */
margin: 0; /* Adjust margin as necessary */
padding: 6px 12px; /* Adjust padding to center the content */
display: flex; /* Use flexbox to center the content */
justify-content: center; /* Center content horizontally */
align-items: center; /* Center content vertically */
border-radius: 10px; /* Rounded corners */
transition: background-color 0.3s, transform 0.3s; /* Smooth transitions for hover and click */
}
/* When the toggle button is off, use a more muted color */
.filter-control .MuiToggleButton-root {
background-color: var(--brand-color-2); /* Off state color */
color: #757575; /* Muted icon color for off state */
}
/* When the toggle button is on, use the primary brand color */
.filter-control .MuiToggleButton-root.Mui-selected {
background-color: var(--brand-color-light); /* On state color */
color: #fff; /* White icon color for on state */
}
/* Style for the icon inside the toggle button */
.filter-control .MuiToggleButton-root .MuiSvgIcon-root {
color: #fff; /* Color of the icon */
}
.filter-control .MuiToggleButton-root:hover {
background-color: rgba(
213,
181,
163,
0.7
); /* Slightly darker for hover on off state */
}
.filter-control .MuiToggleButton-root.Mui-selected:hover {
background-color: rgba(
30,
58,
95,
0.6
); /* Lighten the on state color on hover */
}
@media (max-width: 768px) {
.filter-bar {
flex-direction: column; /* Stack filters on smaller screens */
}
.filter-control {
width: 100%; /* Full width for mobile */
}
.filter-control .MuiToggleButton-root {
margin-left: 0; /* Adjust margin for smaller screens */
}
}
/* FilterBar.css */
.filter-bar {
padding: 10px;
display: flex;
gap: 10px; /* Space between filter controls */
background-color: var(--filter-bar-background-color, var(--background-color));
overflow: hidden;
border-radius: 10px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
width: 100%; /* Use full width */
max-width: 82%;
margin: 0 auto 20px;
}
.filter-control {
display: flex;
align-items: center;
}
.filter-control,
.filter-bar .search-bar {
flex-grow: 1;
flex-basis: auto;
}
.filter-bar .offer-toggle .MuiToggleButton-root {
margin-left: auto;
}
.filter-control label {
font-size: 0.9rem;
margin-right: 10px; /* Adjust the right margin to add space between the label and the select */
background-color: #f0f0f0; /* Restore the label background color */
padding: 6px 10px; /* Padding inside the label */
border: 1px solid #ccc; /* Restore the label border */
border-radius: 5px; /* Border radius for the label */
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); /* Restore the label shadow */
color: var(--filter-bar-text-color, #333); /* Text color for the label */
}
.filter-control select {
padding: 8px 10px; /* Adjust padding for a cleaner look */
border: 1px solid var(--filter-bar-border-color, #ccd6f6); /* Soften the border color */
border-radius: 5px; /* Border radius for the select */
cursor: pointer;
outline: none;
-webkit-appearance: none; /* Remove default styling */
-moz-appearance: none; /* Remove default styling */
appearance: none;
background-color: var(--filter-bar-select-background-color, #fff); /* Background color for the select */
transition: all 0.3s ease; /* Smooth transition for interaction states */
font-size: 0.9rem; /* Adjust font size for readability */
color: var(--filter-bar-text-color, #333); /* Text color */
text-align-last: center; /* This centers the text in the dropdown */
text-align: center; /* This attempts to center the option text, but may not work in all browsers */
-moz-text-align-last: center; /* This is for Firefox specifically */
}
.filter-control .custom-select-wrapper {
position: relative;
display: flex;
align-items: center;
}
.filter-control select {
padding: 8px 30px 8px 10px; /* Padding to make room for the icon */
border: 1px solid #ccc; /* Border for the select */
border-radius: 5px; /* Border radius for the select */
cursor: pointer;
outline: none;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background-color: var(--filter-bar-select-background-color, #fff); /* Background color for the select */
transition: border-color 0.3s ease;
}
.filterbar-dropdown-icon {
position: absolute;
right: 8px;
top: 53%;
transform: translateY(-50%);
color: #555;
pointer-events: none;
transition: color 0.3s ease;
}
.filter-control:hover select {
border-color: #8892b0; /* Darker border on hover for emphasis */
}
.filter-control:hover .dropdown-icon {
color: #8892b0; /* Icon color changes on hover */
}
.filter-control select:focus {
border-color: #8892b0; /* Focus state border color */
box-shadow: 0 0 0 2px rgba(136, 146, 176, 0.5); /* Subtle focus shadow */
}
.filter-control .MuiToggleButton-root {
height: 38px; /* Adjust this value to match your select elements */
margin: 0; /* Adjust margin as necessary */
padding: 6px 12px; /* Adjust padding to center the content */
display: flex; /* Use flexbox to center the content */
justify-content: center; /* Center content horizontally */
align-items: center; /* Center content vertically */
border-radius: 10px; /* Rounded corners */
transition: background-color 0.3s, transform 0.3s; /* Smooth transitions for hover and click */
}
/* When the toggle button is off, use a more muted color */
.filter-control .MuiToggleButton-root {
background-color: var(--brand-color-2); /* Off state color */
color: #757575; /* Muted icon color for off state */
}
/* When the toggle button is on, use the primary brand color */
.filter-control .MuiToggleButton-root.Mui-selected {
background-color: var(--brand-color-light); /* On state color */
color: #fff; /* White icon color for on state */
}
/* Style for the icon inside the toggle button */
.filter-control .MuiToggleButton-root .MuiSvgIcon-root {
color: #fff; /* Color of the icon */
}
.filter-control .MuiToggleButton-root:hover {
background-color: rgba(
213,
181,
163,
0.7
); /* Slightly darker for hover on off state */
}
.filter-control .MuiToggleButton-root.Mui-selected:hover {
background-color: rgba(
30,
58,
95,
0.6
); /* Lighten the on state color on hover */
}
@media (max-width: 768px) {
.filter-bar {
flex-direction: column; /* Stack filters on smaller screens */
}
.filter-control {
width: 100%; /* Full width for mobile */
}
.filter-control .MuiToggleButton-root {
margin-left: 0; /* Adjust margin for smaller screens */
}
}

Comment on lines +18 to +49
const fetchData = useCallback(async () => {
try {
setIsLoading(true);
const queryParams = new URLSearchParams(filters).toString();

const apiUrls = [
`/api/getCardData?${queryParams}`,
"/api/getMarketConversions",
"/api/getDealsClosedByMarket",
`/api/getLeadSourceRoi?${queryParams}`,
`/api/getLeadSourcePerformance?${queryParams}`,
];

const responses = await Promise.all(
apiUrls.map((url) =>
axios.get(`${process.env.REACT_APP_KONTRAX_PSTMN_API_URL}${url}`)
)
);

setData({
singleValueCardData: responses[0].data.data,
barChartData: responses[1].data.data,
bubbleChartData: responses[2].data.data,
roiByLeadSourceData: responses[3].data.data,
salesRadarChartData: responses[4].data.data,
});
} catch (error) {
setError(error);
} finally {
setIsLoading(false);
}
}, [filters]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure error handling in fetchData function is robust and does not expose sensitive information. Consider logging errors for debugging while displaying generic messages to users.

- setError(error);
+ setError("Failed to fetch dashboard data. Please try again later.");

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
const fetchData = useCallback(async () => {
try {
setIsLoading(true);
const queryParams = new URLSearchParams(filters).toString();
const apiUrls = [
`/api/getCardData?${queryParams}`,
"/api/getMarketConversions",
"/api/getDealsClosedByMarket",
`/api/getLeadSourceRoi?${queryParams}`,
`/api/getLeadSourcePerformance?${queryParams}`,
];
const responses = await Promise.all(
apiUrls.map((url) =>
axios.get(`${process.env.REACT_APP_KONTRAX_PSTMN_API_URL}${url}`)
)
);
setData({
singleValueCardData: responses[0].data.data,
barChartData: responses[1].data.data,
bubbleChartData: responses[2].data.data,
roiByLeadSourceData: responses[3].data.data,
salesRadarChartData: responses[4].data.data,
});
} catch (error) {
setError(error);
} finally {
setIsLoading(false);
}
}, [filters]);
const fetchData = useCallback(async () => {
try {
setIsLoading(true);
const queryParams = new URLSearchParams(filters).toString();
const apiUrls = [
`/api/getCardData?${queryParams}`,
"/api/getMarketConversions",
"/api/getDealsClosedByMarket",
`/api/getLeadSourceRoi?${queryParams}`,
`/api/getLeadSourcePerformance?${queryParams}`,
];
const responses = await Promise.all(
apiUrls.map((url) =>
axios.get(`${process.env.REACT_APP_KONTRAX_PSTMN_API_URL}${url}`)
)
);
setData({
singleValueCardData: responses[0].data.data,
barChartData: responses[1].data.data,
bubbleChartData: responses[2].data.data,
roiByLeadSourceData: responses[3].data.data,
salesRadarChartData: responses[4].data.data,
});
} catch (error) {
setError("Failed to fetch dashboard data. Please try again later.");
} finally {
setIsLoading(false);
}
}, [filters]);

item.special ? "bottom-nav-website" : ""
}`}
key={index}
onClick={() => item.special && openLink("https://kontra-x.com")}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding aria-label attributes to buttons for improved accessibility, especially for screen reader users.

- <div className={`bottom-nav-item ${item.cta ? "bottom-nav-cta" : ""}`} key={index} onClick={() => item.special && openLink("https://kontra-x.com")}>
+ <div className={`bottom-nav-item ${item.cta ? "bottom-nav-cta" : ""}`} key={index} aria-label={item.label} onClick={() => item.special && openLink("https://kontra-x.com")}>

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
onClick={() => item.special && openLink("https://kontra-x.com")}
<div className={`bottom-nav-item ${item.cta ? "bottom-nav-cta" : ""}`} key={index} aria-label={item.label} onClick={() => item.special && openLink("https://kontra-x.com")}>

Comment on lines +112 to +159
app.post("/email/send", async function (req, res) {
try {
// Validate environment variables
const API_BASE_URL = process.env.API_BASE_URL;
const BEARER_TOKEN_NAME = process.env.BEARER_TOKEN_NAME;

if (!API_BASE_URL || !BEARER_TOKEN_NAME) {
throw new Error("Missing environment configuration");
}

// Retrieve and validate the bearer token
const bearerToken = await getParameterFromSSM(BEARER_TOKEN_NAME);
if (!bearerToken) {
throw new Error("Bearer token not found or invalid");
}

// Prepare the request configuration
const config = {
method: "post",
url: `${API_BASE_URL}/mail/send`,
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${bearerToken}`,
},
data: JSON.stringify(req.body),
maxBodyLength: Infinity,
};
console.log("Axios request configuration:", config);
logRequestAndResponse(req);

// Perform the request and send the response
const responseData = await performRequest(config);
console.log("End Response:", responseData);
res.json(responseData);
} catch (error) {
console.error(
`Handler error: ${error.message} - Status: ${error.response?.status}`,
JSON.stringify(error.response?.data, null, 2)
);

res.status(500).json({
message: error.message,
status: error.response?.status,
statusText: error.response?.statusText,
data: error.response?.data,
});
}
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the /email/send endpoint, consider adding more specific error handling for different types of failures, such as validation errors, external API errors, and unexpected exceptions. This can improve the API's usability by providing more informative error messages to the client. Additionally, ensure sensitive information is not leaked through error messages.

-      throw new Error("Missing environment configuration");
+      res.status(400).json({ message: "Missing environment configuration" });

-      throw new Error("Bearer token not found or invalid");
+      res.status(401).json({ message: "Bearer token not found or invalid" });

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
app.post("/email/send", async function (req, res) {
try {
// Validate environment variables
const API_BASE_URL = process.env.API_BASE_URL;
const BEARER_TOKEN_NAME = process.env.BEARER_TOKEN_NAME;
if (!API_BASE_URL || !BEARER_TOKEN_NAME) {
throw new Error("Missing environment configuration");
}
// Retrieve and validate the bearer token
const bearerToken = await getParameterFromSSM(BEARER_TOKEN_NAME);
if (!bearerToken) {
throw new Error("Bearer token not found or invalid");
}
// Prepare the request configuration
const config = {
method: "post",
url: `${API_BASE_URL}/mail/send`,
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${bearerToken}`,
},
data: JSON.stringify(req.body),
maxBodyLength: Infinity,
};
console.log("Axios request configuration:", config);
logRequestAndResponse(req);
// Perform the request and send the response
const responseData = await performRequest(config);
console.log("End Response:", responseData);
res.json(responseData);
} catch (error) {
console.error(
`Handler error: ${error.message} - Status: ${error.response?.status}`,
JSON.stringify(error.response?.data, null, 2)
);
res.status(500).json({
message: error.message,
status: error.response?.status,
statusText: error.response?.statusText,
data: error.response?.data,
});
}
});
app.post("/email/send", async function (req, res) {
try {
// Validate environment variables
const API_BASE_URL = process.env.API_BASE_URL;
const BEARER_TOKEN_NAME = process.env.BEARER_TOKEN_NAME;
if (!API_BASE_URL || !BEARER_TOKEN_NAME) {
res.status(400).json({ message: "Missing environment configuration" });
}
// Retrieve and validate the bearer token
const bearerToken = await getParameterFromSSM(BEARER_TOKEN_NAME);
if (!bearerToken) {
res.status(401).json({ message: "Bearer token not found or invalid" });
}
// Prepare the request configuration
const config = {
method: "post",
url: `${API_BASE_URL}/mail/send`,
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${bearerToken}`,
},
data: JSON.stringify(req.body),
maxBodyLength: Infinity,
};
console.log("Axios request configuration:", config);
logRequestAndResponse(req);
// Perform the request and send the response
const responseData = await performRequest(config);
console.log("End Response:", responseData);
res.json(responseData);
} catch (error) {
console.error(
`Handler error: ${error.message} - Status: ${error.response?.status}`,
JSON.stringify(error.response?.data, null, 2)
);
res.status(500).json({
message: error.message,
status: error.response?.status,
statusText: error.response?.statusText,
data: error.response?.data,
});
}
});

Comment on lines +114 to +158
app.post("/skiptrace", async function (req, res) {
try {
// Validate environment variables
const API_BASE_URL = process.env.API_BASE_URL;
const BEARER_TOKEN_NAME = process.env.BEARER_TOKEN_NAME;
if (!API_BASE_URL || !BEARER_TOKEN_NAME) {
throw new Error("Missing environment configuration");
}

// Retrieve and validate the bearer token
const bearerToken = await getParameterFromSSM(BEARER_TOKEN_NAME);
if (!bearerToken) {
throw new Error("Bearer token not found or invalid");
}

// Prepare the request configuration
const config = {
method: "post",
url: `${API_BASE_URL}/property/skip-trace`,
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${bearerToken}`,
},
data: JSON.stringify(req.body),
maxBodyLength: Infinity,
};
console.log("Server Side External API request configuration:", config);
logRequestAndResponse(req);
const responseData = await performRequest(config);
console.log("End Response:", responseData);
res.json(responseData);
} catch (error) {
console.error(
`Handler error: ${error.message} - Status: ${error.response?.status}`,
JSON.stringify(error.response?.data, null, 2)
);

res.status(500).json({
message: error.message,
status: error.response?.status,
statusText: error.response?.statusText,
data: error.response?.data,
});
}
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the email API processor, enhance the error handling in the /skiptrace endpoint to provide more informative and user-friendly error messages. Also, ensure that sensitive information is not exposed through error messages or logs.

-      throw new Error("Missing environment configuration");
+      res.status(400).json({ message: "Missing environment configuration" });

-      throw new Error("Bearer token not found or invalid");
+      res.status(401).json({ message: "Bearer token not found or invalid" });

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
app.post("/skiptrace", async function (req, res) {
try {
// Validate environment variables
const API_BASE_URL = process.env.API_BASE_URL;
const BEARER_TOKEN_NAME = process.env.BEARER_TOKEN_NAME;
if (!API_BASE_URL || !BEARER_TOKEN_NAME) {
throw new Error("Missing environment configuration");
}
// Retrieve and validate the bearer token
const bearerToken = await getParameterFromSSM(BEARER_TOKEN_NAME);
if (!bearerToken) {
throw new Error("Bearer token not found or invalid");
}
// Prepare the request configuration
const config = {
method: "post",
url: `${API_BASE_URL}/property/skip-trace`,
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${bearerToken}`,
},
data: JSON.stringify(req.body),
maxBodyLength: Infinity,
};
console.log("Server Side External API request configuration:", config);
logRequestAndResponse(req);
const responseData = await performRequest(config);
console.log("End Response:", responseData);
res.json(responseData);
} catch (error) {
console.error(
`Handler error: ${error.message} - Status: ${error.response?.status}`,
JSON.stringify(error.response?.data, null, 2)
);
res.status(500).json({
message: error.message,
status: error.response?.status,
statusText: error.response?.statusText,
data: error.response?.data,
});
}
});
app.post("/skiptrace", async function (req, res) {
try {
// Validate environment variables
const API_BASE_URL = process.env.API_BASE_URL;
const BEARER_TOKEN_NAME = process.env.BEARER_TOKEN_NAME;
if (!API_BASE_URL || !BEARER_TOKEN_NAME) {
res.status(400).json({ message: "Missing environment configuration" });
}
// Retrieve and validate the bearer token
const bearerToken = await getParameterFromSSM(BEARER_TOKEN_NAME);
if (!bearerToken) {
res.status(401).json({ message: "Bearer token not found or invalid" });
}
// Prepare the request configuration
const config = {
method: "post",
url: `${API_BASE_URL}/property/skip-trace`,
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${bearerToken}`,
},
data: JSON.stringify(req.body),
maxBodyLength: Infinity,
};
console.log("Server Side External API request configuration:", config);
logRequestAndResponse(req);
const responseData = await performRequest(config);
console.log("End Response:", responseData);
res.json(responseData);
} catch (error) {
console.error(
`Handler error: ${error.message} - Status: ${error.response?.status}`,
JSON.stringify(error.response?.data, null, 2)
);
res.status(500).json({
message: error.message,
status: error.response?.status,
statusText: error.response?.statusText,
data: error.response?.data,
});
}
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant