Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: React Skeleton #2403

Open
wants to merge 71 commits into
base: develop
Choose a base branch
from
Open

Conversation

shohag121
Copy link
Member

@shohag121 shohag121 commented Oct 17, 2024

All Submissions:

  • My code follow the WordPress' coding standards
  • My code satisfies feature requirements
  • My code is tested
  • My code passes the PHPCS tests
  • My code has proper inline documentation
  • I've included related pull request(s) (optional)
  • I've included developer documentation (optional)
  • I've added proper labels to this pull request

Changes proposed in this Pull Request:

Related Pull Request(s)

Closes

How to test the changes in this Pull Request:

  • Please check if flash rewrite rules need to be updated or not just after switching into this branch.

Changelog entry

Title

Detailed Description of the pull request. What was previous behaviour
and what will be changed in this PR.

Before Changes

Describe the issue before changes with screenshots(s).

After Changes

Describe the issue after changes with screenshot(s).

Feature Video (optional)

Link of detailed video if this PR is for a feature.

PR Self Review Checklist:

  • Code is not following code style guidelines
  • Bad naming: make sure you would understand your code if you read it a few months from now.
  • KISS: Keep it simple, Sweetie (not stupid!).
  • DRY: Don't Repeat Yourself.
  • Code that is not readable: too many nested 'if's are a bad sign.
  • Performance issues
  • Complicated constructions that need refactoring or comments: code should almost always be self-explanatory.
  • Grammar errors.

FOR PR REVIEWER ONLY:

As a reviewer, your feedback should be focused on the idea, not the person. Seek to understand, be respectful, and focus on constructive dialog.

As a contributor, your responsibility is to learn from suggestions and iterate your pull request should it be needed based on feedback. Seek to collaborate and produce the best possible contribution to the greater whole.

  • Correct — Does the change do what it’s supposed to? ie: code 100% fulfilling the requirements?
  • Secure — Would a nefarious party find some way to exploit this change? ie: everything is sanitized/escaped appropriately for any SQL or XSS injection possibilities?
  • Readable — Will your future self be able to understand this change months down the road?
  • Elegant — Does the change fit aesthetically within the overall style and architecture?

Summary by CodeRabbit

Based on the comprehensive summary, here are the updated release notes:

  • New Features

    • Added a new Status page in the admin dashboard with dynamic content rendering.
    • Introduced DataView Table component for flexible data management.
    • Implemented a Sortable List component with drag-and-drop functionality.
    • Enhanced dashboard navigation with React routing capabilities.
    • Added new REST API endpoints for managing continents and countries.
    • Introduced new components for status elements, including Button, Heading, Link, and more.
    • Added new useWindowDimensions hook for tracking viewport dimensions.
    • Introduced VendorNavMenuChecker for managing vendor dashboard navigation.
    • Added NewDashboard class for custom dashboard templates.
    • Enhanced withdrawal management with new components and hooks for handling requests and balances.
    • Added a new Filter component for standardized filtering operations.
    • Introduced DokanModal for customizable modal dialogs.
  • Improvements

    • Updated REST API endpoints for customers, continents, and countries.
    • Enhanced the integration of React components and styles into the asset management system.
    • Improved error handling and loading states across various components.
  • Technical Updates

    • Upgraded Tailwind CSS configuration.
    • Updated webpack entry points and configuration.
    • Added new dependencies for improved functionality.
    • Extended the global Window interface for better type safety in TypeScript.
  • Documentation

    • Added comprehensive documentation for components, hooks, and utilities.
    • Provided implementation guides for new features.
    • Enhanced documentation for the DataView Table and Sortable List components.
    • Updated documentation for defining menus and managing PHP overrides in React applications.
    • Introduced guidelines for creating filter and slot documentation.

This comment was marked as off-topic.

coderabbitai[bot]

This comment was marked as off-topic.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (1)
src/Layout/index.tsx (1)

46-69: LGTM: Layout component structure is well-designed and flexible.

The Layout component is well-structured and provides flexibility through conditional rendering of header and footer components. The use of SlotFillProvider is appropriate for WordPress plugin integration.

Consider using default prop values for better readability:

const Layout = ({
    children,
    route,
-   title = '',
+   title = '', // Consider moving this default to the prop definition
    headerComponent,
    footerComponent,
}: LayoutProps) => {
    // ...
}

This change doesn't affect functionality but can improve code readability.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between a2701f5 and 057a92f.

📒 Files selected for processing (4)
  • src/Dashboard/index.tsx (1 hunks)
  • src/Layout/Header.tsx (1 hunks)
  • src/Layout/index.tsx (1 hunks)
  • src/Routing/index.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/Dashboard/index.tsx
  • src/Layout/Header.tsx
  • src/Routing/index.tsx
🧰 Additional context used
🔇 Additional comments (6)
src/Layout/index.tsx (6)

1-9: LGTM: Imports are appropriate and comprehensive.

The imports cover all necessary dependencies for the component's functionality, including WordPress-specific elements and custom components.


14-22: LGTM: ThemeProvider implementation is correct and follows best practices.

