From 12cfd0d54e0957b6df92946b851b063e078b181c Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Mon, 10 May 2021 14:53:52 +0100 Subject: [PATCH] [Components][l]: Update portal components --- dist/index.cjs.js | 139 ++++++++++++++++++++++++++++---- dist/index.esm.js | 138 +++++++++++++++++++++++++++---- src/components/blog/Post.js | 20 ++--- src/components/blog/PostList.js | 3 - src/components/search/Form.js | 35 +++----- src/index.js | 10 ++- yarn.lock | 5 ++ 7 files changed, 277 insertions(+), 73 deletions(-) diff --git a/dist/index.cjs.js b/dist/index.cjs.js index 6bc81469..6454437b 100644 --- a/dist/index.cjs.js +++ b/dist/index.cjs.js @@ -393,27 +393,27 @@ Org.propTypes = { /** * Displays a blog post page * @param {object} props - * { + * post = { * title: - * content: - * modified: + * createdAt: . + * featuredImage: * } * @returns */ var Post = function Post(_ref) { - var page = _ref.page; - var title = page.title, - content = page.content, - modified = page.modified, - featured_image = page.featured_image; + var post = _ref.post; + var title = post.title, + content = post.content, + createdAt = post.createdAt, + featuredImage = post.featuredImage; return /*#__PURE__*/React__default['default'].createElement(React__default['default'].Fragment, null, /*#__PURE__*/React__default['default'].createElement("h1", { className: "text-3xl font-semibold text-primary my-6 inline-block" }, title), /*#__PURE__*/React__default['default'].createElement("p", { className: "mb-6" - }, "Edited: ", modified), /*#__PURE__*/React__default['default'].createElement("img", { - src: featured_image, + }, "Posted: ", createdAt), /*#__PURE__*/React__default['default'].createElement("img", { + src: featuredImage, className: "mb-6", alt: "featured_img" }), /*#__PURE__*/React__default['default'].createElement("div", null, parse__default['default'](content))); @@ -423,8 +423,8 @@ Post.propTypes = { page: PropTypes__default['default'].shape({ title: PropTypes__default['default'].string.isRequired, content: PropTypes__default['default'].string.isRequired, - modified: PropTypes__default['default'].string, - featured_image: PropTypes__default['default'].string + createdAt: PropTypes__default['default'].number, + featuredImage: PropTypes__default['default'].string }) }; @@ -442,9 +442,7 @@ Post.propTypes = { var PostList = function PostList(_ref) { var posts = _ref.posts; - return /*#__PURE__*/React__default['default'].createElement(React__default['default'].Fragment, null, /*#__PURE__*/React__default['default'].createElement("h1", { - className: "text-3xl font-semibold text-primary my-6 inline-block" - }, posts.length, " posts found"), posts.map(function (post, index) { + return /*#__PURE__*/React__default['default'].createElement(React__default['default'].Fragment, null, posts.map(function (post, index) { return /*#__PURE__*/React__default['default'].createElement("div", { key: index }, /*#__PURE__*/React__default['default'].createElement("a", { @@ -601,9 +599,118 @@ Recent.propTypes = { datasets: PropTypes__default['default'].array.isRequired }; +/** + * Search component form that can be customized with change and submit handlers + * @param {object} props + * { + * handleChange: A form input change event handler. This function is executed when the + * search input or order by input changes. + * handleSubmit: A form submit event handler. This function is executed when the + * search form is submitted. + * } + * @returns + */ + +var Form = function Form(_ref) { + var handleSubmit = _ref.handleSubmit; + + var _useState = React.useState(""), + _useState2 = _slicedToArray(_useState, 2), + searchQuery = _useState2[0], + setSearchQuery = _useState2[1]; + + return /*#__PURE__*/React__default['default'].createElement("form", { + onSubmit: function onSubmit(e) { + return e.preventDefault(); + }, + className: "items-center" + }, /*#__PURE__*/React__default['default'].createElement("div", { + className: "flex" + }, /*#__PURE__*/React__default['default'].createElement("input", { + type: "text", + name: "search#q", + value: searchQuery, + onChange: function onChange(e) { + setSearchQuery(e.target.value); + }, + placeholder: "Search", + "aria-label": "Search", + className: "bg-white focus:outline-none focus:shadow-outline border border-gray-300 w-1/2 rounded-lg py-2 px-4 block appearance-none leading-normal" + }), /*#__PURE__*/React__default['default'].createElement("button", { + onClick: function onClick() { + return handleSubmit(searchQuery); + }, + type: "button", + className: "inline-block text-sm px-4 py-3 mx-3 leading-none border rounded text-white bg-black border-black lg:mt-0" + }, "Search"))); +}; + +Form.propTypes = { + handleSubmit: PropTypes__default['default'].func.isRequired +}; + +/** + * Single item from a search result showing info about a dataset. + * @param {object} props data package with the following format: + * { + * organization: {name: , title: }, + * title: + * name: + * description: + * notes: + * } + * @returns React Component + */ + +var Item = function Item(_ref) { + var dataset = _ref.dataset; + return /*#__PURE__*/React__default['default'].createElement("div", { + className: "mb-6" + }, /*#__PURE__*/React__default['default'].createElement("h3", { + className: "text-xl font-semibold" + }, /*#__PURE__*/React__default['default'].createElement(Link__default['default'], { + href: "/@".concat(dataset.organization ? dataset.organization.name : 'dataset', "/").concat(dataset.name) + }, /*#__PURE__*/React__default['default'].createElement("a", { + className: "text-primary" + }, dataset.title || dataset.name))), /*#__PURE__*/React__default['default'].createElement(Link__default['default'], { + href: "/@".concat(dataset.organization ? dataset.organization.name : 'dataset') + }, /*#__PURE__*/React__default['default'].createElement("a", { + className: "text-gray-500 block mt-1" + }, dataset.organization ? dataset.organization.title : 'dataset')), /*#__PURE__*/React__default['default'].createElement("div", { + className: "leading-relaxed mt-2" + }, dataset.description || dataset.notes)); +}; + +Item.propTypes = { + dataset: PropTypes__default['default'].object.isRequired +}; + +/** + * Displays the total search result + * @param {object} props + * { + * count: The total number of search results + * } + * @returns React Component + */ + +var Total = function Total(_ref) { + var count = _ref.count; + return /*#__PURE__*/React__default['default'].createElement("h1", { + className: "text-3xl font-semibold text-primary my-6 inline-block" + }, count, " results found"); +}; + +Total.propTypes = { + count: PropTypes__default['default'].number.isRequired +}; + exports.CustomLink = CustomLink; exports.DataExplorer = DataExplorer; exports.Error = ErrorMessage; +exports.Form = Form; +exports.Item = Item; +exports.ItemTotal = Total; exports.KeyInfo = KeyInfo; exports.Nav = Nav; exports.Org = Org; diff --git a/dist/index.esm.js b/dist/index.esm.js index 3d29a4e4..15d3b862 100644 --- a/dist/index.esm.js +++ b/dist/index.esm.js @@ -360,27 +360,27 @@ Org.propTypes = { /** * Displays a blog post page * @param {object} props - * { + * post = { * title: - * content: - * modified: + * createdAt: . + * featuredImage: * } * @returns */ var Post = function Post(_ref) { - var page = _ref.page; - var title = page.title, - content = page.content, - modified = page.modified, - featured_image = page.featured_image; + var post = _ref.post; + var title = post.title, + content = post.content, + createdAt = post.createdAt, + featuredImage = post.featuredImage; return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("h1", { className: "text-3xl font-semibold text-primary my-6 inline-block" }, title), /*#__PURE__*/React.createElement("p", { className: "mb-6" - }, "Edited: ", modified), /*#__PURE__*/React.createElement("img", { - src: featured_image, + }, "Posted: ", createdAt), /*#__PURE__*/React.createElement("img", { + src: featuredImage, className: "mb-6", alt: "featured_img" }), /*#__PURE__*/React.createElement("div", null, parse(content))); @@ -390,8 +390,8 @@ Post.propTypes = { page: PropTypes.shape({ title: PropTypes.string.isRequired, content: PropTypes.string.isRequired, - modified: PropTypes.string, - featured_image: PropTypes.string + createdAt: PropTypes.number, + featuredImage: PropTypes.string }) }; @@ -409,9 +409,7 @@ Post.propTypes = { var PostList = function PostList(_ref) { var posts = _ref.posts; - return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("h1", { - className: "text-3xl font-semibold text-primary my-6 inline-block" - }, posts.length, " posts found"), posts.map(function (post, index) { + return /*#__PURE__*/React.createElement(React.Fragment, null, posts.map(function (post, index) { return /*#__PURE__*/React.createElement("div", { key: index }, /*#__PURE__*/React.createElement("a", { @@ -568,4 +566,110 @@ Recent.propTypes = { datasets: PropTypes.array.isRequired }; -export { CustomLink, DataExplorer, ErrorMessage as Error, KeyInfo, Nav, Org, PlotlyChart, Post, PostList, ReadMe, Recent, ResourcesInfo as ResourceInfo, Table }; +/** + * Search component form that can be customized with change and submit handlers + * @param {object} props + * { + * handleChange: A form input change event handler. This function is executed when the + * search input or order by input changes. + * handleSubmit: A form submit event handler. This function is executed when the + * search form is submitted. + * } + * @returns + */ + +var Form = function Form(_ref) { + var handleSubmit = _ref.handleSubmit; + + var _useState = useState(""), + _useState2 = _slicedToArray(_useState, 2), + searchQuery = _useState2[0], + setSearchQuery = _useState2[1]; + + return /*#__PURE__*/React.createElement("form", { + onSubmit: function onSubmit(e) { + return e.preventDefault(); + }, + className: "items-center" + }, /*#__PURE__*/React.createElement("div", { + className: "flex" + }, /*#__PURE__*/React.createElement("input", { + type: "text", + name: "search#q", + value: searchQuery, + onChange: function onChange(e) { + setSearchQuery(e.target.value); + }, + placeholder: "Search", + "aria-label": "Search", + className: "bg-white focus:outline-none focus:shadow-outline border border-gray-300 w-1/2 rounded-lg py-2 px-4 block appearance-none leading-normal" + }), /*#__PURE__*/React.createElement("button", { + onClick: function onClick() { + return handleSubmit(searchQuery); + }, + type: "button", + className: "inline-block text-sm px-4 py-3 mx-3 leading-none border rounded text-white bg-black border-black lg:mt-0" + }, "Search"))); +}; + +Form.propTypes = { + handleSubmit: PropTypes.func.isRequired +}; + +/** + * Single item from a search result showing info about a dataset. + * @param {object} props data package with the following format: + * { + * organization: {name: , title: }, + * title: + * name: + * description: + * notes: + * } + * @returns React Component + */ + +var Item = function Item(_ref) { + var dataset = _ref.dataset; + return /*#__PURE__*/React.createElement("div", { + className: "mb-6" + }, /*#__PURE__*/React.createElement("h3", { + className: "text-xl font-semibold" + }, /*#__PURE__*/React.createElement(Link, { + href: "/@".concat(dataset.organization ? dataset.organization.name : 'dataset', "/").concat(dataset.name) + }, /*#__PURE__*/React.createElement("a", { + className: "text-primary" + }, dataset.title || dataset.name))), /*#__PURE__*/React.createElement(Link, { + href: "/@".concat(dataset.organization ? dataset.organization.name : 'dataset') + }, /*#__PURE__*/React.createElement("a", { + className: "text-gray-500 block mt-1" + }, dataset.organization ? dataset.organization.title : 'dataset')), /*#__PURE__*/React.createElement("div", { + className: "leading-relaxed mt-2" + }, dataset.description || dataset.notes)); +}; + +Item.propTypes = { + dataset: PropTypes.object.isRequired +}; + +/** + * Displays the total search result + * @param {object} props + * { + * count: The total number of search results + * } + * @returns React Component + */ + +var Total = function Total(_ref) { + var count = _ref.count; + return /*#__PURE__*/React.createElement("h1", { + className: "text-3xl font-semibold text-primary my-6 inline-block" + }, count, " results found"); +}; + +Total.propTypes = { + count: PropTypes.number.isRequired +}; + +export { CustomLink, DataExplorer, ErrorMessage as Error, Form, Item, Total as ItemTotal, KeyInfo, Nav, Org, PlotlyChart, Post, PostList, ReadMe, Recent, ResourcesInfo as ResourceInfo, Table }; diff --git a/src/components/blog/Post.js b/src/components/blog/Post.js index e979d679..111d2a73 100644 --- a/src/components/blog/Post.js +++ b/src/components/blog/Post.js @@ -5,24 +5,24 @@ import parse from 'html-react-parser'; /** * Displays a blog post page * @param {object} props - * { + * post = { * title: - * content: - * modified: + * createdAt: . + * featuredImage: * } * @returns */ -const Post = ({ page }) => { - const { title, content, modified, featured_image } = page; +const Post = ({ post }) => { + const { title, content, createdAt, featuredImage } = post; return ( <>

{title}

-

Edited: {modified}

- featured_img +

Posted: {createdAt}

+ featured_img
{parse(content)}
); @@ -33,8 +33,8 @@ Post.propTypes = { page: PropTypes.shape({ title: PropTypes.string.isRequired, content: PropTypes.string.isRequired, - modified: PropTypes.string, - featured_image: PropTypes.string, + createdAt: PropTypes.number, + featuredImage: PropTypes.string, }) } diff --git a/src/components/blog/PostList.js b/src/components/blog/PostList.js index d641d2ce..6e7c5410 100644 --- a/src/components/blog/PostList.js +++ b/src/components/blog/PostList.js @@ -16,9 +16,6 @@ import parse from 'html-react-parser'; const PostList = ({ posts }) => { return ( <> -

- {posts.length} posts found -

{posts.map((post, index) => (
{ - +const Form = ({ handleSubmit }) => { + const [searchQuery, setSearchQuery] = useState("") return ( -
+ e.preventDefault()} className="items-center">
{ setSearchQuery(e.target.value) }} placeholder="Search" aria-label="Search" className="bg-white focus:outline-none focus:shadow-outline border border-gray-300 w-1/2 rounded-lg py-2 px-4 block appearance-none leading-normal" />
-
- - -
); }; Form.propTypes = { - handleChange: PropTypes.func.isRequired, handleSubmit: PropTypes.func.isRequired } diff --git a/src/index.js b/src/index.js index 99f31e39..e36b36e8 100644 --- a/src/index.js +++ b/src/index.js @@ -21,6 +21,11 @@ import CustomLink from './components/misc/CustomLink' import Nav from './components/ui/Nav' import Recent from './components/ui/Recent' +//UI components +import Form from './components/search/Form' +import Item from './components/search/Item' +import ItemTotal from './components/search/Total' + export { Table, PlotlyChart, @@ -34,5 +39,8 @@ export { PostList, Org, Error, - CustomLink + CustomLink, + Form, + Item, + ItemTotal } \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index a6483791..64b7e88f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4557,6 +4557,11 @@ data-urls@^2.0.0: whatwg-mimetype "^2.3.0" whatwg-url "^8.0.0" +dayjs@^1.10.4: + version "1.10.4" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.4.tgz#8e544a9b8683f61783f570980a8a80eaf54ab1e2" + integrity sha512-RI/Hh4kqRc1UKLOAf/T5zdMMX5DQIlDxwUe3wSyMMnEbGunnpENCdbUgM+dW7kXidZqCttBrmw7BhN4TMddkCw== + debug@2, debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"