From 2efd5ef950c91402336732b232b4252d4ed5c9d3 Mon Sep 17 00:00:00 2001 From: Shazahanul Islam Shohag Date: Tue, 14 Jan 2025 10:25:21 +0600 Subject: [PATCH] feat: dokan status page (#2500) * update: Status elements and status page added * update: Status elements dynamically render * update: Vendor Dashboard nave menu Status elements added * refactor: exception added in set_children * refactor: translation and custom element support added. * refactor: removed unnecessary status element in page --- base-tailwind.config.js | 2 +- includes/Abstracts/StatusElement.php | 269 ++++++++++++++++++ includes/Admin/Status/Button.php | 100 +++++++ includes/Admin/Status/Heading.php | 22 ++ includes/Admin/Status/Link.php | 68 +++++ includes/Admin/Status/Page.php | 24 ++ includes/Admin/Status/Paragraph.php | 32 +++ includes/Admin/Status/Section.php | 23 ++ includes/Admin/Status/Status.php | 227 +++++++++++++++ includes/Admin/Status/SubSection.php | 23 ++ includes/Admin/Status/Tab.php | 23 ++ includes/Admin/Status/Table.php | 48 ++++ includes/Admin/Status/TableColumn.php | 23 ++ includes/Admin/Status/TableRow.php | 23 ++ .../Providers/AdminServiceProvider.php | 5 + includes/REST/AdminDashboardController.php | 21 ++ includes/VendorNavMenuChecker.php | 60 ++++ package.json | 2 + src/Status/Elements/Button.tsx | 37 +++ src/Status/Elements/Heading.tsx | 27 ++ src/Status/Elements/Link.tsx | 15 + src/Status/Elements/Paragraph.tsx | 7 + src/Status/Elements/Section.tsx | 32 +++ src/Status/Elements/SubSection.tsx | 32 +++ src/Status/Elements/Table.tsx | 48 ++++ src/Status/Elements/TableColumn.tsx | 18 ++ src/Status/Elements/TableRow.tsx | 18 ++ src/Status/Menu.tsx | 50 ++++ src/Status/SettingsParser.tsx | 43 +++ src/Status/Status.tsx | 175 ++++++++++++ src/Status/Tab.tsx | 80 ++++++ src/Status/index.tsx | 13 + src/Status/status-tailwind.config.js | 9 + src/Status/status.scss | 3 + webpack.config.js | 1 + 35 files changed, 1602 insertions(+), 1 deletion(-) create mode 100644 includes/Abstracts/StatusElement.php create mode 100644 includes/Admin/Status/Button.php create mode 100644 includes/Admin/Status/Heading.php create mode 100644 includes/Admin/Status/Link.php create mode 100644 includes/Admin/Status/Page.php create mode 100644 includes/Admin/Status/Paragraph.php create mode 100644 includes/Admin/Status/Section.php create mode 100644 includes/Admin/Status/Status.php create mode 100644 includes/Admin/Status/SubSection.php create mode 100644 includes/Admin/Status/Tab.php create mode 100644 includes/Admin/Status/Table.php create mode 100644 includes/Admin/Status/TableColumn.php create mode 100644 includes/Admin/Status/TableRow.php create mode 100644 src/Status/Elements/Button.tsx create mode 100644 src/Status/Elements/Heading.tsx create mode 100644 src/Status/Elements/Link.tsx create mode 100644 src/Status/Elements/Paragraph.tsx create mode 100644 src/Status/Elements/Section.tsx create mode 100644 src/Status/Elements/SubSection.tsx create mode 100644 src/Status/Elements/Table.tsx create mode 100644 src/Status/Elements/TableColumn.tsx create mode 100644 src/Status/Elements/TableRow.tsx create mode 100644 src/Status/Menu.tsx create mode 100644 src/Status/SettingsParser.tsx create mode 100644 src/Status/Status.tsx create mode 100644 src/Status/Tab.tsx create mode 100644 src/Status/index.tsx create mode 100644 src/Status/status-tailwind.config.js create mode 100644 src/Status/status.scss diff --git a/base-tailwind.config.js b/base-tailwind.config.js index 4720824467..8d9fd4c1ad 100644 --- a/base-tailwind.config.js +++ b/base-tailwind.config.js @@ -93,4 +93,4 @@ const baseConfig = { ], }; -module.exports = baseConfig; +export default baseConfig; diff --git a/includes/Abstracts/StatusElement.php b/includes/Abstracts/StatusElement.php new file mode 100644 index 0000000000..96393ab376 --- /dev/null +++ b/includes/Abstracts/StatusElement.php @@ -0,0 +1,269 @@ +id = $id; + } + + /** + * @return bool + */ + public function is_support_children(): bool { + return $this->support_children; + } + + /** + * @param bool $support_children + * + * @return StatusElement + */ + public function set_support_children( bool $support_children ): StatusElement { + $this->support_children = $support_children; + + return $this; + } + + /** + * @return string + */ + public function get_id(): string { + return $this->id; + } + + /** + * @param string $id + * + * @return StatusElement + */ + public function set_id( string $id ): StatusElement { + $this->id = $id; + + return $this; + } + + /** + * @return string + */ + public function get_hook_key(): string { + return $this->hook_key; + } + + /** + * @param string $hook_key + * + * @return StatusElement + */ + public function set_hook_key( string $hook_key ): StatusElement { + $this->hook_key = $hook_key; + + return $this; + } + + /** + * @return string + */ + public function get_title(): string { + return $this->title; + } + + /** + * @param string $title + * + * @return StatusElement + */ + public function set_title( string $title ): StatusElement { + $this->title = $title; + + return $this; + } + + /** + * @return string + */ + public function get_description(): string { + return $this->description; + } + + /** + * @param string $description + * + * @return StatusElement + */ + public function set_description( string $description ): StatusElement { + $this->description = $description; + + return $this; + } + + /** + * @return string + */ + public function get_icon(): string { + return $this->icon; + } + + /** + * @param string $icon + * + * @return StatusElement + */ + public function set_icon( string $icon ): StatusElement { + $this->icon = $icon; + + return $this; + } + + /** + * @return array + */ + public function get_children(): array { + $children = array(); + $filtered_children = apply_filters( $this->get_hook_key() . '_children', $this->children, $this ); // phpcs:ignore. + + foreach ( $filtered_children as $child ) { + $child->set_hook_key( $this->get_hook_key() . '_' . $child->get_id() ); + $children[ $child->get_id() ] = $child; + } + + return $children; + } + + /** + * Set children. + * + * @since DOKAN_SINCE + * + * @param array $children + * + * @return StatusElement + * @throws Exception + */ + public function set_children( array $children ): StatusElement { + if ( ! $this->is_support_children() ) { + throw new Exception( esc_html__( 'This element does not support child element.', 'dokan-lite' ) ); + } + $this->children = $children; + + return $this; + } + + /** + * @return string + */ + public function get_type(): string { + return $this->type; + } + + /** + * @param string $type + * + * @return StatusElement + */ + public function set_type( string $type ): StatusElement { + $this->type = $type; + + return $this; + } + + /** + * @return string + */ + public function get_data(): string { + return $this->data; + } + + /** + * @param string $data + * + * @return StatusElement + */ + public function set_data( string $data ): StatusElement { + $this->data = $data; + + return $this; + } + + /** + * @throws Exception + */ + public function add( StatusElement $child ): StatusElement { + if ( ! $this->is_support_children() ) { + throw new Exception( esc_html__( 'This element does not support child element.', 'dokan-lite' ) ); + } + $this->children[] = $child; + + return $this; + } + + /** + * @throws Exception + */ + public function remove( StatusElement $element ): StatusElement { + if ( ! $this->is_support_children() ) { + // translators: %s is Status element type. + throw new Exception( esc_html( sprintf( esc_html__( 'Status %s Does not support adding any children.', 'dokan-lite' ), $this->get_type() ) ) ); + } + + $children = array_filter( + $this->get_children(), + function ( $child ) use ( $element ) { + return $child !== $element; + } + ); + $this->set_children( $children ); + + return $this; + } + + + /** + * @return array + */ + public function render(): array { + $children = array(); + if ( $this->is_support_children() ) { + foreach ( $this->get_children() as $child ) { + $children[] = $child->render(); + } + } + + $data = [ + 'id' => $this->get_id(), + 'title' => $this->get_title(), + 'description' => $this->get_description(), + 'icon' => $this->get_icon(), + 'type' => $this->get_type(), + 'data' => $this->escape_data( $this->get_data() ), + 'hook_key' => $this->get_hook_key(), + 'children' => $children, + ]; + + return apply_filters( 'dokan_status_element_render_' . $this->get_hook_key(), $data, $this ); + } + + /** + * @param string $data + * + * @return string + */ + abstract public function escape_data( string $data ): string; +} diff --git a/includes/Admin/Status/Button.php b/includes/Admin/Status/Button.php new file mode 100644 index 0000000000..ae26023f3c --- /dev/null +++ b/includes/Admin/Status/Button.php @@ -0,0 +1,100 @@ +request; + } + + /** + * @param string $request + * + * @return Button + */ + public function set_request( string $request ): Button { + $this->request = $request; + + return $this; + } + + /** + * @return string + */ + public function get_endpoint(): string { + return $this->endpoint; + } + + /** + * @param string $endpoint + * + * @return Button + */ + public function set_endpoint( string $endpoint ): Button { + $this->endpoint = $endpoint; + + return $this; + } + + /** + * @return array + */ + public function get_payload(): array { + return $this->payload; + } + + /** + * @param array $payload + * + * @return Button + */ + public function set_payload( array $payload ): Button { + $this->payload = $payload; + + return $this; + } + + /** + * @inheritDoc + */ + public function render(): array { + $data = parent::render(); + $data['request'] = $this->get_request(); + $data['endpoint'] = trim( $this->get_endpoint(), '/' ); + $data['payload'] = $this->get_payload(); + return $data; + } + + /** + * @inheritDoc + */ + public function escape_data( string $data ): string { + return esc_html( $data ); + } +} diff --git a/includes/Admin/Status/Heading.php b/includes/Admin/Status/Heading.php new file mode 100644 index 0000000000..8bfa44092a --- /dev/null +++ b/includes/Admin/Status/Heading.php @@ -0,0 +1,22 @@ +url; + } + + /** + * @param string $url + * + * @return Link + */ + public function set_url( string $url ): Link { + $this->url = $url; + + return $this; + } + + /** + * @return string + */ + public function get_title_text(): string { + return $this->title_text; + } + + /** + * @param string $title_text + * + * @return Link + */ + public function set_title_text( string $title_text ): Link { + $this->title_text = $title_text; + + return $this; + } + + /** + * @inheritDoc + */ + public function render(): array { + $data = parent::render(); + $data['url'] = $this->get_url(); + $data['title_text'] = $this->get_title_text(); + return $data; + } + + /** + * @inheritDoc + */ + public function escape_data( string $data ): string { + return esc_html( $data ); + } +} diff --git a/includes/Admin/Status/Page.php b/includes/Admin/Status/Page.php new file mode 100644 index 0000000000..5df3e1fc73 --- /dev/null +++ b/includes/Admin/Status/Page.php @@ -0,0 +1,24 @@ + [ + 'href' => [], + 'title' => [], + ], + 'br' => [], + 'em' => [], + 'strong' => [], + 'span' => [], + 'code' => [], + ]; + return wp_kses( $data, $allowed_tags ); + } +} diff --git a/includes/Admin/Status/Section.php b/includes/Admin/Status/Section.php new file mode 100644 index 0000000000..8aa417252c --- /dev/null +++ b/includes/Admin/Status/Section.php @@ -0,0 +1,23 @@ +describe(); + } catch ( Exception $e ) { + dokan_log( $e->getMessage() ); + } + + add_action( 'dokan_admin_menu', [ $this, 'register_menu' ], 99, 2 ); + add_action( 'dokan_register_scripts', [ $this, 'register_scripts' ] ); + add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_scripts' ] ); + } + + /** + * Get a new Page object. + * + * @param string $id ID. + * + * @return Page + */ + public static function page( string $id ): Page { + return new Page( $id ); + } + + /** + * Get a new tab object. + * + * @param string $id ID. + * + * @return Tab + */ + public static function tab( string $id ): Tab { + return new Tab( $id ); + } + + /** + * Get a new Section object. + * + * @param string $id ID. + * + * @return Section + */ + public static function section( string $id ): Section { + return new Section( $id ); + } + + /** + * Get a new SubSection object. + * + * @param string $id ID. + * + * @return SubSection + */ + public static function sub_section( string $id ): SubSection { + return new SubSection( $id ); + } + + /** + * Get a new Table object. + * + * @param string $id ID. + * + * @return Table + */ + public static function table( string $id ): Table { + return new Table( $id ); + } + + public static function table_row( string $id ): TableRow { + return new TableRow( $id ); + } + + public static function table_column( string $id ): TableColumn { + return new TableColumn( $id ); + } + + public static function paragraph( string $id ): Paragraph { + return new Paragraph( $id ); + } + + public static function heading( string $id ): Heading { + return new Heading( $id ); + } + + public static function link( string $id ): Link { + return new Link( $id ); + } + + public static function button( string $id ): Button { + return new Button( $id ); + } + + /** + * @inheritDoc + */ + public function escape_data( string $data ): string { + return $data; + } + + public function render(): array { + return parent::render()['children']; + } + + + /** + * Register the submenu menu. + * + * @since DOKAN_SINCE + * + * @param string $capability Menu capability. + * @param string $position Menu position. + * + * @return void + */ + public function register_menu( string $capability, string $position ) { + add_submenu_page( + 'dokan', + __( 'Dokan Status', 'dokan-lite' ), + __( 'Status', 'dokan-lite' ), + $capability, + 'dokan-status', + [ $this, 'render_status_page' ], + 99 + ); + } + + public function register_scripts() { + $asset_file = include DOKAN_DIR . '/assets/js/dokan-status.asset.php'; + + wp_register_script( + 'dokan-status', + DOKAN_PLUGIN_ASSEST . '/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'] ); + } + + public function enqueue_scripts() { + if ( 'dokan_page_dokan-status' !== get_current_screen()->id ) { + return; + } + + wp_enqueue_script( 'dokan-status' ); + wp_enqueue_style( 'dokan-status' ); + } + + /** + * Load Status Page Template + * + * @since DOKAN_SINCE + * + * @return void + */ + public function render_status_page() { + echo '
'; + } + + /** + * Describe the settings options. + * + * @return void + * @throws Exception + */ + public function describe() { + // $this->add( + // self::heading( 'main_heading' ) + // ->set_title( __( 'Dokan Status', 'dokan-lite' ) ) + // ->set_description( __( 'Check the status of your Dokan installation.', 'dokan-lite' ) ) + // ); + + // $this->add( + // self::section( 'overridden_features' ) + // ->set_title( __( 'Overridden Templates', 'dokan-lite' ) ) + // ->set_description( __( 'The templates currently overridden that is preventing enabling new features.', 'dokan-lite' ) ) + // ->add( + // self::table( 'override_table' ) + // ->set_title( __( 'General Heading', 'dokan-lite' ) ) + // ->set_headers( + // [ + // __( 'Template', 'dokan-lite' ), + // __( 'Feature', 'dokan-lite' ), + // 'Action', + // ] + // ) + // ->add( + // self::table_row( 'override_row' ) + // ->add( + // self::table_column( 'template' ) + // ->add( + // self::paragraph( 'file' ) + // ->set_title( __( 'FileA.php', 'dokan-lite' ) ) + // ) + // ) + // ->add( + // self::table_column( 'action' ) + // ->add( + // self::button( 'action' ) + // ->set_title( __( 'Remove', 'dokan-lite' ) ) + // ) + // ) + // ) + // ) + // ); + + do_action( 'dokan_status_after_describing_elements', $this ); + } +} diff --git a/includes/Admin/Status/SubSection.php b/includes/Admin/Status/SubSection.php new file mode 100644 index 0000000000..adcc3221d0 --- /dev/null +++ b/includes/Admin/Status/SubSection.php @@ -0,0 +1,23 @@ +headers; + } + + /** + * @param array $headers + * + * @return Table + */ + public function set_headers( array $headers ): Table { + $this->headers = $headers; + + return $this; + } + + public function render(): array { + $data = parent::render(); + $data['headers'] = $this->get_headers(); + + return $data; + } + + /** + * @inheritDoc + */ + public function escape_data( string $data ): string { + // No escaping needed for table data. + return $data; + } +} diff --git a/includes/Admin/Status/TableColumn.php b/includes/Admin/Status/TableColumn.php new file mode 100644 index 0000000000..c2f1248fc0 --- /dev/null +++ b/includes/Admin/Status/TableColumn.php @@ -0,0 +1,23 @@ +getContainer() ->addShared( \WeDevs\Dokan\Admin\SetupWizard::class, \WeDevs\Dokan\Admin\SetupWizard::class ) ->addTag( self::TAG ); + $this->getContainer() + ->addShared( \WeDevs\Dokan\Admin\Status\Status::class, \WeDevs\Dokan\Admin\Status\Status::class ) + ->addTag( self::TAG ); } } diff --git a/includes/REST/AdminDashboardController.php b/includes/REST/AdminDashboardController.php index bb8c09212f..464af658b3 100644 --- a/includes/REST/AdminDashboardController.php +++ b/includes/REST/AdminDashboardController.php @@ -2,6 +2,7 @@ namespace WeDevs\Dokan\REST; +use WeDevs\Dokan\Admin\Status\Status; use WP_Error; use WP_REST_Response; use WP_REST_Server; @@ -64,6 +65,16 @@ public function register_routes() { ), ) ); + register_rest_route( + $this->namespace, '/' . $this->base . '/status', array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_status' ), + 'permission_callback' => array( $this, 'check_permission' ), + 'args' => array(), + ), + ) + ); } /** @@ -164,6 +175,16 @@ public function get_feeds( $request ) { return rest_ensure_response( $feeds ); } + public function get_status( $request ) { + /** + * @var Status $status + */ + $status = dokan_get_container()->get( Status::class ); + $content = $status->render(); + + return rest_ensure_response( $content ); + } + /** * Support SimplePie class in WP 5.5+ * diff --git a/includes/VendorNavMenuChecker.php b/includes/VendorNavMenuChecker.php index feb21b825a..df8ae4d380 100644 --- a/includes/VendorNavMenuChecker.php +++ b/includes/VendorNavMenuChecker.php @@ -2,6 +2,9 @@ namespace WeDevs\Dokan; +use Exception; +use WeDevs\Dokan\Admin\Status\Status; + class VendorNavMenuChecker { /** @@ -19,6 +22,7 @@ class VendorNavMenuChecker { public function __construct() { add_filter( 'dokan_get_dashboard_nav', [ $this, 'convert_to_react_menu' ], 999 ); add_filter( 'dokan_admin_notices', [ $this, 'display_notice' ] ); + add_action( 'dokan_status_after_describing_elements', [ $this, 'add_status_section' ] ); } /** @@ -207,8 +211,64 @@ public function display_notice( array $notices ): array { 'type' => 'alert', 'title' => esc_html__( 'Some of Dokan Templates are overridden which limit new features.', 'dokan-lite' ), 'description' => $notice, + 'actions' => [ + [ + 'type' => 'primary', + 'text' => esc_html__( 'Learn More', 'dokan-lite' ), + 'action' => admin_url( 'admin.php?page=dokan-status' ), + 'target' => '_blank', + ], + ], ]; return $notices; } + + /** + * Add template dependencies to status page. + * + * @since DOKAN_SINCE + * + * @return void + * @throws Exception + */ + public function add_status_section( Status $status ) { + if ( empty( $this->list_overridden_templates() ) ) { + return; + } + + $table = Status::table( 'override_table' ) + ->set_title( __( 'General Heading', 'dokan-lite' ) ) + ->set_headers( + [ + __( 'Template', 'dokan-lite' ), + ] + ); + + foreach ( $this->list_overridden_templates() as $id => $template ) { + $table->add( + Status::table_row( 'override_row_' . $id ) + ->add( + Status::table_column( 'template_' . $id ) + ->add( + Status::paragraph( 'file_location_' . $id ) + ->set_title( $template ) + ) + ->add( + Status::paragraph( 'file_location_' . $id . '_instruction' ) + ->set_title( __( 'Please Remove the above file to enable ', 'dokan-lite' ) ) + ) + ) + ); + } + + $status->add( + Status::section( 'overridden_features' ) + ->set_title( __( 'Overridden Templates', 'dokan-lite' ) ) + ->set_description( __( 'The templates currently overridden that is preventing enabling new features.', 'dokan-lite' ) ) + ->add( + $table + ) + ); + } } diff --git a/package.json b/package.json index 55af203e1d..3b6f119882 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ }, "dependencies": { "@getdokan/dokan-ui": "^1.0.14", + "@wordpress/api-fetch": "^7.14.0", "@wordpress/components": "^28.9.0", "@wordpress/data": "^10.9.0", "@wordpress/dom-ready": "^4.9.0", @@ -61,6 +62,7 @@ "@wordpress/hooks": "^4.9.0", "@wordpress/i18n": "^5.8.0", "@wordpress/plugins": "^7.10.0", + "@wordpress/url": "^4.15.0", "react-router-dom": "^6.27.0" } } diff --git a/src/Status/Elements/Button.tsx b/src/Status/Elements/Button.tsx new file mode 100644 index 0000000000..ca5acbcfee --- /dev/null +++ b/src/Status/Elements/Button.tsx @@ -0,0 +1,37 @@ +import { StatusElement } from '../Status'; +import { useState } from '@wordpress/element'; +import apiFetch from '@wordpress/api-fetch'; +import { addQueryArgs } from '@wordpress/url'; + +const Button = ( { element }: { element: StatusElement } ) => { + const [ isClicked, setIsClicked ] = useState( false ); + const onClick = () => { + setIsClicked( true ); + + const path = + 'GET' === element.request + ? addQueryArgs( element.endpoint, element.payload ) + : element.endpoint; + + const args = { + path: element.endpoint, + method: element.request, + data: 'GET' !== element.request ? element.payload : {}, + }; + + apiFetch( args ).then( ( response ) => { + setIsClicked( false ); + } ); + }; + return ( + + ); +}; +export default Button; diff --git a/src/Status/Elements/Heading.tsx b/src/Status/Elements/Heading.tsx new file mode 100644 index 0000000000..10bd524ac4 --- /dev/null +++ b/src/Status/Elements/Heading.tsx @@ -0,0 +1,27 @@ +import { StatusElement } from '../Status'; +import SettingsParser from '../SettingsParser'; + +const Heading = ( { element }: { element: StatusElement } ) => { + return ( +
+
+

+ { element.title } +

+
+
+ { element.children.map( ( child ) => { + return ( + + ); + } ) } +
+
+ ); +}; +export default Heading; diff --git a/src/Status/Elements/Link.tsx b/src/Status/Elements/Link.tsx new file mode 100644 index 0000000000..a42b3f8a70 --- /dev/null +++ b/src/Status/Elements/Link.tsx @@ -0,0 +1,15 @@ +import { StatusElement } from '../Status'; +import SettingsParser from '../SettingsParser'; + +const Link = ( { element }: { element: StatusElement } ) => { + return ( + + { element.title } + + ); +}; +export default Link; diff --git a/src/Status/Elements/Paragraph.tsx b/src/Status/Elements/Paragraph.tsx new file mode 100644 index 0000000000..70c520bc3f --- /dev/null +++ b/src/Status/Elements/Paragraph.tsx @@ -0,0 +1,7 @@ +import { StatusElement } from '../Status'; +import SettingsParser from '../SettingsParser'; + +const Paragraph = ( { element }: { element: StatusElement } ) => { + return

{ element.title }

; +}; +export default Paragraph; diff --git a/src/Status/Elements/Section.tsx b/src/Status/Elements/Section.tsx new file mode 100644 index 0000000000..c6ae27de00 --- /dev/null +++ b/src/Status/Elements/Section.tsx @@ -0,0 +1,32 @@ +import { StatusElement } from '../Status'; +import SettingsParser from '../SettingsParser'; + +const Section = ( { element }: { element: StatusElement } ) => { + return ( +
+
+

+ { element.title } +

+ { element.description && ( +

+ { element.description } +

+ ) } +
+
+ { element.children.map( ( child ) => { + return ( + + ); + } ) } +
+
+ ); +}; +export default Section; diff --git a/src/Status/Elements/SubSection.tsx b/src/Status/Elements/SubSection.tsx new file mode 100644 index 0000000000..e414962a3c --- /dev/null +++ b/src/Status/Elements/SubSection.tsx @@ -0,0 +1,32 @@ +import { StatusElement } from '../Status'; +import SettingsParser from '../SettingsParser'; + +const SubSection = ( { element }: { element: StatusElement } ) => { + return ( + <> +
+

+ { element.title } +

+ { element.description && ( +

+ { element.description } +

+ ) } +
+
+ { element.children.map( ( child ) => { + return ( + + ); + } ) } +
+ + ); +}; +export default SubSection; diff --git a/src/Status/Elements/Table.tsx b/src/Status/Elements/Table.tsx new file mode 100644 index 0000000000..a592bdc7b8 --- /dev/null +++ b/src/Status/Elements/Table.tsx @@ -0,0 +1,48 @@ +import { StatusElement } from '../Status'; +import SettingsParser from '../SettingsParser'; + +const Table = ( { element }: { element: StatusElement } ) => { + return ( +
+ + { element.headers.length > 0 && ( + + + { element.headers.map( ( header: string ) => { + return ( + + ); + } ) } + + + ) } + + { element.children.map( ( child ) => { + return ( + + ); + } ) } + +
+ { header } +
+
+ ); +}; +export default Table; diff --git a/src/Status/Elements/TableColumn.tsx b/src/Status/Elements/TableColumn.tsx new file mode 100644 index 0000000000..2c269fabd8 --- /dev/null +++ b/src/Status/Elements/TableColumn.tsx @@ -0,0 +1,18 @@ +import { StatusElement } from '../Status'; +import SettingsParser from '../SettingsParser'; + +const TableColumn = ( { element }: { element: StatusElement } ) => { + return ( + + { element.children.map( ( child ) => { + return ( + + ); + } ) } + + ); +}; +export default TableColumn; diff --git a/src/Status/Elements/TableRow.tsx b/src/Status/Elements/TableRow.tsx new file mode 100644 index 0000000000..5c9216398e --- /dev/null +++ b/src/Status/Elements/TableRow.tsx @@ -0,0 +1,18 @@ +import { StatusElement } from '../Status'; +import SettingsParser from '../SettingsParser'; + +const TableRow = ( { element }: { element: StatusElement } ) => { + return ( + + { element.children.map( ( child ) => { + return ( + + ); + } ) } + + ); +}; +export default TableRow; diff --git a/src/Status/Menu.tsx b/src/Status/Menu.tsx new file mode 100644 index 0000000000..32e470e5fb --- /dev/null +++ b/src/Status/Menu.tsx @@ -0,0 +1,50 @@ +import { StatusElement } from './Status'; + +function classNames( ...classes ) { + return classes.filter( Boolean ).join( ' ' ); +} + +const Menu = ( { + pages, + loading, + activePage, + onMenuClick, +}: { + pages: StatusElement[]; + loading: boolean; + activePage: string; + onMenuClick: ( page: string ) => void; +} ): JSX.Element => { + return ( + + ); +}; + +export default Menu; diff --git a/src/Status/SettingsParser.tsx b/src/Status/SettingsParser.tsx new file mode 100644 index 0000000000..def59fe365 --- /dev/null +++ b/src/Status/SettingsParser.tsx @@ -0,0 +1,43 @@ +import { StatusElement } from './Status'; +import Section from './Elements/Section'; +import SubSection from './Elements/SubSection'; +import Heading from './Elements/Heading'; +import Table from './Elements/Table'; +import TableRow from './Elements/TableRow'; +import TableColumn from './Elements/TableColumn'; +import Paragraph from './Elements/Paragraph'; +import Link from './Elements/Link'; +import Button from './Elements/Button'; + +const SettingsParser = ( { element }: { element: StatusElement } ) => { + switch ( element.type ) { + case 'section': + return
; + case 'sub-section': + return ; + case 'table': + return ; + case 'table-row': + return ; + case 'table-column': + return ; + case 'heading': + return ; + case 'paragraph': + return ; + case 'link': + return ; + case 'button': + return