The ThemeProvider component correctly manages the theme state and provides it to its children through the context. The use of useState for theme management is appropriate for this use case.


24-43: LGTM: Type definitions are comprehensive and enhance type safety.

The DokanRoute type and LayoutProps interface provide clear and comprehensive type definitions, which will improve code readability and catch potential type-related errors early in development.


72-74: LGTM: useTheme custom hook is correctly implemented.

The useTheme custom hook provides a convenient way to access the theme context in other components. Its implementation follows React hook conventions.


76-76: LGTM: Default export is correct.

The Layout component is correctly exported as the default export, following common React component export patterns.


1-76: Overall, the Layout component is well-implemented with room for minor improvements.

The new Layout component provides a flexible and type-safe structure for the application. It effectively integrates WordPress-specific components and implements theming capabilities. The code follows React best practices and is well-organized.

To further improve the code:

  1. Address the issue raised in the previous review comment regarding the default value for ThemeContext (lines 11-12).
  2. Implement the null check for route.id as suggested in the previous review comment (line 65).
  3. Consider moving the default value for the title prop to the prop definition for improved readability.

These changes will enhance the robustness and maintainability of the component.

To ensure that the Layout component is being used correctly throughout the project, you can run the following verification script:

This script will help identify where the Layout component and useTheme hook are being used, allowing you to verify that they are being implemented correctly across the project.

mralaminahamed and others added 2 commits October 21, 2024 13:47
This commit introduces a new REST API endpoint for searching customers
specific to a vendor's orders. Key changes include:

- Add new route `/dokan/v1/customers/search` in CustomersController
- Implement `search_customers` method with the following features:
  * Search customers by ID or term (name/email)
  * Limit results to customers who have ordered from the current vendor
  * Support excluding specific customer IDs
  * Limit results to 20 when search term is less than 3 characters
  * Apply `dokan_json_search_found_customers` filter for extensibility
- Add permission check to ensure only users with 'edit_shop_orders' capability can access
- Include detailed PHPDoc for the new filter

This feature allows vendors to efficiently search their customer base
through the REST API, mirroring the functionality of the existing AJAX action
while providing a standardized API interface.
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (2)
src/Routing/index.tsx (2)

1-5: Remove unused imports to improve code cleanliness and performance.

The following imports are not used in this file and should be removed:

  • redirect
  • replace

Apply this diff to remove unused imports:

-import { useNavigate, useParams, useLocation, redirect, replace, useMatches, useNavigation,  } from 'react-router-dom';
+import { useNavigate, useParams, useLocation, useMatches, useNavigation } from 'react-router-dom';

7-41: LGTM! Minor formatting suggestion.

The withRouter higher-order component is well-implemented and provides a good abstraction for adding routing props to other components. It correctly handles both function and element components.

Consider removing extra spaces in the parameter destructuring for consistency:

-        let params   = useParams();
+        let params = useParams();
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 057a92f and 3d4d19c.

📒 Files selected for processing (2)
  • src/Dashboard/index.tsx (1 hunks)
  • src/Routing/index.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/Dashboard/index.tsx
🧰 Additional context used
🔇 Additional comments (2)
src/Routing/index.tsx (2)

70-70: LGTM! Default export is correct.

The default export of the getRoutes function is appropriate and follows good module design practices.


43-68: ⚠️ Potential issue

Address TypeScript errors and ensure consistent path prefixes.

  1. The paths in the route definitions are inconsistent. Some start with '/' while others don't. This can lead to unexpected routing behavior.

  2. The use of @ts-ignore suppresses TypeScript errors, which can hide potential issues. Instead, properly type the wp object.

To resolve these issues:

  1. Make the paths consistent by adding a leading '/' to all paths:
-            path: 'settings',
+            path: '/settings',
  1. Remove the @ts-ignore comment and properly type the wp object. You can declare the type for wp or extend the Window interface:
declare global {
  interface Window {
    wp: {
      hooks: {
        applyFilters: (filterName: string, value: any, ...args: any[]) => any;
      };
    };
  }
}

routes = window.wp.hooks.applyFilters('dokan-dashboard-routes', routes) as Array<DokanRoute>;

These changes will improve type safety and consistency in your routing logic.

coderabbitai[bot]

This comment was marked as off-topic.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (2)
src/Layout/Header.tsx (2)

7-18: LGTM: Well-structured and flexible component rendering.

The component's structure is well-organized and utilizes Tailwind CSS for responsive styling. The use of Slot components for extensibility is a great practice. The conditional rendering of the title and passing of the navigate function to the header actions slot are implemented correctly.

Consider adding an aria-label to the outer div to improve accessibility:

- <div className="flex items-center sm:flex-wrap md:flex-nowrap">
+ <div className="flex items-center sm:flex-wrap md:flex-nowrap" aria-label="Page header">

1-21: Overall: Excellent implementation of the Header component.

This Header component is well-implemented and aligns perfectly with the PR objectives of setting up a skeleton for the new vendor dashboard. It provides a flexible and extensible structure, utilizing WordPress components and React Router for navigation. The use of Slot components allows for easy customization, which is crucial for a dashboard layout.

The component follows React best practices, uses modern functional component syntax, and leverages Tailwind CSS for responsive styling. This implementation sets a solid foundation for further development of the dashboard layout.

As you continue developing the dashboard, consider the following:

  1. Implement unit tests for this component to ensure its behavior remains consistent as the project evolves.
  2. Document the usage of the Slot components to guide other developers on how to extend the header functionality.
  3. Consider creating a theme context if you plan to implement dark mode or other theme variations in the future.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between c295722 and 0b1ce02.

📒 Files selected for processing (1)
  • src/Layout/Header.tsx (1 hunks)
🧰 Additional context used
🔇 Additional comments (4)
src/Layout/Header.tsx (4)

1-2: LGTM: Imports are appropriate and necessary.

The imports of Slot from @wordpress/components and useNavigate from react-router-dom are well-chosen for the component's requirements. They align with the WordPress ecosystem and provide necessary routing functionality.


4-4: LGTM: Component definition is clear and follows best practices.

The Header component is well-defined as a functional component with a descriptive name. The use of default prop value for title is a good practice for handling optional props.


5-5: LGTM: Proper use of the useNavigate hook.

The useNavigate hook is correctly used and stored in a well-named constant. This setup will allow for programmatic navigation within the component.


21-21: LGTM: Appropriate default export.

The default export of the Header component is correct and follows common React component export patterns.

coderabbitai[bot]

This comment was marked as off-topic.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Outside diff range and nitpick comments (3)
src/Layout/index.tsx (1)

25-44: Add JSDoc documentation and improve type consistency.

The type definitions would benefit from documentation and consistent optionality.

+/**
+ * Represents a route configuration in the Dokan dashboard
+ */
 export type DokanRoute = {
+    /** Unique identifier for the route */
     id: string;
+    /** Display title for the route */
     title?: string;
-    icon?: JSX.Element | React.ReactNode;
+    /** Icon component to display (React.ReactNode includes JSX.Element) */
+    icon?: React.ReactNode;
-    element: JSX.Element | React.ReactNode;
+    /** Component to render for this route */
+    element: React.ReactNode;
     // ... rest of the type
 };

+/**
+ * Props for the Layout component
+ */
 interface LayoutProps {
     children: React.ReactNode;
     route: DokanRoute;
     title?: string;
-    headerComponent?: JSX.Element|React.ReactNode;
-    footerComponent?: JSX.Element|React.ReactNode;
+    headerComponent?: React.ReactNode;
+    footerComponent?: React.ReactNode;
 }
package.json (2)

64-64: Consider code-splitting for React Router.

The addition of react-router-dom is appropriate for dashboard navigation. However, ensure route-based code splitting is implemented to optimize initial load performance.

Recommendations:

  1. Use React.lazy() for route components
  2. Implement Suspense boundaries
  3. Consider implementing progressive loading for dashboard sections

Line range hint 25-64: Review bundle size impact.

The addition of multiple new dependencies could significantly increase the bundle size. Consider implementing appropriate optimization strategies.

Recommendations:

  1. Implement tree-shaking for all new dependencies
  2. Consider using dynamic imports for less frequently used components
  3. Monitor the bundle size impact using webpack-bundle-analyzer
  4. Implement chunking strategies to optimize loading performance
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between e59521e and e6bf1ec.

📒 Files selected for processing (2)
  • package.json (3 hunks)
  • src/Layout/index.tsx (1 hunks)
🔇 Additional comments (4)
src/Layout/index.tsx (1)

1-10: LGTM! Well-organized imports following WordPress conventions.

The imports are properly structured, using WordPress-specific packages where appropriate.

package.json (3)

57-63: Verify WordPress package versions compatibility.

The WordPress packages being added (@wordpress/components, @wordpress/data, etc.) are at different major versions (v28.x vs v4.x vs v7.x). This might lead to compatibility issues.

#!/bin/bash
# Check for potential version conflicts in WordPress packages
echo "Checking @wordpress/* package usage..."
rg -l "@wordpress" | xargs cat | rg "from '@wordpress/"

56-56: Verify @getdokan/dokan-ui compatibility.

The addition of @getdokan/dokan-ui (v1.0.14) is a significant change. Ensure it's compatible with the WordPress admin environment and follows the project's design system.

#!/bin/bash
# Check for potential UI component usage
echo "Checking dokan-ui component usage..."
rg -l "@getdokan/dokan-ui" | xargs cat | rg "from '@getdokan/dokan-ui"

25-26: Verify Tailwind CSS configuration to prevent style conflicts.

The addition of Tailwind CSS utilities (@tailwindcss/forms, @tailwindcss/typography, tailwindcss-scoped-preflight) is appropriate for a modern React dashboard. However, ensure proper scoping to prevent conflicts with WordPress admin styles.

Consider the following recommendations:

  1. Use tailwindcss-scoped-preflight to scope Tailwind's base styles
  2. Configure content paths in tailwind.config.js to minimize bundle size
  3. Add appropriate CSS cascade layers to manage style precedence

Also applies to: 39-39

src/Layout/index.tsx Outdated Show resolved Hide resolved
src/Layout/index.tsx Outdated Show resolved Hide resolved
src/Layout/index.tsx Outdated Show resolved Hide resolved
…er-api' into update/vendor-dashboard-structure

# Conflicts:
#	includes/REST/Manager.php
coderabbitai[bot]

This comment was marked as off-topic.

coderabbitai[bot]

This comment was marked as off-topic.

@shashwatahalder01

This comment was marked as resolved.

@shashwatahalder01

This comment was marked as resolved.

@shashwatahalder01

This comment was marked as resolved.

@shashwatahalder01

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as off-topic.

Aunshon and others added 2 commits February 11, 2025 14:52
# Conflicts:
#	includes/DependencyManagement/Providers/CommonServiceProvider.php
* feat: react admin dashboard

* refactor: implemented the `Hookable` Interface

* refactor: implemented the `Hookable` Interface

* refactor: implemented the new servicefor AdminDashboardServiceProvider.php

* refactor: implemented the `Hookable` to Dashboard

* chore: comment changed
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

♻️ Duplicate comments (1)
includes/Admin/Status/Status.php (1)

21-23: ⚠️ Potential issue

Ensure data is properly escaped to prevent security vulnerabilities.

The escape_data method currently returns data without any escaping, which may lead to security vulnerabilities like XSS attacks if the data is output directly to the browser.

Apply this diff:

public function escape_data( string $data ): string {
-    return $data;
+    return esc_html( $data );
}
🧹 Nitpick comments (7)
includes/Admin/Dashboard/Dashboard.php (3)

28-31: Ensure robust error handling for hook registration.
Though the hooks are standard, consider adding try-catch blocks or additional validation for any non-typical edge cases if third-party integrations might tamper with these hooks.


74-75: Address the TODO or remove stale comment.
Leaving a TODO for production code can cause confusion later. If you have a definite plan to refactor this subsection, consider tracking it in an issue or removing the comment once resolved.


220-221: Fix class closing brace placement to satisfy coding standards.
According to the pipeline failure, the closing brace must be on a new line after the class body.

 }
+
src/admin/dashboard/components/Layout.tsx (1)

6-15: Provide explicit TypeScript types for props.
Defining an interface for the route and children props would improve type safety and readability.

