diff --git a/base-tailwind.config.js b/base-tailwind.config.js
new file mode 100644
index 0000000000..2047d53595
--- /dev/null
+++ b/base-tailwind.config.js
@@ -0,0 +1,66 @@
+import {
+ scopedPreflightStyles,
+ isolateInsideOfContainer,
+} from 'tailwindcss-scoped-preflight';
+
+const rootClass = '.dokan-layout'; //We will use this class to scope the styles.
+
+/** @type {import('tailwindcss').Config} */
+const baseConfig = {
+ important: rootClass,
+ content: [ './src/**/*.{js,jsx,ts,tsx}', '!./**/*.asset.php' ],
+ theme: {
+ extend: {
+ backgroundColor: {
+ dokan: {
+ sidebar: {
+ DEFAULT:
+ 'var(--dokan-sidebar-background-color, #F05025)',
+ hover: 'var(--dokan-sidebar-hover-background-color, #F05025)',
+ },
+ btn: {
+ DEFAULT:
+ 'var(--dokan-button-background-color, #F05025)',
+ hover: 'var(--dokan-button-hover-background-color, #F05025)',
+ },
+ },
+ },
+ textColor: {
+ dokan: {
+ sidebar: {
+ DEFAULT: 'var(--dokan-sidebar-text-color, #CFCFCF)',
+ hover: 'var(--dokan-sidebar-hover-text-color, #ffffff)',
+ },
+ btn: {
+ DEFAULT: 'var(--dokan-button-text-color, #ffffff)',
+ hover: 'var(--dokan-button-hover-text-color, #ffffff)',
+ },
+ },
+ },
+ borderColor: {
+ dokan: {
+ btn: {
+ DEFAULT: 'var(--dokan-button-border-color, #F05025)',
+ hover: 'var(--dokan-button-hover-border-color, #F05025)',
+ },
+ },
+ },
+ colors: {
+ primary: 'var(--dokan-button-background-color, #F05025)',
+ dokan: {
+ sidebar: 'var(--dokan-button-background-color, #1B233B)',
+ btn: 'var(--dokan-button-background-color, #F05025)',
+ },
+ },
+ },
+ },
+ plugins: [
+ scopedPreflightStyles( {
+ isolationStrategy: isolateInsideOfContainer( rootClass, {} ),
+ } ),
+ require( '@tailwindcss/typography' ),
+ require( '@tailwindcss/forms' ),
+ ],
+};
+
+module.exports = baseConfig;
diff --git a/includes/Assets.php b/includes/Assets.php
index 7f79cca66f..f87825b08a 100644
--- a/includes/Assets.php
+++ b/includes/Assets.php
@@ -2,6 +2,7 @@
namespace WeDevs\Dokan;
+use Automattic\WooCommerce\Internal\Admin\WCAdminAssets;
use WeDevs\Dokan\Admin\Notices\Helper;
use WeDevs\Dokan\ReverseWithdrawal\SettingsHelper;
use WeDevs\Dokan\ProductCategory\Helper as CategoryHelper;
@@ -360,6 +361,10 @@ public function get_styles() {
'src' => DOKAN_PLUGIN_ASSEST . '/css/dokan-tailwind.css',
'version' => filemtime( DOKAN_DIR . '/assets/css/dokan-tailwind.css' ),
],
+ 'dokan-react-frontend' => [
+ 'src' => DOKAN_PLUGIN_ASSEST . '/css/frontend.css',
+ 'version' => filemtime( DOKAN_DIR . '/assets/css/frontend.css' ),
+ ],
];
return $styles;
@@ -373,6 +378,7 @@ public function get_styles() {
public function get_scripts() {
global $wp_version;
+ $frontend_shipping_asset = require DOKAN_DIR . '/assets/js/frontend.asset.php';
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
$asset_url = DOKAN_PLUGIN_ASSEST;
$asset_path = DOKAN_DIR . '/assets/';
@@ -567,6 +573,11 @@ public function get_scripts() {
'deps' => [ 'jquery' ],
'version' => filemtime( $asset_path . 'js/dokan-frontend.js' ),
],
+ 'dokan-react-frontend' => [
+ 'src' => $asset_url . '/js/frontend.js',
+ 'deps' => $frontend_shipping_asset['dependencies'],
+ 'version' => $frontend_shipping_asset['version'],
+ ],
];
return $scripts;
@@ -873,6 +884,11 @@ public function dokan_dashboard_scripts() {
self::load_form_validate_script();
$this->load_gmap_script();
+ $wc_instance = WCAdminAssets::get_instance();
+ $wc_instance->register_scripts();
+
+ wp_enqueue_script( 'dokan-react-frontend' );
+ wp_enqueue_style( 'dokan-react-frontend' );
wp_enqueue_script( 'jquery' );
wp_enqueue_script( 'jquery-ui' );
wp_enqueue_script( 'jquery-ui-autocomplete' );
diff --git a/includes/REST/CustomersController.php b/includes/REST/CustomersController.php
new file mode 100644
index 0000000000..af72481175
--- /dev/null
+++ b/includes/REST/CustomersController.php
@@ -0,0 +1,363 @@
+namespace, '/' . $this->rest_base . '/search', array(
+ array(
+ 'methods' => WP_REST_Server::READABLE,
+ 'callback' => array( $this, 'search_customers' ),
+ 'permission_callback' => array( $this, 'search_customers_permissions_check' ),
+ 'args' => array(
+ 'search' => array(
+ 'description' => __( 'Search string.', 'dokan-lite' ),
+ 'type' => 'string',
+ 'required' => true,
+ ),
+ 'exclude' => array(
+ 'description' => __( 'Comma-separated list of customer IDs to exclude.', 'dokan-lite' ),
+ 'type' => 'string',
+ ),
+ ),
+ ),
+ )
+ );
+ }
+
+ /**
+ * Check if a given request has access to perform an action.
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ * @param string $action The action to check (view, create, edit, delete).
+ *
+ * @return WP_Error|boolean
+ */
+ protected function check_permission( $request, $action ) {
+ if ( ! $this->check_vendor_permission() ) {
+ $messages = [
+ 'view' => __( 'Sorry, you cannot list resources.', 'dokan-lite' ),
+ 'create' => __( 'Sorry, you are not allowed to create resources.', 'dokan-lite' ),
+ 'edit' => __( 'Sorry, you are not allowed to edit this resource.', 'dokan-lite' ),
+ 'delete' => __( 'Sorry, you are not allowed to delete this resource.', 'dokan-lite' ),
+ 'batch' => __( 'Sorry, you are not allowed to batch update resources.', 'dokan-lite' ),
+ 'search' => __( 'Sorry, you are not allowed to search customers.', 'dokan-lite' ),
+ ];
+ return new WP_Error( "dokan_rest_cannot_$action", $messages[ $action ], [ 'status' => rest_authorization_required_code() ] );
+ }
+ return true;
+ }
+
+ /**
+ * Check if the current user has vendor permissions.
+ *
+ * @return bool
+ */
+ public function check_vendor_permission(): bool {
+ return dokan_is_user_seller( dokan_get_current_user_id() );
+ }
+
+ /**
+ * Get all customers.
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ * @return WP_Error|WP_REST_Response
+ */
+ public function get_items( $request ) {
+ return $this->perform_vendor_action(
+ function () use ( $request ) {
+ return parent::get_items( $request );
+ }
+ );
+ }
+
+ /**
+ * Get a single customer.
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ * @return WP_Error|WP_REST_Response
+ */
+ public function get_item( $request ) {
+ return $this->perform_vendor_action(
+ function () use ( $request ) {
+ return parent::get_item( $request );
+ }
+ );
+ }
+
+ /**
+ * Create a customer.
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ * @return WP_Error|WP_REST_Response
+ */
+ public function create_item( $request ) {
+ return $this->perform_vendor_action(
+ function () use ( $request ) {
+ return parent::create_item( $request );
+ }
+ );
+ }
+
+ /**
+ * Update a customer.
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ * @return WP_Error|WP_REST_Response
+ */
+ public function update_item( $request ) {
+ return $this->perform_vendor_action(
+ function () use ( $request ) {
+ return parent::update_item( $request );
+ }
+ );
+ }
+
+ /**
+ * Delete a customer.
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ * @return WP_Error|WP_REST_Response
+ */
+ public function delete_item( $request ) {
+ return $this->perform_vendor_action(
+ function () use ( $request ) {
+ return parent::delete_item( $request );
+ }
+ );
+ }
+
+ public function batch_items( $request ) {
+ return $this->perform_vendor_action(
+ function () use ( $request ) {
+ return parent::batch_items( $request );
+ }
+ );
+ }
+
+ /**
+ * Search customers for the current vendor.
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ *
+ * @return WP_Error|WP_REST_Response
+ * @throws \Exception
+ */
+ public function search_customers( $request ) {
+ if ( ! current_user_can( 'edit_shop_orders' ) ) {
+ return new WP_Error( 'dokan_rest_cannot_search', __( 'You do not have permission to search customers.', 'dokan-lite' ), [ 'status' => rest_authorization_required_code() ] );
+ }
+
+ $term = $request->get_param( 'search' );
+ $exclude = $request->get_param( 'exclude' ) ? explode( ',', $request->get_param( 'exclude' ) ) : [];
+ $limit = '';
+
+ if ( empty( $term ) ) {
+ return new WP_Error( 'dokan_rest_empty_search', __( 'Search term is required.', 'dokan-lite' ), [ 'status' => 400 ] );
+ }
+
+ $ids = [];
+ // Search by ID.
+ if ( is_numeric( $term ) ) {
+ $customer = new WC_Customer( intval( $term ) );
+
+ // Customer exists.
+ if ( 0 !== $customer->get_id() ) {
+ $ids = [ $customer->get_id() ];
+ }
+ }
+
+ // Usernames can be numeric so we first check that no users was found by ID before searching for numeric username, this prevents performance issues with ID lookups.
+ if ( empty( $ids ) ) {
+ $data_store = WC_Data_Store::load( 'customer' );
+
+ // If search is smaller than 3 characters, limit result set to avoid
+ // too many rows being returned.
+ if ( 3 > strlen( $term ) ) {
+ $limit = 20;
+ }
+ $ids = $data_store->search_customers( $term, $limit );
+ }
+
+ $found_customers = [];
+
+ $ids = array_diff( $ids, $exclude );
+
+ foreach ( $ids as $id ) {
+ if ( ! dokan_customer_has_order_from_this_seller( $id ) ) {
+ continue;
+ }
+
+ $customer = new WC_Customer( $id );
+ $found_customers[ $id ] = [
+ 'id' => $id,
+ 'name' => sprintf(
+ '%s',
+ $customer->get_first_name() . ' ' . $customer->get_last_name()
+ ),
+ 'email' => $customer->get_email(),
+ ];
+ }
+
+ /**
+ * Filter the found customers for Dokan REST API search.
+ *
+ * This filter allows you to modify the list of customers found during a search
+ * before it is returned by the REST API.
+ *
+ * @since DOKAN_SINCE
+ *
+ * @param array $found_customers An array of found customers. Each customer is an array containing:
+ * 'id' => (int) The customer's ID.
+ * 'name' => (string) The customer's full name.
+ * 'email' => (string) The customer's email address.
+ * @param string $term The search term used to find customers.
+ * @param array $exclude An array of customer IDs to exclude from the search results.
+ * @param int $limit The maximum number of results to return (if any).
+ *
+ * @return array The filtered array of found customers.
+ */
+ $found_customers = apply_filters( 'dokan_json_search_found_customers', $found_customers, $term, $exclude, $limit );
+
+ return rest_ensure_response( array_values( $found_customers ) );
+ }
+
+ /**
+ * Prepare a single customer for create or update.
+ *
+ * @param WP_REST_Request $request Request object.
+ * @param bool $creating If is creating a new object.
+ *
+ * @return WP_Error|WC_Data
+ */
+ protected function prepare_object_for_database( $request, $creating = false ) {
+ $customer = parent::prepare_object_for_database( $request, $creating );
+
+ if ( is_wp_error( $customer ) ) {
+ return $customer;
+ }
+
+ if ( ! $customer instanceof WC_Customer ) {
+ return new WP_Error( 'dokan_rest_invalid_customer', __( 'Invalid customer.', 'dokan-lite' ), [ 'status' => 400 ] );
+ }
+
+ // Add any Dokan-specific customer preparation here
+
+ return apply_filters( "dokan_rest_pre_insert_{$this->post_type}_object", $customer, $request, $creating );
+ }
+
+ /**
+ * Perform an action with vendor permission check.
+ *
+ * @param callable $action The action to perform.
+ *
+ * @return mixed The result of the action.
+ */
+ private function perform_vendor_action( callable $action ) {
+ add_filter( 'woocommerce_rest_check_permissions', [ $this, 'check_vendor_permission' ] );
+ $result = $action();
+ remove_filter( 'woocommerce_rest_check_permissions', [ $this, 'check_vendor_permission' ] );
+ return $result;
+ }
+
+ /**
+ * Check if a given request has access to get items.
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ *
+ * @return WP_Error|boolean
+ */
+ public function get_items_permissions_check( $request ) {
+ return $this->check_permission( $request, 'view' );
+ }
+
+ /**
+ * Check if a given request has access to get a specific item.
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ *
+ * @return WP_Error|boolean
+ */
+ public function get_item_permissions_check( $request ) {
+ return $this->check_permission( $request, 'view' );
+ }
+
+ /**
+ * Check if a given request has access to create a customer.
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ *
+ * @return WP_Error|boolean
+ */
+ public function create_item_permissions_check( $request ) {
+ return $this->check_permission( $request, 'create' );
+ }
+
+ /**
+ * Check if a given request has access to update a customer.
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ *
+ * @return WP_Error|boolean
+ */
+ public function update_item_permissions_check( $request ) {
+ return $this->check_permission( $request, 'edit' );
+ }
+
+ /**
+ * Check if a given request has access to delete a customer.
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ *
+ * @return WP_Error|boolean
+ */
+ public function delete_item_permissions_check( $request ) {
+ return $this->check_permission( $request, 'delete' );
+ }
+
+ /**
+ * Check if a given request has access to batch items.
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ *
+ * @return WP_Error|boolean
+ */
+ public function batch_items_permissions_check( $request ) {
+ return $this->check_permission( $request, 'batch' );
+ }
+
+ /**
+ * Check if a given request has access to search customers.
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ *
+ * @return WP_Error|boolean
+ */
+ public function search_customers_permissions_check( $request ) {
+ return $this->check_permission( $request, 'search' );
+ }
+}
diff --git a/includes/REST/DokanDataContinentsController.php b/includes/REST/DokanDataContinentsController.php
new file mode 100644
index 0000000000..783396ae59
--- /dev/null
+++ b/includes/REST/DokanDataContinentsController.php
@@ -0,0 +1,123 @@
+set_woocommerce_rest_check_permissions();
+
+ return parent::get_items( $request );
+ }
+
+ /**
+ * Return the list of states for a given country.
+ *
+ * @since 3.5.0
+ * @param WP_REST_Request $request Request data.
+ * @return WP_Error|WP_REST_Response
+ */
+ public function get_item( $request ) {
+ $this->set_woocommerce_rest_check_permissions();
+ return parent::get_item( $request );
+ }
+
+ /**
+ * Check if a given request has access to read an item.
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ * @return WP_Error|boolean
+ */
+ public function get_item_permissions_check( $request ) {
+ $this->set_woocommerce_rest_check_permissions();
+ $item_permission = $this->get_items_permissions_check( $request );
+
+ if ( is_wp_error( $item_permission ) ) {
+ return $item_permission;
+ }
+
+ return parent::get_item_permissions_check( $request );
+ }
+
+ /**
+ * Check if a given request has access to read items.
+ *
+ * @since DOKAN_SINCE
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ * @return WP_Error|boolean
+ */
+ public function get_items_permissions_check( $request ) {
+ // phpcs:ignore WordPress.WP.Capabilities.Unknown
+ if ( current_user_can( dokan_admin_menu_capability() ) || current_user_can( 'dokandar' ) ) {
+ return true;
+ }
+
+ return new WP_Error(
+ 'dokan_pro_permission_failure',
+ __( 'You are not allowed to do this action.', 'dokan-lite' ),
+ [
+ 'status' => rest_authorization_required_code(),
+ ]
+ );
+ }
+
+ private function set_woocommerce_rest_check_permissions() {
+ add_filter( 'woocommerce_rest_check_permissions', [ $this, 'add_subscriptions_read_permission_to_vendors' ], 10, 4 );
+ }
+
+ /**
+ * Add permissions.
+ *
+ * @since DOKAN_PRO_SINCE
+ *
+ * @param $permission
+ * @param $context
+ * @param $object_id
+ * @param $obj
+ *
+ * @return true
+ */
+ public function add_subscriptions_read_permission_to_vendors( $permission, $context, $object_id, $obj ) {
+ if ( 'read' === $context ) {
+ return true;
+ }
+
+ return $permission;
+ }
+}
diff --git a/includes/REST/DokanDataCountriesController.php b/includes/REST/DokanDataCountriesController.php
new file mode 100644
index 0000000000..908f00311d
--- /dev/null
+++ b/includes/REST/DokanDataCountriesController.php
@@ -0,0 +1,123 @@
+set_woocommerce_rest_check_permissions();
+
+ return parent::get_items( $request );
+ }
+
+ /**
+ * Return the list of states for a given country.
+ *
+ * @since 3.5.0
+ * @param WP_REST_Request $request Request data.
+ * @return WP_Error|WP_REST_Response
+ */
+ public function get_item( $request ) {
+ $this->set_woocommerce_rest_check_permissions();
+ return parent::get_item( $request );
+ }
+
+ /**
+ * Check if a given request has access to read an item.
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ * @return WP_Error|boolean
+ */
+ public function get_item_permissions_check( $request ) {
+ $this->set_woocommerce_rest_check_permissions();
+ $item_permission = $this->get_items_permissions_check( $request );
+
+ if ( is_wp_error( $item_permission ) ) {
+ return $item_permission;
+ }
+
+ return parent::get_item_permissions_check( $request );
+ }
+
+ /**
+ * Check if a given request has access to read items.
+ *
+ * @since DOKAN_SINCE
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ * @return WP_Error|boolean
+ */
+ public function get_items_permissions_check( $request ) {
+ // phpcs:ignore WordPress.WP.Capabilities.Unknown
+ if ( current_user_can( dokan_admin_menu_capability() ) || current_user_can( 'dokandar' ) ) {
+ return true;
+ }
+
+ return new WP_Error(
+ 'dokan_pro_permission_failure',
+ __( 'You are not allowed to do this action.', 'dokan-lite' ),
+ [
+ 'status' => rest_authorization_required_code(),
+ ]
+ );
+ }
+
+ private function set_woocommerce_rest_check_permissions() {
+ add_filter( 'woocommerce_rest_check_permissions', [ $this, 'add_subscriptions_read_permission_to_vendors' ], 10, 4 );
+ }
+
+ /**
+ * Add permissions.
+ *
+ * @since DOKAN_PRO_SINCE
+ *
+ * @param $permission
+ * @param $context
+ * @param $object_id
+ * @param $obj
+ *
+ * @return true
+ */
+ public function add_subscriptions_read_permission_to_vendors( $permission, $context, $object_id, $obj ) {
+ if ( 'read' === $context ) {
+ return true;
+ }
+
+ return $permission;
+ }
+}
diff --git a/includes/REST/Manager.php b/includes/REST/Manager.php
index 10d0a5970d..6f861f4dab 100644
--- a/includes/REST/Manager.php
+++ b/includes/REST/Manager.php
@@ -201,6 +201,10 @@ private function get_rest_api_class_map() {
DOKAN_DIR . '/includes/REST/VendorDashboardController.php' => '\WeDevs\Dokan\REST\VendorDashboardController',
DOKAN_DIR . '/includes/REST/ProductBlockController.php' => '\WeDevs\Dokan\REST\ProductBlockController',
DOKAN_DIR . '/includes/REST/CommissionControllerV1.php' => '\WeDevs\Dokan\REST\CommissionControllerV1',
+ DOKAN_DIR . '/includes/REST/CustomersController.php' => '\WeDevs\Dokan\REST\CustomersController',
+ DOKAN_DIR . '/includes/REST/DokanDataCountriesController.php' => '\WeDevs\Dokan\REST\DokanDataCountriesController',
+ DOKAN_DIR . '/includes/REST/DokanDataContinentsController.php' => '\WeDevs\Dokan\REST\DokanDataContinentsController',
+ DOKAN_DIR . '/includes/REST/OrderControllerV3.php' => '\WeDevs\Dokan\REST\OrderControllerV3',
)
);
}
diff --git a/includes/REST/OrderControllerV3.php b/includes/REST/OrderControllerV3.php
new file mode 100644
index 0000000000..74167afca9
--- /dev/null
+++ b/includes/REST/OrderControllerV3.php
@@ -0,0 +1,63 @@
+get_data();
+ $downloads = $data['downloads'];
+ $updated_response = [];
+
+ foreach ( $downloads as $download ) {
+ $product = dokan()->product->get( $download->product_id );
+ $download->product = [
+ 'id' => $product->get_id(),
+ 'name' => $product->get_name(),
+ 'slug' => $product->get_slug(),
+ 'link' => $product->get_permalink(),
+ ];
+
+ /**
+ * @var $file \WC_Product_Download
+ */
+ $file = $product->get_file( $download->download_id );
+ $download->file_data = $file->get_data();
+ $download->file_data['file_title'] = wc_get_filename_from_url( $product->get_file_download_path( $download->download_id ) );
+
+ $updated_response[] = $download;
+ }
+
+ return rest_ensure_response( $updated_response );
+ }
+}
diff --git a/includes/REST/ProductController.php b/includes/REST/ProductController.php
index ee78d383e0..d0f1f970f1 100644
--- a/includes/REST/ProductController.php
+++ b/includes/REST/ProductController.php
@@ -54,6 +54,58 @@ class ProductController extends DokanRESTController {
*/
protected $post_status = [ 'publish', 'pending', 'draft' ];
+ /**
+ * Class constructor.
+ *
+ * @since DOKAN_SINCE
+ */
+ public function __construct() {
+ add_filter( "dokan_rest_{$this->post_type}_object_query", [ $this, 'add_only_downloadable_query' ], 10, 2 );
+ }
+
+ /**
+ * Add only downloadable meta query.
+ *
+ * @since DOKAN_SINCE
+ *
+ * @param array $args
+ *
+ * @param \WP_REST_Request $request
+ */
+ public function add_only_downloadable_query( $args, $request ) {
+ if ( true === dokan_string_to_bool( $request->get_param( 'only_downloadable' ) ) ) {
+ $args['meta_query'][] = [
+ 'key' => '_downloadable',
+ 'value' => 'yes',
+ 'compare' => '=',
+ ];
+ }
+
+ return $args;
+ }
+
+ /**
+ * Product API query parameters collections.
+ *
+ * @since DOKAN_SINCE
+ *
+ * @return array Query parameters.
+ */
+ public function get_product_collection_params() {
+ $schema = parent::get_product_collection_params();
+
+ $schema['only_downloadable'] = [
+ 'description' => __( 'If truthy value then only downloadable products will be returned', 'dokan' ),
+ 'type' => [ 'boolean', 'string' ],
+ 'enum' => [ true, false, 0, 1 ],
+ 'sanitize_callback' => 'dokan_string_to_bool',
+ 'validate_callback' => 'dokan_string_to_bool',
+ 'default' => false,
+ ];
+
+ return $schema;
+ }
+
/**
* Register all routes related with stores
*
diff --git a/package.json b/package.json
index a98b03c555..7e6828effa 100644
--- a/package.json
+++ b/package.json
@@ -22,6 +22,8 @@
"release:dev": "npm install && npm run build && npm run clean-files && npm run makepot && npm run zip"
},
"devDependencies": {
+ "@tailwindcss/forms": "^0.5.9",
+ "@tailwindcss/typography": "^0.5.15",
"@wordpress/scripts": "^27.9.0",
"chartjs-adapter-moment": "^1.0.1",
"debounce": "^1.2.1",
@@ -34,6 +36,7 @@
"papaparse": "^5.4.1",
"replace-in-file": "^6.3.5",
"tailwindcss": "^3.3.3",
+ "tailwindcss-scoped-preflight": "^3.4.5",
"vue": "^2.7.14",
"vue-chartjs": "^3.5.1",
"vue-color": "^2.8.1",
@@ -50,6 +53,14 @@
"wp-readme-to-markdown": "^1.0.1"
},
"dependencies": {
- "@wordpress/i18n": "^5.8.0"
+ "@getdokan/dokan-ui": "^1.0.14",
+ "@wordpress/components": "^28.9.0",
+ "@wordpress/data": "^10.9.0",
+ "@wordpress/dom-ready": "^4.9.0",
+ "@wordpress/element": "^6.9.0",
+ "@wordpress/hooks": "^4.9.0",
+ "@wordpress/i18n": "^5.8.0",
+ "@wordpress/plugins": "^7.10.0",
+ "react-router-dom": "^6.27.0"
}
}
diff --git a/src/Dashboard/index.tsx b/src/Dashboard/index.tsx
new file mode 100644
index 0000000000..4bf0eadc89
--- /dev/null
+++ b/src/Dashboard/index.tsx
@@ -0,0 +1,41 @@
+import {createRoot} from "@wordpress/element";
+import domReady from "@wordpress/dom-ready";
+import Layout from "../Layout";
+import getRoutes, { withRouter } from "../Routing";
+import {
+ createHashRouter,
+ RouterProvider,
+} from "react-router-dom";
+import './tailwind.scss';
+
+const App = () => {
+ const routes = getRoutes();
+
+ const mapedRoutes = routes.map((route) => {
+ const WithRouterComponent = withRouter( route.element );
+
+ return {
+ path: route.path,
+ element: