Skip to content

Dashboard card, minicard and month picker component. (Base PR) #2789

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

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

Conversation

Aunshon
Copy link
Collaborator

@Aunshon Aunshon commented Jul 8, 2025

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

Closes

Screenshot

image
image
screencapture-dokan-dev-test-wp-admin-admin-php-2025-07-08-14_37_47

Copy link
Contributor

coderabbitai bot commented Jul 8, 2025

Walkthrough

This change introduces a new admin dashboard menu feature for the Dokan plugin, including backend PHP registration and a full-featured React-based dashboard UI. New components, styles, and build configurations are added, and the dashboard is integrated into the existing admin dashboard routing and asset pipeline.

Changes

File(s) Change Summary
includes/Admin/Dashboard/Pages/DashboardMenu.php Adds DashboardMenu PHP class for registering a new admin dashboard menu page and its assets.
includes/DependencyManagement/Providers/AdminDashboardServiceProvider.php Registers the DashboardMenu service in the admin dashboard service provider.
src/AdminDashboardMenu/Dashboard.tsx Introduces a new React dashboard component with sections for To-Do, Analytics, and Month Overview.
src/AdminDashboardMenu/Elements/Card.tsx
src/AdminDashboardMenu/Elements/MiniCard.tsx
src/AdminDashboardMenu/Elements/MonthPicker.tsx
src/AdminDashboardMenu/Elements/Section.tsx
Adds reusable React UI components: Card, MiniCard, MonthPicker, and Section.
src/AdminDashboardMenu/index.tsx Registers the new dashboard route and mounts the React dashboard component.
src/AdminDashboardMenu/tailwind.config.js
src/AdminDashboardMenu/tailwind.scss
Adds Tailwind CSS configuration and styles for the new dashboard UI.
webpack-entries.js Registers a new Webpack entry point for the dashboard menu assets.

Sequence Diagram(s)

sequenceDiagram
    participant WPAdmin as WordPress Admin
    participant DashboardMenu as DashboardMenu PHP Class
    participant Webpack as Webpack Asset Pipeline
    participant ReactApp as Dashboard React App

    WPAdmin->>DashboardMenu: Loads admin dashboard
    DashboardMenu->>Webpack: Registers JS/CSS assets
    WPAdmin->>ReactApp: Initializes dashboard route (via registered assets)
    ReactApp->>ReactApp: Renders dashboard UI (To-Do, Analytics, Month Overview)
Loading

Possibly related PRs

Suggested labels

Needs: Dev Review

Suggested reviewers

  • mrabbani

Poem

In the dashboard’s cozy warren,
New menus hop into view—
Cards and charts in React’s garden,
Tailwind breezes styling through.
With every click, a stat revealed,
The admin’s work is less concealed—
🐇 Dokan’s dashboard, bright and new!

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

npm error Exit handler never called!
npm error This is an error with npm itself. Please report this error at:
npm error https://github.com/npm/cli/issues
npm error A complete log of this run can be found in: /.npm/_logs/2025-07-08T08_33_57_491Z-debug-0.log

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @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.

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: 17

🧹 Nitpick comments (8)
src/AdminDashboardMenu/index.tsx (1)

7-7: Consider addressing the TypeScript ignore.

The @ts-ignore comment suggests TypeScript issues with wp.hooks. Consider adding proper type definitions or using a more specific type assertion.