-const Layout = ( { children, route } ) => {
+interface LayoutProps {
+    children: React.ReactNode;
+    route: { id: string };
+}
+
+const Layout = ( { children, route }: LayoutProps ) => {
src/admin/dashboard/components/Dashboard.tsx (2)

33-44: Add error boundary for route rendering.

The route mapping lacks error handling for invalid route elements.

 const mapedRoutes = routes.map((route) => {
+    const RouteErrorBoundary = ({ children }: { children: React.ReactNode }) => {
+        return (
+            <ErrorBoundary fallback={<div>Something went wrong!</div>}>
+                {children}
+            </ErrorBoundary>
+        );
+    };
+
     const WithRouterComponent = withRouter(route.element);

     return {
         path: route.path,
         element: (
+            <RouteErrorBoundary>
                 <Layout route={route}>
                     <WithRouterComponent />
                 </Layout>
+            </RouteErrorBoundary>
         ),
     };
 });

30-53: Add loading state for route initialization.

The component should handle loading states while routes are being initialized.

 const Dashboard = () => {
+    const [isLoading, setIsLoading] = useState(true);
     const routes = getAdminRoutes();
+    
+    useEffect(() => {
+        setIsLoading(false);
+    }, []);

     const mapedRoutes = routes.map((route) => {
         // ... existing code ...
     });

     const router = createHashRouter(mapedRoutes);

     return (
         <>
+            {isLoading ? (
+                <div>Loading...</div>
+            ) : (
                 <RouterProvider router={router} />
+            )}
         </>
     );
 };
src/admin/dashboard/components/Header.tsx (1)

132-138: Improve accessibility for dropdown menu.

The dropdown menu needs proper keyboard navigation and visibility toggle.

Apply this diff:

<div
    className={`absolute right-0 z-10 mt-2 w-48 origin-top-right rounded-md bg-white py-1 shadow-lg ring-1 ring-black/5 focus:outline-none ${
+        isUserMenuOpen ? '' : 'hidden'
    }`}
    role="menu"
    aria-orientation="vertical"
    aria-labelledby="user-menu-button"
-    tabIndex="-1"
+    onKeyDown={(e) => {
+        if (e.key === 'Escape') {
+            setIsUserMenuOpen(false);
+        }
+    }}
>
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7f0c337 and 27ea3d7.

📒 Files selected for processing (15)
  • includes/Admin/Dashboard/Dashboard.php (1 hunks)
  • includes/Admin/Dashboard/Pageable.php (1 hunks)
  • includes/Admin/Dashboard/Pages/AbstractPage.php (1 hunks)
  • includes/Admin/Dashboard/Pages/Status.php (1 hunks)
  • includes/Admin/Status/Status.php (1 hunks)
  • includes/DependencyManagement/Providers/AdminDashboardServiceProvider.php (1 hunks)
  • includes/DependencyManagement/Providers/ServiceProvider.php (1 hunks)
  • src/Status/index.tsx (1 hunks)
  • src/admin/dashboard/admin-dashboard-tailwind.config.js (1 hunks)
  • src/admin/dashboard/components/Dashboard.tsx (1 hunks)
  • src/admin/dashboard/components/Header.tsx (1 hunks)
  • src/admin/dashboard/components/Layout.tsx (1 hunks)
  • src/admin/dashboard/index.tsx (1 hunks)
  • src/admin/dashboard/style.scss (1 hunks)
  • webpack-entries.js (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • src/admin/dashboard/admin-dashboard-tailwind.config.js
  • src/admin/dashboard/style.scss
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/Status/index.tsx
  • webpack-entries.js
🧰 Additional context used
🪛 GitHub Actions: Inspections
includes/Admin/Dashboard/Dashboard.php

[error] 1-1: The closing brace for the class must go on the next line after the body.

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: merge-reports
🔇 Additional comments (8)
includes/Admin/Dashboard/Dashboard.php (1)

208-210: Check for null screen object.
get_current_screen() can sometimes return null in certain edge conditions or if called too early. Safeguard this to avoid potential PHP errors:

 if ( $screen && ( $screen->id === 'toplevel_page_dokan' || $screen->id === 'dokan_page_dokan-dashboard' ) ) {
     // Enqueue scripts...
 }
includes/DependencyManagement/Providers/AdminDashboardServiceProvider.php (1)

9-29: LGTM! Well-structured service provider implementation.

The service provider follows best practices:

  • Proper use of dependency injection
  • Clear service registration mechanism
  • Good separation of concerns
includes/Admin/Dashboard/Pages/AbstractPage.php (1)

17-23: LGTM! Well-implemented hook registration.

The hook registration logic correctly:

  • Checks admin context
  • Uses WordPress filter API
  • Follows single responsibility principle
includes/Admin/Dashboard/Pageable.php (1)

31-31: LGTM! Well-documented return type.

The return type documentation is clear and specific, properly describing the array structure.

includes/Admin/Dashboard/Pages/Status.php (2)

10-10: Replace placeholder version constant.

The DOKAN_SINCE placeholder needs to be replaced with the actual version number where this feature was introduced.


64-78: Add version fallback for assets.

The asset version should have a fallback in case the asset file is not found.

Apply this diff:

    public function register(): void {
-        $asset_file = include DOKAN_DIR . '/assets/js/dokan-status.asset.php';
+        $asset_file = file_exists( DOKAN_DIR . '/assets/js/dokan-status.asset.php' )
+            ? include DOKAN_DIR . '/assets/js/dokan-status.asset.php'
+            : [ 'dependencies' => [], 'version' => DOKAN_VERSION ];

        wp_register_script(
            'dokan-status',
-            DOKAN_PLUGIN_ASSEST . '/js/dokan-status.js',
+            DOKAN_PLUGIN_ASSETS . '/js/dokan-status.js',
            $asset_file['dependencies'],
            $asset_file['version'],
            [
                'strategy' => 'defer',
                'in_footer' => true,
            ]
        );

-        wp_register_style( 'dokan-status', DOKAN_PLUGIN_ASSEST . '/css/dokan-status.css', [], $asset_file['version'] );
+        wp_register_style( 'dokan-status', DOKAN_PLUGIN_ASSETS . '/css/dokan-status.css', [], $asset_file['version'] );
    }
includes/Admin/Status/Status.php (1)

41-80: Remove or implement commented code.

Large blocks of commented code should either be removed or implemented. If this is work in progress, consider adding a TODO comment explaining the plan.

Do you need assistance implementing this code or should it be removed?

includes/DependencyManagement/Providers/ServiceProvider.php (1)

65-65: LGTM!

The addition of AdminDashboardServiceProvider follows the established pattern of service provider registration.

Comment on lines +5 to +6
const dashboardDomNode = document.getElementById( 'dokan-admin-dashboard' );
const dashboardRoot = createRoot( dashboardDomNode! );
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Avoid using non-null assertion on DOM element prematurely.
Consider deferring the creation of the React root until after verifying the DOM node is non-null. This prevents potential runtime errors if the element is missing.

-const dashboardRoot = createRoot( dashboardDomNode! );
 domReady( () => {
+    if ( dashboardDomNode ) {
+        const dashboardRoot = createRoot( dashboardDomNode );
         dashboardRoot.render( <Dashboard /> );
     }
📝 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. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const dashboardDomNode = document.getElementById( 'dokan-admin-dashboard' );
const dashboardRoot = createRoot( dashboardDomNode! );
const dashboardDomNode = document.getElementById( 'dokan-admin-dashboard' );
domReady( () => {
if ( dashboardDomNode ) {
const dashboardRoot = createRoot( dashboardDomNode );
dashboardRoot.render( <Dashboard /> );
}
});

/**
* Register the hooks.
*
* @since DOKAN_SINCE
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Replace placeholder version constant.

The @since DOKAN_SINCE placeholder needs to be replaced with the actual version number.

-     * @since DOKAN_SINCE
+     * @since 3.9.0
📝 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. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
* @since DOKAN_SINCE
* @since 3.9.0

Comment on lines +15 to +19
// @ts-ignore
routes = wp.hooks.applyFilters(
'dokan-admin-dashboard-routes',
routes
) as Array< DokanAdminRoute >;
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Remove @ts-ignore and add proper type definitions.

Instead of ignoring TypeScript errors, add proper type definitions for the WordPress hooks API.

-    // @ts-ignore
-    routes = wp.hooks.applyFilters(
+    routes = (window as any).wp.hooks.applyFilters(

Consider creating type definitions for WordPress hooks:

declare global {
    interface Window {
        wp: {
            hooks: {
                applyFilters<T>(hookName: string, ...args: any[]): T;
            };
        };
    }
}

*
* @package WeDevs\Dokan\Admin\Dashboard
*
* @since DOKAN_SINCE
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Replace placeholder version constant.

The @since DOKAN_SINCE placeholder needs to be replaced with the actual version number.

-     * @since DOKAN_SINCE
+     * @since 3.9.0
📝 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. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
* @since DOKAN_SINCE
* @since 3.9.0

@@ -0,0 +1,205 @@
const Header = () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add TypeScript types and state management.

The component lacks TypeScript types and state management for mobile menu and user menu toggles.

Apply this diff:

+import { useState } from 'react';
+
+interface HeaderProps {
+    logoUrl?: string;
+    companyName?: string;
+}
+
-const Header = () => {
+const Header: React.FC<HeaderProps> = ({ 
+    logoUrl = process.env.REACT_APP_LOGO_URL,
+    companyName = 'Your Company'
+}) => {
+    const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
+    const [isUserMenuOpen, setIsUserMenuOpen] = useState(false);
+
+    const toggleMobileMenu = () => setIsMobileMenuOpen(!isMobileMenuOpen);
+    const toggleUserMenu = () => setIsUserMenuOpen(!isUserMenuOpen);

Also applies to: 205-205

Comment on lines +51 to +55
<img
className="h-8 w-auto"
src="https://tailwindui.com/plus/img/logos/mark.svg?color=indigo&shade=500"
alt="Your Company"
/>
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Replace hardcoded logo URL with dynamic value.

The logo URL should be configurable and not hardcoded to an external service.

Apply this diff:

<img
    className="h-8 w-auto"
-    src="https://tailwindui.com/plus/img/logos/mark.svg?color=indigo&shade=500"
+    src={process.env.REACT_APP_LOGO_URL || '/assets/images/logo.svg'}
    alt="Your Company"
/>
📝 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. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<img
className="h-8 w-auto"
src="https://tailwindui.com/plus/img/logos/mark.svg?color=indigo&shade=500"
alt="Your Company"
/>
<img
className="h-8 w-auto"
src={process.env.REACT_APP_LOGO_URL || '/assets/images/logo.svg'}
alt="Your Company"
/>

Comment on lines +124 to +128
<img
className="size-8 rounded-full"
src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
alt=""
/>
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Replace hardcoded profile image URL.

The profile image URL should be dynamically loaded from the user's data.

Apply this diff:

<img
    className="size-8 rounded-full"
-    src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
+    src={currentUser?.avatarUrl || '/assets/images/default-avatar.png'}
-    alt=""
+    alt={`${currentUser?.name}'s profile`}
/>
📝 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. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<img
className="size-8 rounded-full"
src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
alt=""
/>
<img
className="size-8 rounded-full"
src={currentUser?.avatarUrl || '/assets/images/default-avatar.png'}
alt={`${currentUser?.name}'s profile`}
/>

@shashwatahalder01

This comment was marked as resolved.

* feat: react admin dashboard

* refactor: implemented the `Hookable` Interface

* refactor: implemented the `Hookable` Interface

* refactor: implemented the new servicefor AdminDashboardServiceProvider.php

* refactor: implemented the `Hookable` to Dashboard

* chore: comment changed

* chore: dokan ui scoped preflight added

* refactor: moved mutation observer from footer to React app.
coderabbitai[bot]

This comment was marked as off-topic.

coderabbitai[bot]

This comment was marked as off-topic.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
src/dashboard/Withdraw/WithdrawRequests.tsx (1)

23-51: ⚠️ Potential issue

Fix critical issues in useEffect implementation.

  1. The dependency array is missing several dependencies:

    • navigate
    • useWithdrawRequestHook.setView
    • useWithdrawRequestHook.fetchWithdrawRequests
    • useWithdrawRequestHook.view
    • useWithdrawRequestHook.lastPayload
  2. The user_id is hardcoded to 1, which is incorrect.

Apply this fix:

     useWithdrawRequestHook.fetchWithdrawRequests({
         per_page: useWithdrawRequestHook?.view?.perPage,
         page,
         status,
-        user_id: 1,
+        user_id: currentUser.data.id,
     });
-}, [location.search, currentUser?.data]);
+}, [
+    location.search,
+    currentUser?.data,
+    navigate,
+    useWithdrawRequestHook.setView,
+    useWithdrawRequestHook.fetchWithdrawRequests,
+    useWithdrawRequestHook.view,
+    useWithdrawRequestHook.lastPayload
+]);
🧹 Nitpick comments (3)
src/dashboard/Withdraw/WithdrawRequests.tsx (2)

21-21: Move validStatuses array outside the component.

Define validStatuses as a constant outside the component to prevent unnecessary re-creation on each render and improve reusability.

+const VALID_STATUSES = ['pending', 'approved', 'cancelled'] as const;
+
 function WithdrawRequests() {
-    const validStatuses = ['pending', 'approved', 'cancelled'];

124-131: Simplify the return statement.

The return statement has unnecessary nested fragments that can be simplified.

-    return (
-        <>
-            <div className="dokan-withdraw-wrapper dokan-react-withdraw space-y-6">
-                <Content />
-            </div>
-        </>
-    );
+    return (
+        <div className="dokan-withdraw-wrapper dokan-react-withdraw space-y-6">
+            <Content />
+        </div>
+    );
src/dashboard/Withdraw/withdraw-tailwind.config.js (1)

1-3: Consider using path aliases for imports.

While the relative import works, consider using path aliases (e.g., @config/base-tailwind.config) to improve maintainability and make the imports more resilient to file structure changes.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dfdd5bd and 7ec9cfd.

📒 Files selected for processing (4)
  • src/dashboard/Withdraw/WithdrawRequests.tsx (1 hunks)
  • src/dashboard/Withdraw/index.tsx (1 hunks)
  • src/dashboard/Withdraw/tailwind.scss (1 hunks)
  • src/dashboard/Withdraw/withdraw-tailwind.config.js (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/dashboard/Withdraw/tailwind.scss
  • src/dashboard/Withdraw/index.tsx
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: e2e tests (3, 3)
  • GitHub Check: e2e tests (2, 3)
  • GitHub Check: e2e tests (1, 3)
  • GitHub Check: api tests (1, 1)
🔇 Additional comments (4)
src/dashboard/Withdraw/WithdrawRequests.tsx (2)

12-12: Add TypeScript type annotations to the component.

The component should have proper TypeScript type definitions for better type safety and documentation.


53-122: Extract components for better maintainability.

The Content component and repeated link structure should be extracted for better maintainability and reusability.

src/dashboard/Withdraw/withdraw-tailwind.config.js (2)

12-13: LGTM!

The export statement is clean and follows module conventions.


4-10:

✅ Verification successful

Verify the content path relative to the project root.

The content path looks correct but should be verified to ensure it properly matches files from the project root. Also, confirm that the base configuration's content paths are still relevant when spread into this configuration.


🏁 Script executed:

#!/bin/bash
# Description: Verify the existence of the specified path and matching files

# Check if the path exists
fd -t d "src/dashboard/Withdraw"

# List matching files to verify the glob pattern
fd -e js -e jsx -e ts -e tsx . "src/dashboard/Withdraw"

Length of output: 1100


Content path verified and confirmed.

The glob pattern (./src/dashboard/Withdraw/**/*.{js,jsx,ts,tsx}) correctly targets the Withdraw module files relative to the project root, and the verification script confirmed the presence of these files. Also, the spread of baseConfig.content appears correct, so please ensure that its paths remain relevant in context.

@mrabbani mrabbani added 👍 Dev Review Done and removed Needs: Dev Review It requires a developer review and approval labels Feb 13, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
src/dashboard/Withdraw/RequestWithdrawBtn.tsx (1)

99-139: 🛠️ Refactor suggestion

Enhance error handling and validation.

The function needs proper validation and error handling improvements:

  1. Remove console.error in production code
  2. Add validation for withdrawMethod before submission
     const handleCreateWithdraw = () => {
         const payload = {
             method: withdrawMethod,
             amount: unformatNumber( withdrawAmount ),
         };
 
+        if ( ! payload.method ) {
+            toast( {
+                title: __( 'Withdraw method is required', 'dokan' ),
+                type: 'error',
+            } );
+            return;
+        }
+
         if ( ! payload.amount ) {
             toast( {
                 title: __( 'Withdraw amount is required', 'dokan' ),
                 type: 'error',
             } );
             return;
         }
 
         withdrawHook
             .createWithdraw( payload )
             .then( () => {
                 setIsOpen( false );
                 toast( {
                     title: __( 'Withdraw request created.', 'dokan' ),
                     type: 'success',
                 } );
 
                 withdrawRequests.refresh();
             } )
             .catch( ( err ) => {
                 toast( {
                     title: err?.message ?? __( 'Failed to create withdraw.', 'dokan' ),
                     type: 'error',
                 } );
-                console.error( 'Error creating withdraw:', err );
+                // Use proper error logging service in production
             } );
     };
🧹 Nitpick comments (1)
src/dashboard/Withdraw/RequestWithdrawBtn.tsx (1)

49-57: Add type safety to unformatNumber function.

The function lacks proper type definitions and validation.

-    const unformatNumber = ( value ) => {
+    const unformatNumber = ( value: string | number ): number | string => {
         if ( value === '' ) {
             return value;
         }
+        if (typeof window?.accounting?.unformat !== 'function') {
+            console.warn('Accounting library not found');
+            return value;
+        }
         return window.accounting.unformat(
             value,
             window?.dokanFrontend?.currency.decimal
         );
     };
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7ec9cfd and 664a857.

📒 Files selected for processing (1)
  • src/dashboard/Withdraw/RequestWithdrawBtn.tsx (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: e2e tests (3, 3)
  • GitHub Check: e2e tests (2, 3)
  • GitHub Check: e2e tests (1, 3)
  • GitHub Check: api tests (1, 1)
🔇 Additional comments (2)
src/dashboard/Withdraw/RequestWithdrawBtn.tsx (2)

149-260: LGTM! Well-structured form handling.

The form components are well-organized with proper debouncing, validation, and formatting.


261-348: LGTM! Clean modal implementation.

The modal implementation is clean with proper state management and conditional rendering.

SimpleSelect,
useToast,
} from '@getdokan/dokan-ui';
import { RawHTML, useEffect, useState } from '@wordpress/element';
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Security: Replace RawHTML with safe alternatives.

Using RawHTML with dynamic content poses a security risk for XSS attacks, especially in error messages and payment method links.

Apply these changes:

-                    message = <RawHTML>{ err?.message }</RawHTML>;
+                    message = err?.message;
-                        <RawHTML>
-                            { sprintf(
-                                /* translators: %s: opening and closing anchor tags for "payment methods" link */
-                                __(
-                                    'No payment methods found to submit a withdrawal request. Please set up your %1$spayment methods%2$s first.',
-                                    'dokan-lite'
-                                ),
-                                `<a href="${ window?.dokanFrontend?.withdraw?.paymentSettingUrl }" class="cursor-pointer text-dokan-primary">`,
-                                '</a>'
-                            ) }
-                        </RawHTML>
+                        <>
+                            {__('No payment methods found to submit a withdrawal request. Please set up your ', 'dokan-lite')}
+                            <a 
+                                href={window?.dokanFrontend?.withdraw?.paymentSettingUrl} 
+                                className="cursor-pointer text-dokan-primary"
+                            >
+                                {__('payment methods', 'dokan-lite')}
+                            </a>
+                            {__(' first.', 'dokan-lite')}
+                        </>

Also applies to: 130-130, 245-255

Comment on lines +32 to +33
const currencySymbol = window?.dokanFrontend?.currency?.symbol ?? '';
const withdrawHook = useWithdraw();
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add null check for window object access.

The window object access needs proper null checks to prevent runtime errors.

-    const currencySymbol = window?.dokanFrontend?.currency?.symbol ?? '';
+    const currencySymbol = typeof window !== 'undefined' ? window?.dokanFrontend?.currency?.symbol ?? '' : '';
📝 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. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const currencySymbol = window?.dokanFrontend?.currency?.symbol ?? '';
const withdrawHook = useWithdraw();
const currencySymbol = typeof window !== 'undefined' ? window?.dokanFrontend?.currency?.symbol ?? '' : '';
const withdrawHook = useWithdraw();

@shashwatahalder01
Copy link
Contributor

shashwatahalder01 commented Feb 14, 2025

Scenario:
Loader Icon Appears on Both Buttons in Withdrawal Request Cancel Modal

Screenshot:
Screenshot at Feb 14 11-13-04

@shashwatahalder01
Copy link
Contributor

Scenario:
Request Withdraw Button Displays Insufficient Balance Warning Despite Sufficient Funds.

On the "View Payments" page, clicking the Request Withdraw button triggers an "Insufficient Balance" warning message, even when the vendor's account balance exceeds the minimum withdrawal restriction.

Steps to reproduce:

  1. Navigate to vendor > withdraw > view payments page
  2. Click withdraw button on the "View Payments" page.

Screencast

@shashwatahalder01
Copy link
Contributor

shashwatahalder01 commented Feb 14, 2025

Scenario:
console error on the withdraw page

Screenshot:
Screenshot at Feb 14 15-17-32

@shashwatahalder01
Copy link
Contributor

Scenario:
Console Error When Submitting Withdrawal Request Below Minimum Amount on First Attempt

When a user attempts to submit a withdrawal request for an amount below the minimum required amount, a console error occurs on the first attempt.

Steps to Reproduce:

  1. Navigate to Withdraw Page
  2. Enter an amount below the minimum withdrawal limit (e.g., enter $50 when the minimum is $100).
  3. Click the Submit or Request Withdraw button.
  4. Observe Console
  5. Navigate away from the withdrawal page (e.g., go to the Dashboard or another section). and then return back to the withdrawal page.
  6. Repeat steps 2 to 4 to observe if the error persists.

Screenshot:
Screenshot at Feb 14 15-25-06

@shashwatahalder01
Copy link
Contributor

Scenario:
There is no close button on the withdraw disbursement modal window

Screenshot:
Screenshot at Feb 14 16-58-34
Screenshot at Feb 14 16-58-45

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

Successfully merging this pull request may close these issues.

6 participants