-    // @ts-ignore
-    wp.hooks.addFilter(
+    (wp.hooks as any).addFilter(

Or better yet, add proper WordPress hooks type definitions.

src/AdminDashboardMenu/Elements/MiniCard.tsx (2)

26-28: Consider extracting hard-coded colors to theme variables.

The purple color #7047EB and other colors like #F8F6FE are hard-coded throughout the component. Consider extracting these to theme variables or CSS custom properties for better maintainability and consistency.

- 'w-10 h-10 rounded flex items-center justify-center text-[#7047EB] mr-4',
+ 'w-10 h-10 rounded flex items-center justify-center text-primary mr-4',

42-44: Hard-coded colors should be theme-based.

Similar to the icon styling, the count badge uses hard-coded colors that should be extracted to theme variables for better maintainability.

- countType === 'primary'
-     ? 'bg-[#7047EB]'
-     : 'bg-[#F8F6FE]'
+ countType === 'primary'
+     ? 'bg-primary'
+     : 'bg-primary-light'
src/AdminDashboardMenu/Dashboard.tsx (2)

24-57: Consider reducing code duplication in To-Do section.

The To-Do section has repetitive MiniCard components with identical props. Consider extracting the data to an array and mapping over it to reduce duplication.

+ const todoItems = [
+     { id: 1, text: 'Vendor Approvals', count: 20, countType: 'primary' },
+     { id: 2, text: 'Vendor Approvals', count: 20, countType: 'secondary' },
+     // ... other items
+ ];

- <div className="grid sm:grid-cols-1 md:grid-cols-3 lg:grid-cols-4 gap-4">
-     <MiniCard... />
-     <MiniCard... />
-     // ... repeated components
- </div>
+ <div className="grid sm:grid-cols-1 md:grid-cols-3 lg:grid-cols-4 gap-4">
+     {todoItems.map(item => (
+         <MiniCard
+             key={item.id}
+             icon={<User />}
+             text={item.text}
+             count={item.count}
+             countType={item.countType}
+         />
+     ))}
+ </div>

11-14: Consider adding proper TypeScript interface for month data.

The monthData state could benefit from a proper TypeScript interface to ensure type safety.

+ interface MonthData {
+     month: string;
+     year: string;
+ }

- const [ monthData, setMonthData ] = useState( {
-     month: '',
-     year: '',
- } );
+ const [ monthData, setMonthData ] = useState<MonthData>( {
+     month: '',
+     year: '',
+ } );
src/AdminDashboardMenu/Elements/Card.tsx (1)

24-25: Extract hardcoded colors to theme variables.

Similar to other components, the hardcoded colors should be extracted to theme variables for consistency and maintainability.

- <div className="bg-[#F8F6FE] w-10 h-10 rounded flex items-center justify-center text-[#7047EB]">
+ <div className="bg-primary-light w-10 h-10 rounded flex items-center justify-center text-primary">
includes/Admin/Dashboard/Pages/DashboardMenu.php (1)

10-10: Update version placeholder.

The @since DOKAN_SINCE placeholder should be updated to the actual version number.

- * @since DOKAN_SINCE
+ * @since 3.x.x
src/AdminDashboardMenu/Elements/MonthPicker.tsx (1)

70-88: Extract year validation logic to a helper function.

The year validation logic is repeated in multiple places. Consider extracting it to a helper function for better maintainability.

+    const getValidYear = ( year: string | number | undefined ): number => {
+        if ( !year || isNaN( Number( String( year ) ) ) ) {
+            return new Date().getFullYear();
+        }
+        return Number( year );
+    };

     const handlePreviousYear = () => {
         setCurrentYear( ( prev ) => {
-            const newYear =
-                ! prev || isNaN( Number( String( prev ) ) )
-                    ? new Date().getFullYear() - 1
-                    : Number( prev ) - 1;
+            const newYear = getValidYear( prev ) - 1;
             return newYear.toString();
         } );
     };

     const handleNextYear = () => {
         setCurrentYear( ( prev ) => {
-            const newYear =
-                ! prev || isNaN( Number( String( prev ) ) )
-                    ? new Date().getFullYear() + 1
-                    : Number( prev ) + 1;
+            const newYear = getValidYear( prev ) + 1;
             return newYear.toString();
         } );
     };
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 017d357 and f89e43a.

📒 Files selected for processing (11)
  • includes/Admin/Dashboard/Pages/DashboardMenu.php (1 hunks)
  • includes/DependencyManagement/Providers/AdminDashboardServiceProvider.php (2 hunks)
  • src/AdminDashboardMenu/Dashboard.tsx (1 hunks)
  • src/AdminDashboardMenu/Elements/Card.tsx (1 hunks)
  • src/AdminDashboardMenu/Elements/MiniCard.tsx (1 hunks)
  • src/AdminDashboardMenu/Elements/MonthPicker.tsx (1 hunks)
  • src/AdminDashboardMenu/Elements/Section.tsx (1 hunks)
  • src/AdminDashboardMenu/index.tsx (1 hunks)
  • src/AdminDashboardMenu/tailwind.config.js (1 hunks)
  • src/AdminDashboardMenu/tailwind.scss (1 hunks)
  • webpack-entries.js (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (4)
src/AdminDashboardMenu/tailwind.config.js (1)
base-tailwind.config.js (1)
  • baseConfig (9-291)
src/AdminDashboardMenu/index.tsx (1)
src/admin/dashboard/components/Dashboard.tsx (1)
  • DokanAdminRoute (8-13)
src/AdminDashboardMenu/Dashboard.tsx (1)
src/components/Button.tsx (1)
  • DokanButton (50-64)
includes/Admin/Dashboard/Pages/DashboardMenu.php (2)
includes/Admin/Dashboard/Pages/AbstractPage.php (1)
  • AbstractPage (8-59)
includes/DependencyManagement/Providers/AdminDashboardServiceProvider.php (1)
  • register (29-36)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: e2e tests (2, 3)
  • GitHub Check: e2e tests (1, 3)
  • GitHub Check: e2e tests (3, 3)
  • GitHub Check: api tests (1, 1)
🔇 Additional comments (13)
src/AdminDashboardMenu/tailwind.scss (1)

1-3: LGTM! Clean Tailwind CSS setup.

The configuration correctly imports base Tailwind styles and specifies the local config. The commented import might be intentional during development.

webpack-entries.js (1)

61-61: LGTM! Correctly adds new webpack entry point.

The entry point follows the established naming pattern and correctly maps to the new AdminDashboardMenu index file.

src/AdminDashboardMenu/tailwind.config.js (1)

1-9: LGTM! Well-structured scoped Tailwind configuration.

The configuration correctly extends the base config while appropriately scoping the content scanning to only the AdminDashboardMenu directory. This approach optimizes build performance and ensures styles are generated only for relevant components.

includes/DependencyManagement/Providers/AdminDashboardServiceProvider.php (2)

6-6: LGTM! Proper import addition.

The DashboardMenu import is correctly placed and follows the existing namespace pattern.


23-23: LGTM! Service correctly added to registration.

The DashboardMenu service is properly added to the services array, ensuring it will be registered and tagged appropriately.

src/AdminDashboardMenu/index.tsx (1)

14-16: LGTM! Route configuration follows the correct pattern.

The route object correctly implements the DokanAdminRoute interface with proper usage of the satisfies keyword for type safety. The empty path string appears to be intentional for the default dashboard route.

src/AdminDashboardMenu/Elements/MiniCard.tsx (1)

5-12: Well-structured TypeScript interface.

The interface definition is comprehensive and properly typed, with good use of optional properties and union types for variants.

src/AdminDashboardMenu/Elements/Section.tsx (2)

4-9: Clean and well-structured interface.

The component interface is properly defined with appropriate optional properties and defaults. The structure supports flexible content rendering with optional tooltip and header elements.


16-36: Proper semantic HTML structure and conditional rendering.

The component uses semantic HTML with proper heading hierarchy and implements conditional rendering correctly for tooltip and section header elements.

src/AdminDashboardMenu/Elements/Card.tsx (2)

5-12: Well-designed TypeScript interface.

The interface properly defines all props with appropriate types, including union types for direction and nullable count. The content prop flexibility (string | JSX.Element) is well thought out.


27-46: Proper conditional rendering and color coding.

The count display section correctly uses conditional rendering and applies appropriate color coding for up/down indicators using green and red colors.

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

25-25: Clarify route configuration.

The route is set to '#' which might need clarification. Is this intentional for a hash-based route or should it point to a specific admin page?

Please verify if the route should be '#' or if it needs to point to a specific admin page URL.


66-75: Proper WordPress script registration.

The script registration follows WordPress best practices with proper dependency handling, versioning, and loading strategy configuration.

'dokan-admin-dashboard-dashboard',
( routes: Array< DokanAdminRoute > ) => {
routes.push( {
id: 'dokan-status',
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify the route ID naming convention.

The route ID is 'dokan-status' but this appears to be for a dashboard menu feature. Consider using a more descriptive ID like 'dokan-dashboard-menu' or 'dokan-admin-dashboard' to avoid confusion.


🏁 Script executed:

#!/bin/bash
# Description: Check if 'dokan-status' is used elsewhere or if this is intentional naming
# Expected: Find other usages of this route ID or similar patterns

rg -A 3 -B 3 "dokan-status" --type js --type ts --type tsx

Length of output: 86


🏁 Script executed:

#!/bin/bash
# Re-run search for 'dokan-status' without type filters to locate any occurrences
rg -A 3 -B 3 "dokan-status"

Length of output: 7849


🏁 Script executed:

#!/bin/bash
# Locate the DokanAdminRoute type/interface definition
rg -n "DokanAdminRoute" --type ts --type tsx -A 2 -B 2

Length of output: 82


Rename AdminDashboardMenu route ID to match webpack entry

The id: 'dokan-status' in src/AdminDashboardMenu/index.tsx
– conflicts with the existing “Status” page route and
– doesn’t align with the webpack entry dokan-admin-dashboard-menu

Please update the route ID:

• File: src/AdminDashboardMenu/index.tsx
Line: where id: 'dokan-status' is defined

Diff:

- id: 'dokan-status',
+ id: 'dokan-admin-dashboard-menu',
📝 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
id: 'dokan-status',
id: 'dokan-admin-dashboard-menu',
🤖 Prompt for AI Agents
In src/AdminDashboardMenu/index.tsx at line 13, the route ID is set to
'dokan-status', which conflicts with the existing "Status" page route and does
not match the webpack entry name 'dokan-admin-dashboard-menu'. Rename the route
ID from 'dokan-status' to 'dokan-admin-dashboard-menu' to resolve the conflict
and align with the webpack entry.

/>
<Card
icon={ <User /> }
text="Supprt Tickets"
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

Fix typo in text content.

There's a typo in the text "Supprt Tickets" which should be "Support Tickets".

- text="Supprt Tickets"
+ text="Support Tickets"
📝 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
text="Supprt Tickets"
text="Support Tickets"
🤖 Prompt for AI Agents
In src/AdminDashboardMenu/Dashboard.tsx at line 120, fix the typo in the text
property by changing "Supprt Tickets" to "Support Tickets" to correct the
spelling.

Comment on lines +95 to +139
<div className="grid sm:grid-cols-1 md:grid-cols-3 lg:grid-cols-4 gap-4">
<Card
icon={ <User /> }
text="New Products"
content="$120"
count={ 2.7 }
tooltip={ 'This is a simple tooltip' }
/>
<Card
icon={ <User /> }
text="Active vendors"
content="4"
count={ 2.7 }
countDirection="down"
tooltip={ 'This is a simple tooltip' }
/>
<Card
icon={ <User /> }
text="New Customers"
content="$120"
count={ 2.7 }
tooltip={ 'This is a simple tooltip' }
/>
<Card
icon={ <User /> }
text="Supprt Tickets"
content="$120"
count={ 2.7 }
tooltip={ 'This is a simple tooltip' }
/>
<Card
icon={ <User /> }
text="Refunds"
content="$120"
count={ 2.7 }
countDirection="down"
tooltip={ 'This is a simple tooltip' }
/>
<Card
icon={ <User /> }
text="Reviews"
content="$120"
count={ 2.7 }
/>
</div>
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

Consider extracting hardcoded data to constants or props.

The Month Overview section contains hardcoded data that should be extracted to constants or received as props for better maintainability and reusability.

+ const monthOverviewData = [
+     { id: 1, text: 'New Products', content: '$120', count: 2.7, tooltip: 'This is a simple tooltip' },
+     { id: 2, text: 'Active vendors', content: '4', count: 2.7, countDirection: 'down', tooltip: 'This is a simple tooltip' },
+     // ... other items
+ ];

- <div className="grid sm:grid-cols-1 md:grid-cols-3 lg:grid-cols-4 gap-4">
-     <Card... />
-     <Card... />
-     // ... repeated components
- </div>
+ <div className="grid sm:grid-cols-1 md:grid-cols-3 lg:grid-cols-4 gap-4">
+     {monthOverviewData.map(item => (
+         <Card
+             key={item.id}
+             icon={<User />}
+             text={item.text}
+             content={item.content}
+             count={item.count}
+             countDirection={item.countDirection}
+             tooltip={item.tooltip}
+         />
+     ))}
+ </div>
📝 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
<div className="grid sm:grid-cols-1 md:grid-cols-3 lg:grid-cols-4 gap-4">
<Card
icon={ <User /> }
text="New Products"
content="$120"
count={ 2.7 }
tooltip={ 'This is a simple tooltip' }
/>
<Card
icon={ <User /> }
text="Active vendors"
content="4"
count={ 2.7 }
countDirection="down"
tooltip={ 'This is a simple tooltip' }
/>
<Card
icon={ <User /> }
text="New Customers"
content="$120"
count={ 2.7 }
tooltip={ 'This is a simple tooltip' }
/>
<Card
icon={ <User /> }
text="Supprt Tickets"
content="$120"
count={ 2.7 }
tooltip={ 'This is a simple tooltip' }
/>
<Card
icon={ <User /> }
text="Refunds"
content="$120"
count={ 2.7 }
countDirection="down"
tooltip={ 'This is a simple tooltip' }
/>
<Card
icon={ <User /> }
text="Reviews"
content="$120"
count={ 2.7 }
/>
</div>
// Define this at the top of your component (or import from a separate constants file)
const monthOverviewData = [
{ id: 1, text: 'New Products', content: '$120', count: 2.7, tooltip: 'This is a simple tooltip' },
{ id: 2, text: 'Active vendors', content: '4', count: 2.7, countDirection: 'down', tooltip: 'This is a simple tooltip' },
{ id: 3, text: 'New Customers', content: '$120', count: 2.7, tooltip: 'This is a simple tooltip' },
{ id: 4, text: 'Supprt Tickets', content: '$120', count: 2.7, tooltip: 'This is a simple tooltip' },
{ id: 5, text: 'Refunds', content: '$120', count: 2.7, countDirection: 'down', tooltip: 'This is a simple tooltip' },
{ id: 6, text: 'Reviews', content: '$120', count: 2.7 },
];
...
return (
<div className="grid sm:grid-cols-1 md:grid-cols-3 lg:grid-cols-4 gap-4">
{monthOverviewData.map(item => (
<Card
key={item.id}
icon={<User />}
text={item.text}
content={item.content}
count={item.count}
countDirection={item.countDirection}
tooltip={item.tooltip}
/>
))}
</div>
);
🤖 Prompt for AI Agents
In src/AdminDashboardMenu/Dashboard.tsx between lines 95 and 139, the Card
components contain hardcoded data such as text, content, count, and tooltip
values. To improve maintainability and reusability, extract this data into a
constant array or object outside the JSX and map over it to render the Card
components dynamically. Alternatively, pass this data as props from a parent
component if applicable.

]
);

wp_register_style( 'dokan-admin-dashboard-menu', DOKAN_PLUGIN_ASSEST . '/css/dokan-admin-dashboard-menu.css', [], $asset_file['version'] );
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

Fix typo in constant name (CSS).

Same typo in the CSS asset registration.

- wp_register_style( 'dokan-admin-dashboard-menu', DOKAN_PLUGIN_ASSEST . '/css/dokan-admin-dashboard-menu.css', [], $asset_file['version'] );
+ wp_register_style( 'dokan-admin-dashboard-menu', DOKAN_PLUGIN_ASSETS . '/css/dokan-admin-dashboard-menu.css', [], $asset_file['version'] );
📝 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
wp_register_style( 'dokan-admin-dashboard-menu', DOKAN_PLUGIN_ASSEST . '/css/dokan-admin-dashboard-menu.css', [], $asset_file['version'] );
wp_register_style( 'dokan-admin-dashboard-menu', DOKAN_PLUGIN_ASSETS . '/css/dokan-admin-dashboard-menu.css', [], $asset_file['version'] );
🤖 Prompt for AI Agents
In includes/Admin/Dashboard/Pages/DashboardMenu.php at line 77, the constant
name for the CSS asset path is misspelled as DOKAN_PLUGIN_ASSEST. Correct the
typo by changing DOKAN_PLUGIN_ASSEST to DOKAN_PLUGIN_ASSET to properly reference
the CSS file location.


wp_register_script(
'dokan-admin-dashboard-menu',
DOKAN_PLUGIN_ASSEST . '/js/dokan-admin-dashboard-menu.js',
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

Fix typo in constant name.

There's a typo in the constant name DOKAN_PLUGIN_ASSEST which should be DOKAN_PLUGIN_ASSETS.

- DOKAN_PLUGIN_ASSEST . '/js/dokan-admin-dashboard-menu.js',
+ DOKAN_PLUGIN_ASSETS . '/js/dokan-admin-dashboard-menu.js',
📝 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
DOKAN_PLUGIN_ASSEST . '/js/dokan-admin-dashboard-menu.js',
- DOKAN_PLUGIN_ASSEST . '/js/dokan-admin-dashboard-menu.js',
+ DOKAN_PLUGIN_ASSETS . '/js/dokan-admin-dashboard-menu.js',
🤖 Prompt for AI Agents
In includes/Admin/Dashboard/Pages/DashboardMenu.php at line 68, correct the typo
in the constant name from DOKAN_PLUGIN_ASSEST to DOKAN_PLUGIN_ASSETS to ensure
the correct path is used for the JavaScript file.

Comment on lines +25 to +28
value = {
month: '',
year: '',
},
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

Update default value to match corrected type.

The default value should use numbers to match the corrected interface.

     value = {
-        month: '',
-        year: '',
+        month: 0,
+        year: 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
value = {
month: '',
year: '',
},
value = {
month: 0,
year: 0,
},
🤖 Prompt for AI Agents
In src/AdminDashboardMenu/Elements/MonthPicker.tsx around lines 25 to 28, the
default value for the month and year is set as empty strings, but the interface
expects numbers. Update the default value to use numeric types, such as 0 or
another appropriate number, for both month and year to match the corrected
interface.

Comment on lines +44 to +56
if (
deselectable &&
value?.month &&
Number( value?.month ) === monthIndex + 1 &&
value?.year &&
Number( value?.year ) === Number( currentYear )
) {
// @ts-ignore
onChange( { month: '', year: '' } );
setCurrentYear( '' );
setIsOpen( ! isOpen );
return;
}
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

Remove @ts-ignore and fix type handling.

The @ts-ignore comment indicates a type issue that should be resolved properly. After fixing the interface types, this logic needs to be updated.

             if (
                 deselectable &&
                 value?.month &&
-                Number( value?.month ) === monthIndex + 1 &&
+                value?.month === monthIndex + 1 &&
                 value?.year &&
-                Number( value?.year ) === Number( currentYear )
+                value?.year === Number( currentYear )
             ) {
-                // @ts-ignore
-                onChange( { month: '', year: '' } );
+                onChange( { month: 0, year: 0 } );
                 setCurrentYear( '' );
                 setIsOpen( ! isOpen );
                 return;
             }
📝 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
if (
deselectable &&
value?.month &&
Number( value?.month ) === monthIndex + 1 &&
value?.year &&
Number( value?.year ) === Number( currentYear )
) {
// @ts-ignore
onChange( { month: '', year: '' } );
setCurrentYear( '' );
setIsOpen( ! isOpen );
return;
}
if (
deselectable &&
value?.month &&
value?.month === monthIndex + 1 &&
value?.year &&
value?.year === Number( currentYear )
) {
onChange( { month: 0, year: 0 } );
setCurrentYear( '' );
setIsOpen( ! isOpen );
return;
}
🤖 Prompt for AI Agents
In src/AdminDashboardMenu/Elements/MonthPicker.tsx around lines 44 to 56, remove
the @ts-ignore comment and fix the type handling by updating the onChange call
to pass values that conform to the expected type interface. Ensure that the
month and year fields are set to appropriate empty or null values according to
the defined types instead of empty strings, and adjust the state setters
accordingly to maintain type consistency.

Comment on lines +140 to +161
<button
type="button"
onClick={ handlePreviousYear }
className="p-1 rounded-md hover:bg-gray-100 focus:outline-none"
>
<ChevronLeft className="w-5 h-5" />
</button>

<h2 className="text-lg font-semibold">
{ ! currentYear ||
isNaN( Number( currentYear ) )
? new Date().getFullYear()
: currentYear }
</h2>

<button
type="button"
onClick={ handleNextYear }
className="p-1 rounded-md hover:bg-gray-100 focus:outline-none"
>
<ChevronRight className="w-5 h-5" />
</button>
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 keyboard navigation and accessibility for year buttons.

The year navigation buttons should have proper labels and keyboard support.

                                 <button
                                     type="button"
                                     onClick={ handlePreviousYear }
                                     className="p-1 rounded-md hover:bg-gray-100 focus:outline-none"
+                                    aria-label={ __( 'Previous year' ) }
                                 >
                                     <ChevronLeft className="w-5 h-5" />
                                 </button>

                                 <h2 className="text-lg font-semibold">
                                     { ! currentYear ||
                                     isNaN( Number( currentYear ) )
                                         ? new Date().getFullYear()
                                         : currentYear }
                                 </h2>

                                 <button
                                     type="button"
                                     onClick={ handleNextYear }
                                     className="p-1 rounded-md hover:bg-gray-100 focus:outline-none"
+                                    aria-label={ __( 'Next year' ) }
                                 >
                                     <ChevronRight className="w-5 h-5" />
                                 </button>
📝 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
<button
type="button"
onClick={ handlePreviousYear }
className="p-1 rounded-md hover:bg-gray-100 focus:outline-none"
>
<ChevronLeft className="w-5 h-5" />
</button>
<h2 className="text-lg font-semibold">
{ ! currentYear ||
isNaN( Number( currentYear ) )
? new Date().getFullYear()
: currentYear }
</h2>
<button
type="button"
onClick={ handleNextYear }
className="p-1 rounded-md hover:bg-gray-100 focus:outline-none"
>
<ChevronRight className="w-5 h-5" />
</button>
<button
type="button"
onClick={ handlePreviousYear }
className="p-1 rounded-md hover:bg-gray-100 focus:outline-none"
aria-label={ __( 'Previous year' ) }
>
<ChevronLeft className="w-5 h-5" />
</button>
<h2 className="text-lg font-semibold">
{ ! currentYear ||
isNaN( Number( currentYear ) )
? new Date().getFullYear()
: currentYear }
</h2>
<button
type="button"
onClick={ handleNextYear }
className="p-1 rounded-md hover:bg-gray-100 focus:outline-none"
aria-label={ __( 'Next year' ) }
>
<ChevronRight className="w-5 h-5" />
</button>
🤖 Prompt for AI Agents
In src/AdminDashboardMenu/Elements/MonthPicker.tsx around lines 140 to 161, the
year navigation buttons lack accessibility features such as descriptive labels
and keyboard support. Add aria-label attributes to both buttons to describe
their actions (e.g., "Previous Year" and "Next Year") and ensure they are
focusable and operable via keyboard by verifying the onClick handlers work with
keyboard events or adding onKeyDown handlers if necessary.

Comment on lines +99 to +105
useEffect( () => {
// If not currentYear is set, set it to the current year.
if ( ! value?.year || isNaN( Number( String( value?.year ) ) ) ) {
// @ts-ignore
setCurrentYear( new Date().getFullYear() );
}
}, [] );
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

Fix useEffect dependency array and remove @ts-ignore.

The effect uses value but doesn't include it in the dependency array, and has an unnecessary @ts-ignore.

     useEffect( () => {
         // If not currentYear is set, set it to the current year.
-        if ( ! value?.year || isNaN( Number( String( value?.year ) ) ) ) {
-            // @ts-ignore
+        if ( ! value?.year || value?.year === 0 ) {
             setCurrentYear( new Date().getFullYear() );
         }
-    }, [] );
+    }, [ value?.year ] );
📝 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
useEffect( () => {
// If not currentYear is set, set it to the current year.
if ( ! value?.year || isNaN( Number( String( value?.year ) ) ) ) {
// @ts-ignore
setCurrentYear( new Date().getFullYear() );
}
}, [] );
useEffect( () => {
// If not currentYear is set, set it to the current year.
if ( ! value?.year || value?.year === 0 ) {
setCurrentYear( new Date().getFullYear() );
}
}, [ value?.year ] );
🤖 Prompt for AI Agents
In src/AdminDashboardMenu/Elements/MonthPicker.tsx around lines 99 to 105, the
useEffect hook uses the variable 'value' but does not include it in the
dependency array, which can cause stale closures. Also, the @ts-ignore comment
is unnecessary and should be removed. Fix this by adding 'value' to the
dependency array of useEffect and removing the @ts-ignore comment. Ensure the
effect runs correctly when 'value' changes without suppressing TypeScript
errors.

Comment on lines +171 to +178
const isSelected =
// @ts-ignore
value?.month &&
Number( value?.month ) === index + 1 &&
value?.year &&
// @ts-ignore
Number( value?.year ) ===
Number( currentYear );
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

Remove @ts-ignore comments and fix type handling.

After fixing the interface types, these @ts-ignore comments can be removed.

                     const isSelected =
-                        // @ts-ignore
                         value?.month &&
-                        Number( value?.month ) === index + 1 &&
+                        value?.month === index + 1 &&
                         value?.year &&
-                        // @ts-ignore
-                        Number( value?.year ) ===
+                        value?.year ===
                             Number( currentYear );
📝 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 isSelected =
// @ts-ignore
value?.month &&
Number( value?.month ) === index + 1 &&
value?.year &&
// @ts-ignore
Number( value?.year ) ===
Number( currentYear );
const isSelected =
value?.month &&
value?.month === index + 1 &&
value?.year &&
value?.year ===
Number( currentYear );
🤖 Prompt for AI Agents
In src/AdminDashboardMenu/Elements/MonthPicker.tsx around lines 171 to 178,
remove the @ts-ignore comments by properly typing the value object and its
properties. Update the interface or type definitions to ensure value.month and
value.year are correctly typed as numbers or strings convertible to numbers, so
explicit type assertions or conversions are safe and TypeScript errors are
resolved without ignoring them.

@Aunshon Aunshon self-assigned this Jul 8, 2025
@Aunshon Aunshon added Needs: Testing This requires further testing Needs: Dev Review It requires a developer review and approval labels Jul 8, 2025
@MdAsifHossainNadim MdAsifHossainNadim changed the title Dashboard card, minicard and month picker component. Dashboard card, minicard and month picker component. (Base PR) Jul 18, 2025
@MdAsifHossainNadim
Copy link
Contributor

@Aunshon Brother, we have an issue in this PR. Like:

  • Dashboard menu placement. (Render twice and not in top submenu)
  • Components should be comes from inisde admin/dashboard/pages
  • Handle the dashboard submenu from includes/Admin/Dashboard.php

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs: Dev Review It requires a developer review and approval Needs: Testing This requires further testing
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants