From 40ff8413c70c5961ff87c905034219f0e3b9aed4 Mon Sep 17 00:00:00 2001 From: Bishal Deb Date: Mon, 16 Dec 2019 00:49:54 +0530 Subject: [PATCH 001/100] Blog module created. --- .../blog/client-react/__tests__/Blog.test.ts | 19 ++++++ .../components/BlogFormCmponent.jsx | 64 +++++++++++++++++++ .../components/BlogView.native.tsx | 36 +++++++++++ .../blog/client-react/components/BlogView.tsx | 29 +++++++++ modules/blog/client-react/containers/Blog.tsx | 16 +++++ .../client-react/graphql/BlogQuery.graphql | 6 ++ modules/blog/client-react/index.native.tsx | 36 +++++++++++ modules/blog/client-react/index.tsx | 27 ++++++++ .../client-react/locales/en/translations.json | 6 ++ modules/blog/client-react/locales/index.js | 5 ++ .../client-react/locales/ru/translations.json | 6 ++ modules/blog/client-react/package.json | 5 ++ modules/blog/server-ts/__tests__/Blog.test.ts | 28 ++++++++ modules/blog/server-ts/index.ts | 11 ++++ modules/blog/server-ts/package.json | 5 ++ modules/blog/server-ts/resolvers.ts | 5 ++ modules/blog/server-ts/schema.graphql | 16 +++++ modules/blog/server-ts/sql.ts | 7 ++ packages/client/package.json | 5 +- packages/client/src/modules.ts | 2 + packages/server/package.json | 1 + packages/server/src/modules.ts | 2 + 22 files changed, 335 insertions(+), 2 deletions(-) create mode 100644 modules/blog/client-react/__tests__/Blog.test.ts create mode 100644 modules/blog/client-react/components/BlogFormCmponent.jsx create mode 100644 modules/blog/client-react/components/BlogView.native.tsx create mode 100644 modules/blog/client-react/components/BlogView.tsx create mode 100644 modules/blog/client-react/containers/Blog.tsx create mode 100644 modules/blog/client-react/graphql/BlogQuery.graphql create mode 100644 modules/blog/client-react/index.native.tsx create mode 100644 modules/blog/client-react/index.tsx create mode 100644 modules/blog/client-react/locales/en/translations.json create mode 100644 modules/blog/client-react/locales/index.js create mode 100644 modules/blog/client-react/locales/ru/translations.json create mode 100644 modules/blog/client-react/package.json create mode 100644 modules/blog/server-ts/__tests__/Blog.test.ts create mode 100644 modules/blog/server-ts/index.ts create mode 100644 modules/blog/server-ts/package.json create mode 100644 modules/blog/server-ts/resolvers.ts create mode 100644 modules/blog/server-ts/schema.graphql create mode 100644 modules/blog/server-ts/sql.ts diff --git a/modules/blog/client-react/__tests__/Blog.test.ts b/modules/blog/client-react/__tests__/Blog.test.ts new file mode 100644 index 000000000..a3d31f03f --- /dev/null +++ b/modules/blog/client-react/__tests__/Blog.test.ts @@ -0,0 +1,19 @@ +import { expect } from 'chai'; + +import { updateContent, Renderer } from '@gqlapp/testing-client-react'; + +describe('Blog UI works', () => { + const renderer = new Renderer({}); + const app = renderer.mount(); + renderer.history.push('/Blog'); + const content = updateContent(app.container); + + it('Blog page renders on mount', () => { + // tslint:disable:no-unused-expression + expect(content).to.not.be.empty; + }); + + it('Blog page has title', async () => { + expect(content.textContent).to.include('Hello, This is the Blog module'); + }); +}); diff --git a/modules/blog/client-react/components/BlogFormCmponent.jsx b/modules/blog/client-react/components/BlogFormCmponent.jsx new file mode 100644 index 000000000..e195696be --- /dev/null +++ b/modules/blog/client-react/components/BlogFormCmponent.jsx @@ -0,0 +1,64 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withFormik } from 'formik'; +import { translate } from '@gqlapp/i18n-client-react'; +import { FieldAdapter as Field } from '@gqlapp/forms-client-react'; +import { required, validate } from '@gqlapp/validation-common-react'; +import { + Form, + RenderField, + Button + // RenderContentField +} from '@gqlapp/look-client-react'; + +// import { createEditorState } from "medium-draft"; + +const BlogFormSchema = { + title: [required], + content: [required] +}; + +class BlogForm extends React.Component { + render() { + const { values, handleSubmit, submitting } = this.props; + return ( +
+ + + + + ); + } +} + +BlogForm.propTypes = { + handleSubmit: PropTypes.func, + onSubmit: PropTypes.func, + submitting: PropTypes.bool, + values: PropTypes.object, + blog: PropTypes.object + // t: PropTypes.func +}; + +const BlogFormWithFormik = withFormik({ + mapPropsToValues: props => ({ + title: props.blog && props.blog.title, + content: props.blog && props.blog.content + }), + validate: values => validate(values, BlogFormSchema), + handleSubmit( + values + // { + // props: { onSubmit } + // } + ) { + // onSubmit(values); + console.log(values); + }, + enableReinitialize: true, + displayName: 'BlogForm' // helps with React DevTools +}); + +export default translate('blog')(BlogFormWithFormik(BlogForm)); diff --git a/modules/blog/client-react/components/BlogView.native.tsx b/modules/blog/client-react/components/BlogView.native.tsx new file mode 100644 index 000000000..22039bf57 --- /dev/null +++ b/modules/blog/client-react/components/BlogView.native.tsx @@ -0,0 +1,36 @@ +import React from 'react'; +import { StyleSheet, Text, View } from 'react-native'; +import { TranslateFunction } from '@gqlapp/i18n-client-react'; + +interface BlogViewProps { + t: TranslateFunction; +} + +const BlogView = ({ t }: BlogViewProps) => { + return ( + + + {t('welcomeText')} + + + ); +}; + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: '#fff', + alignItems: 'center', + justifyContent: 'center' + }, + element: { + paddingTop: 30 + }, + box: { + textAlign: 'center', + marginLeft: 15, + marginRight: 15 + } +}); + +export default BlogView; diff --git a/modules/blog/client-react/components/BlogView.tsx b/modules/blog/client-react/components/BlogView.tsx new file mode 100644 index 000000000..4d0eb34d1 --- /dev/null +++ b/modules/blog/client-react/components/BlogView.tsx @@ -0,0 +1,29 @@ +import React from 'react'; +import Helmet from 'react-helmet'; + +import { PageLayout } from '@gqlapp/look-client-react'; +import { TranslateFunction } from '@gqlapp/i18n-client-react'; +import BlogFormCmponent from './BlogFormCmponent'; +import settings from '@gqlapp/config'; + +interface NewBlogViewProps { + t: TranslateFunction; +} + +const renderMetaData = (t: TranslateFunction) => ( + +); + +const NewBlogView = ({ t }: NewBlogViewProps) => { + return ( + + {renderMetaData(t)} + + + ); +}; + +export default NewBlogView; diff --git a/modules/blog/client-react/containers/Blog.tsx b/modules/blog/client-react/containers/Blog.tsx new file mode 100644 index 000000000..06774590a --- /dev/null +++ b/modules/blog/client-react/containers/Blog.tsx @@ -0,0 +1,16 @@ +import React from 'react'; + +import { translate, TranslateFunction } from '@gqlapp/i18n-client-react'; +import BlogView from '../components/BlogView'; + +interface BlogProps { + t: TranslateFunction; +} + +class Blog extends React.Component { + public render() { + return ; + } +} + +export default translate('blog')(Blog); diff --git a/modules/blog/client-react/graphql/BlogQuery.graphql b/modules/blog/client-react/graphql/BlogQuery.graphql new file mode 100644 index 000000000..f9c511315 --- /dev/null +++ b/modules/blog/client-react/graphql/BlogQuery.graphql @@ -0,0 +1,6 @@ +# GraphQL queries +query queryNameQuery { + queryName { + typename + } +} diff --git a/modules/blog/client-react/index.native.tsx b/modules/blog/client-react/index.native.tsx new file mode 100644 index 000000000..531fc1a38 --- /dev/null +++ b/modules/blog/client-react/index.native.tsx @@ -0,0 +1,36 @@ +import React from 'react'; +import { createStackNavigator } from 'react-navigation'; + +import { translate } from '@gqlapp/i18n-client-react'; +import ClientModule from '@gqlapp/module-client-react-native'; +import { HeaderTitle, IconButton } from '@gqlapp/look-client-react-native'; + +import Blog from './containers/Blog'; +import resources from './locales'; + +const HeaderTitleWithI18n = translate('blog')(HeaderTitle); + +export default new ClientModule({ + drawerItem: [ + { + Blog: { + screen: createStackNavigator({ + Blog: { + screen: Blog, + navigationOptions: ({ navigation }: any) => ({ + headerTitle: , + headerLeft: ( + navigation.openDrawer()} /> + ), + headerStyle: { backgroundColor: '#fff' } + }) + } + }), + navigationOptions: { + drawerLabel: + } + } + } + ], + localization: [{ ns: 'blog', resources }] +}); diff --git a/modules/blog/client-react/index.tsx b/modules/blog/client-react/index.tsx new file mode 100644 index 000000000..62a424074 --- /dev/null +++ b/modules/blog/client-react/index.tsx @@ -0,0 +1,27 @@ +import React from 'react'; + +import ClientModule from '@gqlapp/module-client-react'; +import { translate, TranslateFunction } from '@gqlapp/i18n-client-react'; +import loadable from '@loadable/component'; + +import { Route, NavLink } from 'react-router-dom'; +import { MenuItem } from '@gqlapp/look-client-react'; +import resources from './locales'; + +const NavLinkWithI18n = translate('blog')(({ t }: { t: TranslateFunction }) => ( + + {t('blog:navLink')} + +)); + +export default new ClientModule({ + route: [ + import('./containers/Blog').then(c => c.default))} /> + ], + navItem: [ + + + + ], + localization: [{ ns: 'blog', resources }] +}); diff --git a/modules/blog/client-react/locales/en/translations.json b/modules/blog/client-react/locales/en/translations.json new file mode 100644 index 000000000..ef907aa4b --- /dev/null +++ b/modules/blog/client-react/locales/en/translations.json @@ -0,0 +1,6 @@ +{ + "navLink": "Blog nav link", + "title": "Blog module", + "meta": "Blog example", + "welcomeText": "Hello, This is the Blog module" +} \ No newline at end of file diff --git a/modules/blog/client-react/locales/index.js b/modules/blog/client-react/locales/index.js new file mode 100644 index 000000000..d9fb121cb --- /dev/null +++ b/modules/blog/client-react/locales/index.js @@ -0,0 +1,5 @@ +/* + * The index.js can be empty, it's just needed to point the loader to the root directory of the locales. + * https://github.com/alienfast/i18next-loader#option-2-use-with-import-syntax + */ +export default {}; diff --git a/modules/blog/client-react/locales/ru/translations.json b/modules/blog/client-react/locales/ru/translations.json new file mode 100644 index 000000000..d146c9dae --- /dev/null +++ b/modules/blog/client-react/locales/ru/translations.json @@ -0,0 +1,6 @@ +{ + "navLink": "Blog ссылка", + "title": "Blog модуль", + "meta": "Blog пример", + "welcomeText": "Привет, это Blog модуль" +} \ No newline at end of file diff --git a/modules/blog/client-react/package.json b/modules/blog/client-react/package.json new file mode 100644 index 000000000..7b5588795 --- /dev/null +++ b/modules/blog/client-react/package.json @@ -0,0 +1,5 @@ +{ + "name": "@gqlapp/blog-client-react", + "version": "1.0.0", + "private": true +} diff --git a/modules/blog/server-ts/__tests__/Blog.test.ts b/modules/blog/server-ts/__tests__/Blog.test.ts new file mode 100644 index 000000000..5591a0fba --- /dev/null +++ b/modules/blog/server-ts/__tests__/Blog.test.ts @@ -0,0 +1,28 @@ +import { expect } from 'chai'; +import { ApolloClient } from 'apollo-client'; +import gql from 'graphql-tag'; + +import { getApollo } from '@gqlapp/testing-server-ts'; + +const INTROSPECTION_QUERY = gql` + query introspectionQuery { + __schema { + types { + name + } + } + } +`; + +describe('Blog API works', () => { + let apollo: ApolloClient; + + beforeAll(() => { + apollo = getApollo(); + }); + + it('Should send a query to the GraphQL back end', async () => { + const result = await apollo.query({ query: INTROSPECTION_QUERY }); + expect(result.data).to.have.property('__schema'); + }); +}); diff --git a/modules/blog/server-ts/index.ts b/modules/blog/server-ts/index.ts new file mode 100644 index 000000000..8011b17cc --- /dev/null +++ b/modules/blog/server-ts/index.ts @@ -0,0 +1,11 @@ +import ServerModule from '@gqlapp/module-server-ts'; + +import schema from './schema.graphql'; +import createResolvers from './resolvers'; +import Blog from './sql'; + +export default new ServerModule({ + schema: [schema], + createResolversFunc: [createResolvers], + createContextFunc: [() => ({ Blog: new Blog() })] +}); diff --git a/modules/blog/server-ts/package.json b/modules/blog/server-ts/package.json new file mode 100644 index 000000000..0da3a4438 --- /dev/null +++ b/modules/blog/server-ts/package.json @@ -0,0 +1,5 @@ +{ + "name": "@gqlapp/blog-server-ts", + "version": "1.0.0", + "private": true +} diff --git a/modules/blog/server-ts/resolvers.ts b/modules/blog/server-ts/resolvers.ts new file mode 100644 index 000000000..3f32ddc89 --- /dev/null +++ b/modules/blog/server-ts/resolvers.ts @@ -0,0 +1,5 @@ +export default (pubsub: any) => ({ + Query: {}, + Mutation: {}, + Subscription: {} +}); diff --git a/modules/blog/server-ts/schema.graphql b/modules/blog/server-ts/schema.graphql new file mode 100644 index 000000000..8dfc4da35 --- /dev/null +++ b/modules/blog/server-ts/schema.graphql @@ -0,0 +1,16 @@ +# Entity +type TypeName { + typeName: String! +} + +extend type Query { + queryName: TypeName +} + +extend type Mutation { + mutationName(varName: Int!): TypeName +} + +extend type Subscription { + subscriptionName: TypeName +} diff --git a/modules/blog/server-ts/sql.ts b/modules/blog/server-ts/sql.ts new file mode 100644 index 000000000..c2dc3cb9b --- /dev/null +++ b/modules/blog/server-ts/sql.ts @@ -0,0 +1,7 @@ +import { knex } from '@gqlapp/database-server-ts'; + +export default class Blog { + public blogs() { + return knex.select(); + } +} diff --git a/packages/client/package.json b/packages/client/package.json index f3ab1a3a2..66a655d69 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -109,8 +109,9 @@ "styled-components": "^4.3.1", "subscriptions-transport-ws": "^0.9.16", "use-react-router": "^1.0.7" - }, - "devDependencies": { + , + "@gqlapp/blog-client-react": "^1.0.0"}, + "devDependencies": { "@storybook/addon-actions": "^5.1.8", "@storybook/addon-links": "^5.1.8", "@storybook/addons": "^5.1.8", diff --git a/packages/client/src/modules.ts b/packages/client/src/modules.ts index 5aa6d6c8f..6ca344661 100644 --- a/packages/client/src/modules.ts +++ b/packages/client/src/modules.ts @@ -1,3 +1,4 @@ +import blog from '@gqlapp/blog-client-react'; import pwa from '@gqlapp/pwa-client-react'; import core from '@gqlapp/core-client-react'; import look from '@gqlapp/look-client-react'; @@ -20,6 +21,7 @@ const pagination = require('@gqlapp/pagination-client-react').default; const user = require('@gqlapp/user-client-react').default; const modules = new ClientModule( + blog, pwa, look, validation, diff --git a/packages/server/package.json b/packages/server/package.json index f8a7b6d66..23a990fb2 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -57,6 +57,7 @@ "dependencies": { "@babel/preset-env": "^7.0.0", "@babel/register": "^7.0.0", + "@gqlapp/blog-server-ts": "^1.0.0", "@gqlapp/core-common": "^0.1.0", "@gqlapp/database-server-ts": "^0.1.0", "@gqlapp/testing-server-ts": "^0.1.0", diff --git a/packages/server/src/modules.ts b/packages/server/src/modules.ts index 5457e0926..d4df42c52 100644 --- a/packages/server/src/modules.ts +++ b/packages/server/src/modules.ts @@ -1,3 +1,4 @@ +import blog from '@gqlapp/blog-server-ts'; import core from '@gqlapp/core-server-ts'; import i18n from '@gqlapp/i18n-server-ts'; import validation from '@gqlapp/validation-common-react'; @@ -20,6 +21,7 @@ import ServerModule from '@gqlapp/module-server-ts'; const user = require('@gqlapp/user-server-ts').default; const modules: ServerModule = new ServerModule( + blog, authentication, cookies, i18n, From 966e6f0b1521c1f4803aa7ade4ed455ec093bfc9 Mon Sep 17 00:00:00 2001 From: Bishal Deb Date: Mon, 16 Dec 2019 03:01:59 +0530 Subject: [PATCH 002/100] medium-draft added. --- .../components/BlogFormCmponent.jsx | 19 +++-- .../blog/client-react/components/BlogView.tsx | 10 ++- .../ui-antd/components/RenderContentField.jsx | 69 +++++++++++++++++++ .../client-react/ui-antd/components/index.js | 1 + package.json | 2 + yarn.lock | 29 +++++++- 6 files changed, 117 insertions(+), 13 deletions(-) create mode 100644 modules/look/client-react/ui-antd/components/RenderContentField.jsx diff --git a/modules/blog/client-react/components/BlogFormCmponent.jsx b/modules/blog/client-react/components/BlogFormCmponent.jsx index e195696be..d8439f19e 100644 --- a/modules/blog/client-react/components/BlogFormCmponent.jsx +++ b/modules/blog/client-react/components/BlogFormCmponent.jsx @@ -4,12 +4,7 @@ import { withFormik } from 'formik'; import { translate } from '@gqlapp/i18n-client-react'; import { FieldAdapter as Field } from '@gqlapp/forms-client-react'; import { required, validate } from '@gqlapp/validation-common-react'; -import { - Form, - RenderField, - Button - // RenderContentField -} from '@gqlapp/look-client-react'; +import { Form, RenderField, Button, RenderContentField } from '@gqlapp/look-client-react'; // import { createEditorState } from "medium-draft"; @@ -21,10 +16,20 @@ const BlogFormSchema = { class BlogForm extends React.Component { render() { const { values, handleSubmit, submitting } = this.props; + + const DataUpdate = data => (values.content = data); + return (
- + diff --git a/modules/blog/client-react/components/BlogView.tsx b/modules/blog/client-react/components/BlogView.tsx index 4d0eb34d1..beba18870 100644 --- a/modules/blog/client-react/components/BlogView.tsx +++ b/modules/blog/client-react/components/BlogView.tsx @@ -1,7 +1,7 @@ -import React from 'react'; +import React, { useState, useEffect } from 'react'; import Helmet from 'react-helmet'; -import { PageLayout } from '@gqlapp/look-client-react'; +import { PageLayout, Loading } from '@gqlapp/look-client-react'; import { TranslateFunction } from '@gqlapp/i18n-client-react'; import BlogFormCmponent from './BlogFormCmponent'; import settings from '@gqlapp/config'; @@ -18,10 +18,14 @@ const renderMetaData = (t: TranslateFunction) => ( ); const NewBlogView = ({ t }: NewBlogViewProps) => { + const [flag, setflag] = useState(false); + useEffect(() => { + setflag(true); + }, []); return ( {renderMetaData(t)} - + {flag ? : } ); }; diff --git a/modules/look/client-react/ui-antd/components/RenderContentField.jsx b/modules/look/client-react/ui-antd/components/RenderContentField.jsx new file mode 100644 index 000000000..85f77e261 --- /dev/null +++ b/modules/look/client-react/ui-antd/components/RenderContentField.jsx @@ -0,0 +1,69 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +import { Form } from 'antd'; + +import { convertToRaw } from 'draft-js'; +// if using webpack +import { Editor, createEditorState } from 'medium-draft'; +import mediumDraftExporter from 'medium-draft/lib/exporter'; +import mediumDraftImporter from 'medium-draft/lib/importer'; +import 'medium-draft/lib/index.css'; + +const FormItem = Form.Item; + +export default class RenderContentField extends React.Component { + constructor(props) { + super(props); + + this.state = { + editorState: this.props.value + ? createEditorState(convertToRaw(mediumDraftImporter(this.props.value))) + : createEditorState() // for empty content + }; + + this.onChange = editorState => { + this.setState({ editorState }); + this.props.DataUpdate(mediumDraftExporter(editorState.getCurrentContent())); + }; + + this.refsEditor = React.createRef(); + } + + componentDidMount() { + this.refsEditor.current.focus(); + } + + render() { + const { editorState } = this.state; + const { + label, + meta: { touched, error }, + placeholder + } = this.props; + let validateStatus = ''; + if (touched && error) { + validateStatus = 'error'; + } + return ( + +
+ +
+
+ ); + } +} + +RenderContentField.propTypes = { + label: PropTypes.string, + value: PropTypes.string, + DataUpdate: PropTypes.func, + placeholder: PropTypes.string, + meta: PropTypes.object +}; diff --git a/modules/look/client-react/ui-antd/components/index.js b/modules/look/client-react/ui-antd/components/index.js index b3372f9e5..6ac8a1d9b 100644 --- a/modules/look/client-react/ui-antd/components/index.js +++ b/modules/look/client-react/ui-antd/components/index.js @@ -26,5 +26,6 @@ export { default as LanguagePicker } from './LanguagePicker'; export { default as Pagination } from './Pagination'; export { default as Avatar } from './Avatar'; export { default as Icon } from './Icon'; +export { default as RenderContentField } from './RenderContentField'; export { onAppCreate } from './NavBar'; diff --git a/package.json b/package.json index bd9575975..a9c02fb49 100644 --- a/package.json +++ b/package.json @@ -177,8 +177,10 @@ "whatwg-fetch": "^2.0.4" }, "dependencies": { + "draft-convert": "^2.1.8", "inquirer": "^6.2.2", "lodash": "^4.17.11", + "medium-draft": "^0.5.18", "opencollective": "^1.0.3" }, "resolutions": { diff --git a/yarn.lock b/yarn.lock index 5e3bf9d99..f78ecdc15 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9071,6 +9071,15 @@ dotenv@^8.0.0: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.0.0.tgz#ed310c165b4e8a97bb745b0a9d99c31bda566440" integrity sha512-30xVGqjLjiUOArT4+M5q9sYdvuR4riM6yK9wMcas9Vbp6zZa+ocC9dp6QoftuhTPhFAiLK/0C5Ni2nou/Bk8lg== +draft-convert@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/draft-convert/-/draft-convert-2.1.8.tgz#0508efafeea79e11e5793ba771948128ba151291" + integrity sha512-69etPa5JzZVELs4Lzobgxes1oka5IUyJC+NVIVnA9HPO5eOYLqAONFYxmav1vJjYyHsabq/20nSXj2MtIIQ4Fg== + dependencies: + "@babel/runtime" "^7.5.5" + immutable "~3.7.4" + invariant "^2.2.1" + draft-js@^0.10.0, draft-js@~0.10.0: version "0.10.5" resolved "https://registry.yarnpkg.com/draft-js/-/draft-js-0.10.5.tgz#bfa9beb018fe0533dbb08d6675c371a6b08fa742" @@ -12428,7 +12437,7 @@ immutable-tuple@^0.4.9: resolved "https://registry.yarnpkg.com/immutable-tuple/-/immutable-tuple-0.4.10.tgz#e0b1625384f514084a7a84b749a3bb26e9179929" integrity sha512-45jheDbc3Kr5Cw8EtDD+4woGRUV0utIrJBZT8XH0TPZRfm8tzT0/sLGGzyyCCFqFMG5Pv5Igf3WY/arn6+8V9Q== -immutable@^3.7.4, immutable@^3.8.1: +immutable@^3.7.4, immutable@^3.7.6, immutable@^3.8.1: version "3.8.2" resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.2.tgz#c2439951455bb39913daf281376f1530e104adf3" integrity sha1-wkOZUUVbs5kT2vKBN28VMOEErfM= @@ -12729,7 +12738,7 @@ into-stream@^3.1.0: from2 "^2.1.1" p-is-promise "^1.1.0" -invariant@2.2.4, invariant@^2.2.0, invariant@^2.2.2, invariant@^2.2.3, invariant@^2.2.4: +invariant@2.2.4, invariant@^2.2.0, invariant@^2.2.1, invariant@^2.2.2, invariant@^2.2.3, invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== @@ -15302,6 +15311,15 @@ media-typer@0.3.0: resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= +medium-draft@^0.5.18: + version "0.5.18" + resolved "https://registry.yarnpkg.com/medium-draft/-/medium-draft-0.5.18.tgz#8f56693239346fad542c9c8b0d2a7df306188402" + integrity sha512-+KVuqh/WPuTo6ifAcPFKwx4cdiMxeKB0vWKO1IxyuQ/6VIKr8fm9Oaq+3fmOJGezH3nq3q4FdC6sYe/isZpH6Q== + dependencies: + draft-js "^0.10.0" + immutable "^3.7.6" + react-transition-group "^2.5.0" + mem@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" @@ -20335,7 +20353,7 @@ react-transform-hmr@^1.0.4: global "^4.3.0" react-proxy "^1.1.7" -react-transition-group@^2.2.1, react-transition-group@^2.3.0-beta.0: +react-transition-group@^2.2.1, react-transition-group@^2.3.0-beta.0, react-transition-group@^2.5.0: version "2.9.0" resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d" integrity sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg== @@ -21538,6 +21556,11 @@ serialize-javascript@^1.4.0, serialize-javascript@^1.7.0: resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.7.0.tgz#d6e0dfb2a3832a8c94468e6eb1db97e55a192a65" integrity sha512-ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA== +serialize-javascript@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61" + integrity sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ== + serve-favicon@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/serve-favicon/-/serve-favicon-2.5.0.tgz#935d240cdfe0f5805307fdfe967d88942a2cbcf0" From c9b2df9273f0498daa91d3fd222e7f2be8cd887a Mon Sep 17 00:00:00 2001 From: Bishal Deb Date: Mon, 16 Dec 2019 04:33:07 +0530 Subject: [PATCH 003/100] medium-draft imagwe file to base64. --- .../ui-antd/components/RenderContentField.jsx | 37 ++++++++++++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/modules/look/client-react/ui-antd/components/RenderContentField.jsx b/modules/look/client-react/ui-antd/components/RenderContentField.jsx index 85f77e261..28e3cdf63 100644 --- a/modules/look/client-react/ui-antd/components/RenderContentField.jsx +++ b/modules/look/client-react/ui-antd/components/RenderContentField.jsx @@ -5,13 +5,38 @@ import { Form } from 'antd'; import { convertToRaw } from 'draft-js'; // if using webpack -import { Editor, createEditorState } from 'medium-draft'; +import { ImageSideButton, Block, addNewBlock, Editor, createEditorState } from 'medium-draft'; import mediumDraftExporter from 'medium-draft/lib/exporter'; import mediumDraftImporter from 'medium-draft/lib/importer'; import 'medium-draft/lib/index.css'; - +// import "isomorphic-fetch"; const FormItem = Form.Item; +class CustomImageSideButton extends ImageSideButton { + onChange = async e => { + const convertTobase64 = file => { + return new Promise((resolve, reject) => { + const reader = new window.FileReader(); + reader.readAsDataURL(file); + reader.onload = function() { + resolve(reader.result); + }; + reader.onerror = function() { + reject('Error'); + }; + }); + }; + convertTobase64(e.target.files[0]).then(res => { + return this.props.setEditorState( + addNewBlock(this.props.getEditorState(), Block.IMAGE, { + src: res + }) + ); + }); + this.props.close(); + }; +} + export default class RenderContentField extends React.Component { constructor(props) { super(props); @@ -22,6 +47,13 @@ export default class RenderContentField extends React.Component { : createEditorState() // for empty content }; + this.sideButtons = [ + { + title: 'Image', + component: CustomImageSideButton + } + ]; + this.onChange = editorState => { this.setState({ editorState }); this.props.DataUpdate(mediumDraftExporter(editorState.getCurrentContent())); @@ -52,6 +84,7 @@ export default class RenderContentField extends React.Component { ref={this.refsEditor} editorState={editorState} placeholder={placeholder || label} + sideButtons={this.sideButtons} onChange={this.onChange} /> From ec6007bd5e2b98f9ec7291654ffbb3972b1fff0c Mon Sep 17 00:00:00 2001 From: Bishal Deb Date: Thu, 19 Dec 2019 10:55:20 +0530 Subject: [PATCH 004/100] RenderUpload fixed and added in blog form. --- .../components/BlogFormCmponent.jsx | 61 ++++++++++--------- modules/forms/client-react/FieldAdapter.jsx | 45 +++++++++++--- .../ui-antd/components/RenderUpload.jsx | 1 - .../client-react/ui-antd/components/index.js | 2 + 4 files changed, 70 insertions(+), 39 deletions(-) diff --git a/modules/blog/client-react/components/BlogFormCmponent.jsx b/modules/blog/client-react/components/BlogFormCmponent.jsx index d8439f19e..722f177f1 100644 --- a/modules/blog/client-react/components/BlogFormCmponent.jsx +++ b/modules/blog/client-react/components/BlogFormCmponent.jsx @@ -1,42 +1,44 @@ -import React from 'react'; +import React, { useState } from 'react'; import PropTypes from 'prop-types'; import { withFormik } from 'formik'; import { translate } from '@gqlapp/i18n-client-react'; import { FieldAdapter as Field } from '@gqlapp/forms-client-react'; import { required, validate } from '@gqlapp/validation-common-react'; -import { Form, RenderField, Button, RenderContentField } from '@gqlapp/look-client-react'; - -// import { createEditorState } from "medium-draft"; +import { Form, RenderField, Button, RenderUpload, RenderContentField } from '@gqlapp/look-client-react'; const BlogFormSchema = { title: [required], + image: [required], content: [required] }; - -class BlogForm extends React.Component { - render() { - const { values, handleSubmit, submitting } = this.props; - - const DataUpdate = data => (values.content = data); - - return ( - - - - - - ); - } -} +const BlogForm = ({ values, handleSubmit, submitting }) => { + const DataUpdate = data => (values.content = data); + const [load, setload] = useState(false); + return ( +
+ + + + + + ); +}; BlogForm.propTypes = { handleSubmit: PropTypes.func, @@ -50,6 +52,7 @@ BlogForm.propTypes = { const BlogFormWithFormik = withFormik({ mapPropsToValues: props => ({ title: props.blog && props.blog.title, + image: props.blog && props.blog.image, content: props.blog && props.blog.content }), validate: values => validate(values, BlogFormSchema), diff --git a/modules/forms/client-react/FieldAdapter.jsx b/modules/forms/client-react/FieldAdapter.jsx index 542151bd3..32ee6c2d7 100644 --- a/modules/forms/client-react/FieldAdapter.jsx +++ b/modules/forms/client-react/FieldAdapter.jsx @@ -2,19 +2,20 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { connect } from 'formik'; import { get as getPath } from 'lodash'; - -import { PLATFORM } from '@gqlapp/core-common'; +import { isString } from 'util'; +import { PLATFORM } from '../../../packages/common/utils'; class FieldAdapter extends Component { static propTypes = { formik: PropTypes.object.isRequired, component: PropTypes.func, + type: PropTypes.string, onChangeText: PropTypes.func, onChange: PropTypes.func, onBlur: PropTypes.func, name: PropTypes.string.isRequired, - value: PropTypes.string, - defaultValue: PropTypes.string, + value: PropTypes.any, + defaultValue: PropTypes.any, checked: PropTypes.bool, defaultChecked: PropTypes.bool, disabled: PropTypes.bool @@ -25,12 +26,28 @@ class FieldAdapter extends Component { this.props = props; } - onChange = e => { + // To Do - ReConfirm that this works + onChange = (e, secondArg) => { const { onChange } = this.props; + // console.log(this.props); if (onChange) { - onChange(e.target.value, e); + onChange(e); + } + if (e._isAMomentObject && secondArg) { + this.props.formik.setFieldValue(this.props.name, secondArg); + } else if (Array.isArray(e) && e[0]._isAMomentObject && e[1]._isAMomentObject && secondArg) { + this.props.formik.setFieldValue(this.props.name, secondArg); + } else if (isString(e)) { + // for Option Field + this.props.formik.setFieldValue(this.props.name, e); + } else if (e.target.type == 'radio') { + this.props.formik.setFieldValue(e.target.name, e.target.value); + } else if (e.target.checked) { + this.props.formik.setFieldValue(e.target.name, e.target.checked); + } else if (e.target.type == 'number') { + this.props.formik.setFieldValue(e.target.name, parseInt(e.target.value)); } else { - this.props.formik.handleChange(e); + this.props.formik.setFieldValue(this.props.name, e.target.value || e.target.checked); } }; @@ -42,7 +59,9 @@ class FieldAdapter extends Component { if (PLATFORM === 'mobile') { formik.setFieldTouched(name, true); } else { - formik.handleBlur(e); + // console.log(name); + // formik.handleBlur(e); + formik.setFieldTouched(name, true); } } }; @@ -59,9 +78,17 @@ class FieldAdapter extends Component { }; render() { - const { formik, component, name, defaultValue, defaultChecked, disabled } = this.props; + const { formik, component, name, defaultChecked, disabled } = this.props; + let { defaultValue } = this.props; let { value, checked } = this.props; value = value || ''; + // const type = this.props.type; + // if (type == 'number') { + // value = parseInt(value); + // defaultValue = parseInt(defaultValue); + // console.log(value); + // } + checked = checked || false; const meta = { touched: getPath(formik.touched, name), diff --git a/modules/look/client-react/ui-antd/components/RenderUpload.jsx b/modules/look/client-react/ui-antd/components/RenderUpload.jsx index ead97195c..cf0fd5d38 100644 --- a/modules/look/client-react/ui-antd/components/RenderUpload.jsx +++ b/modules/look/client-react/ui-antd/components/RenderUpload.jsx @@ -128,6 +128,5 @@ RenderUpload.propTypes = { input: PropTypes.object, label: PropTypes.string, setload: PropTypes.func, - value: PropTypes.string }; diff --git a/modules/look/client-react/ui-antd/components/index.js b/modules/look/client-react/ui-antd/components/index.js index 6ac8a1d9b..0d0af38e4 100644 --- a/modules/look/client-react/ui-antd/components/index.js +++ b/modules/look/client-react/ui-antd/components/index.js @@ -10,6 +10,8 @@ export { default as Option } from './Option'; export { default as RenderField } from './RenderField'; export { default as RenderSelect } from './RenderSelect'; export { default as RenderCheckBox } from './RenderCheckBox'; +export { default as RenderUpload } from './RenderUpload'; +export { default as RenderUploadMultiple } from './RenderUploadMultiple'; export { default as Alert } from './Alert'; export { default as Container } from './Container'; export { default as Row } from './Row'; From 092e032bcab00609cf0c5eb63d4fa1f100ee1cd6 Mon Sep 17 00:00:00 2001 From: Bishal Deb Date: Thu, 19 Dec 2019 11:00:05 +0530 Subject: [PATCH 005/100] RenderUpload title and card in blog form. --- modules/blog/client-react/components/BlogView.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/modules/blog/client-react/components/BlogView.tsx b/modules/blog/client-react/components/BlogView.tsx index beba18870..62bd84534 100644 --- a/modules/blog/client-react/components/BlogView.tsx +++ b/modules/blog/client-react/components/BlogView.tsx @@ -1,7 +1,7 @@ import React, { useState, useEffect } from 'react'; import Helmet from 'react-helmet'; -import { PageLayout, Loading } from '@gqlapp/look-client-react'; +import { PageLayout, Loading, Card } from '@gqlapp/look-client-react'; import { TranslateFunction } from '@gqlapp/i18n-client-react'; import BlogFormCmponent from './BlogFormCmponent'; import settings from '@gqlapp/config'; @@ -25,7 +25,13 @@ const NewBlogView = ({ t }: NewBlogViewProps) => { return ( {renderMetaData(t)} - {flag ? : } + {flag ? ( + + + + ) : ( + + )} ); }; From 28558777b8a7b27aa73db5d4db698c428d7939b4 Mon Sep 17 00:00:00 2001 From: Bishal Deb Date: Fri, 20 Dec 2019 21:47:27 +0530 Subject: [PATCH 006/100] Blog view component done. --- .../client-react/components/BlogComponent.jsx | 47 ++++++++++++ .../components/BlogFormCmponent.jsx | 74 +++++++++++-------- .../blog/client-react/components/BlogView.jsx | 0 .../{BlogView.tsx => NewBlogView.jsx} | 28 +++---- modules/blog/client-react/containers/Blog.tsx | 16 ---- .../blog/client-react/containers/NewBlog.jsx | 52 +++++++++++++ modules/blog/client-react/index.tsx | 2 +- tsconfig.json | 2 +- 8 files changed, 154 insertions(+), 67 deletions(-) create mode 100644 modules/blog/client-react/components/BlogComponent.jsx create mode 100644 modules/blog/client-react/components/BlogView.jsx rename modules/blog/client-react/components/{BlogView.tsx => NewBlogView.jsx} (52%) delete mode 100644 modules/blog/client-react/containers/Blog.tsx create mode 100644 modules/blog/client-react/containers/NewBlog.jsx diff --git a/modules/blog/client-react/components/BlogComponent.jsx b/modules/blog/client-react/components/BlogComponent.jsx new file mode 100644 index 000000000..9fdb9922e --- /dev/null +++ b/modules/blog/client-react/components/BlogComponent.jsx @@ -0,0 +1,47 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { translate } from '@gqlapp/i18n-client-react'; +import { Col, Row } from '@gqlapp/look-client-react'; + +import { Card, Avatar } from 'antd'; + +const { Meta } = Card; + +const BlogComponent = ({ blog }) => { + return ( + + + }> +

+ {blog.title} +

+
+ } + title={ + + {`${blog.author.firstname} ${blog.author.lastname} `} + ({blog.author.username}) + + } + description={`${blog.createdAt} - ${blog.readTime} read`} + /> +
+
+ + + + ); +}; + +BlogComponent.propTypes = { + blog: PropTypes.object + // t: PropTypes.func +}; + +export default translate('blog')(BlogComponent); diff --git a/modules/blog/client-react/components/BlogFormCmponent.jsx b/modules/blog/client-react/components/BlogFormCmponent.jsx index 722f177f1..d9c443094 100644 --- a/modules/blog/client-react/components/BlogFormCmponent.jsx +++ b/modules/blog/client-react/components/BlogFormCmponent.jsx @@ -4,39 +4,51 @@ import { withFormik } from 'formik'; import { translate } from '@gqlapp/i18n-client-react'; import { FieldAdapter as Field } from '@gqlapp/forms-client-react'; import { required, validate } from '@gqlapp/validation-common-react'; -import { Form, RenderField, Button, RenderUpload, RenderContentField } from '@gqlapp/look-client-react'; +import { Form, RenderField, Button, RenderUpload, Col, Row, Card, RenderContentField } from '@gqlapp/look-client-react'; const BlogFormSchema = { title: [required], image: [required], content: [required] }; -const BlogForm = ({ values, handleSubmit, submitting }) => { +const BlogForm = ({ values, handleSubmit, submitting, cardTitle }) => { const DataUpdate = data => (values.content = data); const [load, setload] = useState(false); return ( -
- - - - - + + + + {cardTitle} + + } + > +
+ + + + + +
+ +
); }; @@ -45,7 +57,8 @@ BlogForm.propTypes = { onSubmit: PropTypes.func, submitting: PropTypes.bool, values: PropTypes.object, - blog: PropTypes.object + blog: PropTypes.object, + cardTitle: PropTypes.string // t: PropTypes.func }; @@ -57,13 +70,12 @@ const BlogFormWithFormik = withFormik({ }), validate: values => validate(values, BlogFormSchema), handleSubmit( - values - // { - // props: { onSubmit } - // } + values, + { + props: { onSubmit } + } ) { - // onSubmit(values); - console.log(values); + onSubmit(values); }, enableReinitialize: true, displayName: 'BlogForm' // helps with React DevTools diff --git a/modules/blog/client-react/components/BlogView.jsx b/modules/blog/client-react/components/BlogView.jsx new file mode 100644 index 000000000..e69de29bb diff --git a/modules/blog/client-react/components/BlogView.tsx b/modules/blog/client-react/components/NewBlogView.jsx similarity index 52% rename from modules/blog/client-react/components/BlogView.tsx rename to modules/blog/client-react/components/NewBlogView.jsx index 62bd84534..70b4884f0 100644 --- a/modules/blog/client-react/components/BlogView.tsx +++ b/modules/blog/client-react/components/NewBlogView.jsx @@ -1,39 +1,31 @@ import React, { useState, useEffect } from 'react'; import Helmet from 'react-helmet'; - -import { PageLayout, Loading, Card } from '@gqlapp/look-client-react'; -import { TranslateFunction } from '@gqlapp/i18n-client-react'; -import BlogFormCmponent from './BlogFormCmponent'; +import PropTypes from 'prop-types'; +import { PageLayout, Loading } from '@gqlapp/look-client-react'; import settings from '@gqlapp/config'; +import BlogFormCmponent from './BlogFormCmponent'; -interface NewBlogViewProps { - t: TranslateFunction; -} - -const renderMetaData = (t: TranslateFunction) => ( +const renderMetaData = t => ( ); -const NewBlogView = ({ t }: NewBlogViewProps) => { +const NewBlogView = props => { const [flag, setflag] = useState(false); useEffect(() => { setflag(true); }, []); return ( - {renderMetaData(t)} - {flag ? ( - - - - ) : ( - - )} + {renderMetaData(props.t)} + {flag ? : } ); }; +NewBlogView.propTypes = { + t: PropTypes.func +}; export default NewBlogView; diff --git a/modules/blog/client-react/containers/Blog.tsx b/modules/blog/client-react/containers/Blog.tsx deleted file mode 100644 index 06774590a..000000000 --- a/modules/blog/client-react/containers/Blog.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import React from 'react'; - -import { translate, TranslateFunction } from '@gqlapp/i18n-client-react'; -import BlogView from '../components/BlogView'; - -interface BlogProps { - t: TranslateFunction; -} - -class Blog extends React.Component { - public render() { - return ; - } -} - -export default translate('blog')(Blog); diff --git a/modules/blog/client-react/containers/NewBlog.jsx b/modules/blog/client-react/containers/NewBlog.jsx new file mode 100644 index 000000000..b8e144216 --- /dev/null +++ b/modules/blog/client-react/containers/NewBlog.jsx @@ -0,0 +1,52 @@ +import React from 'react'; + +import { translate } from '@gqlapp/i18n-client-react'; +import { message } from 'antd'; +import NewBlogView from '../components/NewBlogView'; +import BlogComponent from '../components/BlogComponent'; + +class NewBlog extends React.Component { + state = { + title: '', + image: '', + content: '', + flag: false, + author: { + image: 'https://accounts.google.com/SignOutOptions?hl=en-GB&continue=https://www.google.com%3Fhl%3Den-GB', + firstname: 'Bishal', + lastname: 'Deb', + username: 'Zalophus' + }, + createdAt: '2009-12-10', + readTime: '5 min' + }; + + onSubmit = value => { + message.loading('Please wait...', 0); + try { + this.setState({ + title: value.title, + image: value.image, + content: value.content, + flag: true + }); + } catch (e) { + message.destroy(); + message.error('Submission error. Please try again'); + throw Error(e); + } + message.destroy(); + message.success('Submission success'); + }; + + render() { + return ( + <> + + {this.state.flag && } + + ); + } +} + +export default translate('blog')(NewBlog); diff --git a/modules/blog/client-react/index.tsx b/modules/blog/client-react/index.tsx index 62a424074..ba2e22983 100644 --- a/modules/blog/client-react/index.tsx +++ b/modules/blog/client-react/index.tsx @@ -16,7 +16,7 @@ const NavLinkWithI18n = translate('blog')(({ t }: { t: TranslateFunction }) => ( export default new ClientModule({ route: [ - import('./containers/Blog').then(c => c.default))} /> + import('./containers/NewBlog').then(c => c.default))} /> ], navItem: [ diff --git a/tsconfig.json b/tsconfig.json index 23c1afbe7..80e44043b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -21,7 +21,7 @@ "include": [ "**/typings.d.ts", "**/*.ts", - "**/*.tsx" + "**/*.tsx", "modules/blog/client-react/components/NewBlogView.jsx", "modules/blog/client-react/containers/NewBlog.jsx" ], "exclude": [ "node_modules" From 3d7a161acf8578ea193a59b10649e33a0a2222de Mon Sep 17 00:00:00 2001 From: Bishal Deb Date: Fri, 20 Dec 2019 22:38:50 +0530 Subject: [PATCH 007/100] Blog route done. --- .../blog/client-react/components/BlogView.jsx | 32 +++++++++++++++++++ modules/blog/client-react/containers/Blog.jsx | 28 ++++++++++++++++ modules/blog/client-react/index.tsx | 3 +- 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 modules/blog/client-react/containers/Blog.jsx diff --git a/modules/blog/client-react/components/BlogView.jsx b/modules/blog/client-react/components/BlogView.jsx index e69de29bb..c4bae89ca 100644 --- a/modules/blog/client-react/components/BlogView.jsx +++ b/modules/blog/client-react/components/BlogView.jsx @@ -0,0 +1,32 @@ +import React, { useState, useEffect } from 'react'; +import Helmet from 'react-helmet'; +import PropTypes from 'prop-types'; +import { PageLayout, Loading } from '@gqlapp/look-client-react'; +import settings from '@gqlapp/config'; +// import { message } from 'antd'; +import BlogComponent from './BlogComponent'; + +const renderMetaData = t => ( + +); + +const BlogView = props => { + const [flag, setflag] = useState(false); + useEffect(() => { + setflag(true); + }, []); + return ( + + {renderMetaData(props.t)} + {flag ? : } + + ); +}; +BlogView.propTypes = { + t: PropTypes.func +}; + +export default BlogView; diff --git a/modules/blog/client-react/containers/Blog.jsx b/modules/blog/client-react/containers/Blog.jsx new file mode 100644 index 000000000..f51818fbc --- /dev/null +++ b/modules/blog/client-react/containers/Blog.jsx @@ -0,0 +1,28 @@ +import React from 'react'; + +import { translate } from '@gqlapp/i18n-client-react'; +// import { message } from 'antd'; +import BlogView from '../components/BlogView'; + +class NewBlog extends React.Component { + state = { + title: 'Hey Bishal Here', + image: 'https://miro.medium.com/fit/c/40/40/2*_KGzadiy9s83D4vzhsCyyg.png', + content: '

Bishal Here again

', + author: { + image: 'https://miro.medium.com/fit/c/40/40/2*_KGzadiy9s83D4vzhsCyyg.png', + firstname: 'Bishal', + lastname: 'Deb', + username: 'Zalophus' + }, + createdAt: '2009-12-10', + readTime: '5 min', + claps: 125 + }; + + render() { + return ; + } +} + +export default translate('blog')(NewBlog); diff --git a/modules/blog/client-react/index.tsx b/modules/blog/client-react/index.tsx index ba2e22983..0e704d5e0 100644 --- a/modules/blog/client-react/index.tsx +++ b/modules/blog/client-react/index.tsx @@ -16,7 +16,8 @@ const NavLinkWithI18n = translate('blog')(({ t }: { t: TranslateFunction }) => ( export default new ClientModule({ route: [ - import('./containers/NewBlog').then(c => c.default))} /> + import('./containers/NewBlog').then(c => c.default))} />, + import('./containers/Blog').then(c => c.default))} /> ], navItem: [ From 5d4882f06631653e2a8b54ebe82b3433dae45486 Mon Sep 17 00:00:00 2001 From: Bishal Deb Date: Sat, 21 Dec 2019 18:49:21 +0530 Subject: [PATCH 008/100] Icon for like added. --- .../client-react/components/BlogComponent.jsx | 22 +++++++++++++++---- modules/blog/client-react/containers/Blog.jsx | 10 +++++++-- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/modules/blog/client-react/components/BlogComponent.jsx b/modules/blog/client-react/components/BlogComponent.jsx index 9fdb9922e..2157911bf 100644 --- a/modules/blog/client-react/components/BlogComponent.jsx +++ b/modules/blog/client-react/components/BlogComponent.jsx @@ -3,11 +3,11 @@ import PropTypes from 'prop-types'; import { translate } from '@gqlapp/i18n-client-react'; import { Col, Row } from '@gqlapp/look-client-react'; -import { Card, Avatar } from 'antd'; +import { Card, Avatar, Button, Divider } from 'antd'; const { Meta } = Card; -const BlogComponent = ({ blog }) => { +const BlogComponent = ({ setClap, blog }) => { return ( { />
+ + + + + + + ); +}; + +BlogRefCard.propTypes = { + model: PropTypes.object, + user: PropTypes.object, + // setClap: PropTypes.func, + t: PropTypes.func +}; + +export default translate('blog')(BlogRefCard); diff --git a/modules/blog/client-react/containers/Blog.jsx b/modules/blog/client-react/containers/Blog.jsx index ecfe3b54f..04c917e36 100644 --- a/modules/blog/client-react/containers/Blog.jsx +++ b/modules/blog/client-react/containers/Blog.jsx @@ -2,24 +2,11 @@ import React from 'react'; import { translate } from '@gqlapp/i18n-client-react'; // import { message } from 'antd'; +import { blog } from '../demoData'; import BlogView from '../components/BlogView'; class NewBlog extends React.Component { - state = { - title: 'Hey Bishal Here', - image: 'https://miro.medium.com/fit/c/40/40/2*_KGzadiy9s83D4vzhsCyyg.png', - content: '

Bishal Here again

', - author: { - image: 'https://miro.medium.com/fit/c/40/40/2*_KGzadiy9s83D4vzhsCyyg.png', - firstname: 'Bishal', - lastname: 'Deb', - username: 'Zalophus' - }, - createdAt: '2009-12-10', - readTime: '5 min', - claps: 125, - clapFlag: true - }; + state = { ...blog }; setClap = () => { let val = !this.state.clapFlag; diff --git a/modules/blog/client-react/demoData/index.jsx b/modules/blog/client-react/demoData/index.jsx new file mode 100644 index 000000000..5129746c2 --- /dev/null +++ b/modules/blog/client-react/demoData/index.jsx @@ -0,0 +1,34 @@ +export const blog = { + title: 'Boruto', + image: 'https://miro.medium.com/fit/c/40/40/2*_KGzadiy9s83D4vzhsCyyg.png', + content: '

Boruto - Naruto Nexy Generations

', + model: { + id: 1, + name: 'Anime', + desc: 'The world otakus are proud of. Lol.', + image: + 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT_yHrpo9HrvefMGkn6NSCwmVUDICnDMQYF79oFMl6Z316p-XwXAQ&s' + }, + author: { + image: 'https://miro.medium.com/fit/c/40/40/2*_KGzadiy9s83D4vzhsCyyg.png', + firstname: 'Bishal', + lastname: 'Deb', + username: 'Zalophus', + desc: 'Just another normal human being here!' + }, + tags: [ + { id: 1, name: 'tag 1' }, + { id: 2, name: 'tag 2' }, + { id: 3, name: 'tag 3' }, + { id: 4, name: 'tag 4' }, + { id: 5, name: 'tag 5' }, + { id: 6, name: 'tag 6' } + ], + createdAt: '2009-12-10', + readTime: '5 min', + claps: 125, + clapFlag: true, + status: 'Published' +}; + +export const blogs = []; From 84e5b5ca68fa0184c8d39b0d0b62dd39cbf1b521 Mon Sep 17 00:00:00 2001 From: Bishal Deb Date: Wed, 25 Dec 2019 02:46:58 +0530 Subject: [PATCH 011/100] BlogDetails Views done! --- .../client-react/components/BlogComponent.jsx | 32 +++++-- .../components/BlogFormCmponent.jsx | 39 ++++++++- ...ogRefCard.jsx => BlogRefCardComponent.jsx} | 6 +- .../components/MiniBlogsCardComponent.jsx | 85 +++++++++++++++++++ modules/blog/client-react/containers/Blog.jsx | 17 ++-- modules/blog/client-react/demoData/index.jsx | 66 +++++++++++++- 6 files changed, 224 insertions(+), 21 deletions(-) rename modules/blog/client-react/components/{BlogRefCard.jsx => BlogRefCardComponent.jsx} (89%) create mode 100644 modules/blog/client-react/components/MiniBlogsCardComponent.jsx diff --git a/modules/blog/client-react/components/BlogComponent.jsx b/modules/blog/client-react/components/BlogComponent.jsx index 16059e268..d39bb48ee 100644 --- a/modules/blog/client-react/components/BlogComponent.jsx +++ b/modules/blog/client-react/components/BlogComponent.jsx @@ -4,11 +4,12 @@ import { translate } from '@gqlapp/i18n-client-react'; import { Col, Row } from '@gqlapp/look-client-react'; import { Card, Avatar, Button, Divider, Tag } from 'antd'; -import BlogRefCard from './BlogRefCard'; +import BlogRefCardComponent from './BlogRefCardComponent'; +import MiniBlogsCardComponent from './MiniBlogsCardComponent'; const { Meta } = Card; -const BlogComponent = ({ setClap, blog }) => { +const BlogComponent = ({ setClap, blog, moreBlogs }) => { return ( { />
- {/* */} - {/*
*/} - {/* */} {blog.tags.map((item, idx) => ( @@ -65,8 +63,27 @@ const BlogComponent = ({ setClap, blog }) => { {`${blog.claps}`} - - + + + + + +

+
+
+ More From DemoBlog +
+

+ + {moreBlogs.map(item => ( + + ))} + ); @@ -74,6 +91,7 @@ const BlogComponent = ({ setClap, blog }) => { BlogComponent.propTypes = { blog: PropTypes.object, + moreBlogs: PropTypes.array, setClap: PropTypes.func, t: PropTypes.func }; diff --git a/modules/blog/client-react/components/BlogFormCmponent.jsx b/modules/blog/client-react/components/BlogFormCmponent.jsx index d9c443094..5607a3486 100644 --- a/modules/blog/client-react/components/BlogFormCmponent.jsx +++ b/modules/blog/client-react/components/BlogFormCmponent.jsx @@ -4,12 +4,24 @@ import { withFormik } from 'formik'; import { translate } from '@gqlapp/i18n-client-react'; import { FieldAdapter as Field } from '@gqlapp/forms-client-react'; import { required, validate } from '@gqlapp/validation-common-react'; -import { Form, RenderField, Button, RenderUpload, Col, Row, Card, RenderContentField } from '@gqlapp/look-client-react'; +import { + Form, + RenderField, + Button, + RenderUpload, + Col, + Row, + Card, + RenderContentField, + RenderSelect +} from '@gqlapp/look-client-react'; +import { Select } from 'antd'; const BlogFormSchema = { title: [required], image: [required], - content: [required] + content: [required], + modelId: [required] }; const BlogForm = ({ values, handleSubmit, submitting, cardTitle }) => { const DataUpdate = data => (values.content = data); @@ -25,6 +37,26 @@ const BlogForm = ({ values, handleSubmit, submitting, cardTitle }) => { } >
+ + Jack + Rok + Lucy + Tom + {/* {this.state.listingCategories.gearCategory.map( + (category, idx) => ( + + {category} + + ) + )} */} + ({ title: props.blog && props.blog.title, image: props.blog && props.blog.image, - content: props.blog && props.blog.content + content: props.blog && props.blog.content, + modelId: props.blog && props.blog.model ? props.blog.model.id : null }), validate: values => validate(values, BlogFormSchema), handleSubmit( diff --git a/modules/blog/client-react/components/BlogRefCard.jsx b/modules/blog/client-react/components/BlogRefCardComponent.jsx similarity index 89% rename from modules/blog/client-react/components/BlogRefCard.jsx rename to modules/blog/client-react/components/BlogRefCardComponent.jsx index 6097fc3bf..59e14d6ed 100644 --- a/modules/blog/client-react/components/BlogRefCard.jsx +++ b/modules/blog/client-react/components/BlogRefCardComponent.jsx @@ -5,7 +5,7 @@ import { Col, Row } from '@gqlapp/look-client-react'; import { Card, Avatar, Button } from 'antd'; -const BlogRefCard = ({ user, model }) => { +const BlogRefCardComponent = ({ user, model }) => { return ( @@ -39,11 +39,11 @@ const BlogRefCard = ({ user, model }) => { ); }; -BlogRefCard.propTypes = { +BlogRefCardComponent.propTypes = { model: PropTypes.object, user: PropTypes.object, // setClap: PropTypes.func, t: PropTypes.func }; -export default translate('blog')(BlogRefCard); +export default translate('blog')(BlogRefCardComponent); diff --git a/modules/blog/client-react/components/MiniBlogsCardComponent.jsx b/modules/blog/client-react/components/MiniBlogsCardComponent.jsx new file mode 100644 index 000000000..055ffa080 --- /dev/null +++ b/modules/blog/client-react/components/MiniBlogsCardComponent.jsx @@ -0,0 +1,85 @@ +import React, { useState } from 'react'; +import PropTypes from 'prop-types'; +import { translate } from '@gqlapp/i18n-client-react'; +import { Col, Row } from '@gqlapp/look-client-react'; + +import { Card, Avatar, Button, Divider, Tooltip } from 'antd'; + +const { Meta } = Card; +const BlogRefCardComponent = ({ blog }) => { + const [clap, increClap] = useState(blog.claps); + const [clapFlag, increclapFlag] = useState(blog.clapFlag); + const setClap = () => { + increClap(clap + (!clapFlag ? 1 : -1)); + increclapFlag(!clapFlag); + }; + + const blogData = () => { + return ( + <> + +

+ + {blog.title.substring(0, 24)} + {blog.title.length > 24 && '...'} + +

+
+
+ } + title={ + + {`${blog.author.firstname} ${blog.author.lastname} `} + ({blog.author.username}) + + } + description={{`${blog.createdAt} - ${blog.readTime} read`}} + /> + + + @@ -87,6 +90,7 @@ const BlogFormWithFormik = withFormik({ title: props.blog && props.blog.title, image: props.blog && props.blog.image, content: props.blog && props.blog.content, + tags: props.blog && props.blog.tags.length > 1 ? props.blog.tags : [], modelId: props.blog && props.blog.model ? props.blog.model.id : null }), validate: values => validate(values, BlogFormSchema), diff --git a/modules/look/client-react/ui-antd/components/RenderTagsField.jsx b/modules/look/client-react/ui-antd/components/RenderTagsField.jsx new file mode 100644 index 000000000..2f5785ee8 --- /dev/null +++ b/modules/look/client-react/ui-antd/components/RenderTagsField.jsx @@ -0,0 +1,96 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { Tag, Input, Icon, Form } from 'antd'; + +const FormItem = Form.Item; +export default class RenderTagsField extends React.Component { + state = { + tags: this.props.tagVal, + inputVisible: false, + inputValue: '' + }; + + handleClose = removedTag => { + const tags = this.state.tags.filter(tag => tag !== removedTag); + this.setState({ tags }); + this.props.handleTags(tags); + }; + + showInput = () => { + this.setState({ inputVisible: true }, () => this.input.focus()); + }; + + handleInputChange = e => { + this.setState({ inputValue: e.target.value }); + }; + + handleInputConfirm = () => { + const { inputValue } = this.state; + let { tags } = this.state; + if (inputValue && tags.indexOf(inputValue) === -1) { + tags = [...tags, inputValue]; + } + this.props.handleTags(tags); + this.setState({ + tags, + inputVisible: false, + inputValue: '' + }); + }; + + saveInputRef = input => (this.input = input); + + forMap = tag => { + const tagElem = ( + { + e.preventDefault(); + this.handleClose(tag); + }} + > + {tag} + + ); + return ( + + {tagElem} + + ); + }; + + render() { + const { tags, inputVisible, inputValue } = this.state; + const tagChild = tags.map(this.forMap); + return ( +
+ +
{tagChild}
+ {inputVisible && ( + + )} + {!inputVisible && ( + + New Tag + + )} +
+
+ ); + } +} + +RenderTagsField.propTypes = { + label: PropTypes.string, + handleTags: PropTypes.func, + tagVal: PropTypes.array +}; diff --git a/modules/look/client-react/ui-antd/components/index.js b/modules/look/client-react/ui-antd/components/index.js index d2a1e67bc..02ea0b599 100644 --- a/modules/look/client-react/ui-antd/components/index.js +++ b/modules/look/client-react/ui-antd/components/index.js @@ -13,6 +13,7 @@ export { default as RenderAddress } from './RenderAddress'; export { default as RenderCheckBox } from './RenderCheckBox'; export { default as RenderUpload } from './RenderUpload'; export { default as RenderUploadMultiple } from './RenderUploadMultiple'; +export { default as RenderTagsField } from './RenderTagsField'; export { default as Alert } from './Alert'; export { default as Container } from './Container'; export { default as Row } from './Row'; From 059d12473227ae868e70c44e76fc82b516dea56c Mon Sep 17 00:00:00 2001 From: Bishal Deb Date: Fri, 27 Dec 2019 00:37:31 +0530 Subject: [PATCH 015/100] Status added and blog form completed --- .../blog/client-react/components/BlogFormCmponent.jsx | 11 +++++++++++ modules/blog/client-react/constants/index.js | 7 +++++++ 2 files changed, 18 insertions(+) create mode 100644 modules/blog/client-react/constants/index.js diff --git a/modules/blog/client-react/components/BlogFormCmponent.jsx b/modules/blog/client-react/components/BlogFormCmponent.jsx index 8011e52d1..f06d90f27 100644 --- a/modules/blog/client-react/components/BlogFormCmponent.jsx +++ b/modules/blog/client-react/components/BlogFormCmponent.jsx @@ -18,9 +18,12 @@ import { } from '@gqlapp/look-client-react'; import { Select } from 'antd'; +import { statusForm } from '../constants'; + const BlogFormSchema = { title: [required], image: [required], + status: [required], content: [required], modelId: [required] }; @@ -64,6 +67,13 @@ const BlogForm = ({ values, handleSubmit, submitting, cardTitle, model }) => { value={values.content} /> + + {statusForm.map((item, idx) => ( + + {item.text} + + ))} + @@ -88,6 +98,7 @@ BlogForm.propTypes = { const BlogFormWithFormik = withFormik({ mapPropsToValues: props => ({ title: props.blog && props.blog.title, + status: props.blog && props.blog.status, image: props.blog && props.blog.image, content: props.blog && props.blog.content, tags: props.blog && props.blog.tags.length > 1 ? props.blog.tags : [], diff --git a/modules/blog/client-react/constants/index.js b/modules/blog/client-react/constants/index.js new file mode 100644 index 000000000..602b8e870 --- /dev/null +++ b/modules/blog/client-react/constants/index.js @@ -0,0 +1,7 @@ +export const status = ['draft', 'published', 'disabled']; + +export const statusForm = [ + { key: status[0], text: 'Save it as draft for further edits' }, + { key: status[1], text: 'The blog will be published on submit' }, + { key: status[2], text: 'Keep it disabled for now and publish later' } +]; From 36cd35396ead3a699cd10d69cbd3f03e78d0ce38 Mon Sep 17 00:00:00 2001 From: Bishal Deb Date: Sat, 28 Dec 2019 18:51:31 +0530 Subject: [PATCH 016/100] Bookmark and dropdown added. --- .../components/MiniBlogsCardComponent.jsx | 55 ++++++++++++++----- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/modules/blog/client-react/components/MiniBlogsCardComponent.jsx b/modules/blog/client-react/components/MiniBlogsCardComponent.jsx index 055ffa080..a138b1879 100644 --- a/modules/blog/client-react/components/MiniBlogsCardComponent.jsx +++ b/modules/blog/client-react/components/MiniBlogsCardComponent.jsx @@ -1,11 +1,12 @@ import React, { useState } from 'react'; import PropTypes from 'prop-types'; import { translate } from '@gqlapp/i18n-client-react'; -import { Col, Row } from '@gqlapp/look-client-react'; +// import { } from "@gqlapp/look-client-react"; -import { Card, Avatar, Button, Divider, Tooltip } from 'antd'; +import { Menu, Col, Row, Card, Avatar, Button, Divider, Tooltip, Icon, Dropdown } from 'antd'; const { Meta } = Card; + const BlogRefCardComponent = ({ blog }) => { const [clap, increClap] = useState(blog.claps); const [clapFlag, increclapFlag] = useState(blog.clapFlag); @@ -14,6 +15,13 @@ const BlogRefCardComponent = ({ blog }) => { increclapFlag(!clapFlag); }; + const menu = ( + + Share the blog + Report the blog + + ); + const blogData = () => { return ( <> @@ -38,16 +46,35 @@ const BlogRefCardComponent = ({ blog }) => { /> - + + + + + +
+ + + {blog.status == status[1] && ( + +
+ + + )} +
+ + ); + }; + const blogImage = () => {blog.title}; + return ( +
+ + + {blogData()} + + + + + + +

{`Category: ${blog.model.name}`}

+ {blogData()} + + + {blogImage()} + +
+
+ +
+ ); +}; + +MyMiniBlogsCardComponent.propTypes = { + blog: PropTypes.object, + t: PropTypes.func +}; + +export default translate('blog')(MyMiniBlogsCardComponent); diff --git a/modules/blog/client-react/containers/Blog.jsx b/modules/blog/client-react/containers/Blog.jsx index fb78a1adb..aaec52ac5 100644 --- a/modules/blog/client-react/containers/Blog.jsx +++ b/modules/blog/client-react/containers/Blog.jsx @@ -5,7 +5,7 @@ import { translate } from '@gqlapp/i18n-client-react'; import { blog, moreBlogs } from '../demoData'; import BlogView from '../components/BlogView'; -class NewBlog extends React.Component { +class Blog extends React.Component { state = { blog, moreBlogs }; setClap = () => { @@ -23,4 +23,4 @@ class NewBlog extends React.Component { } } -export default translate('blog')(NewBlog); +export default translate('blog')(Blog); diff --git a/modules/blog/client-react/containers/MyBlogs.jsx b/modules/blog/client-react/containers/MyBlogs.jsx new file mode 100644 index 000000000..22cf1b60e --- /dev/null +++ b/modules/blog/client-react/containers/MyBlogs.jsx @@ -0,0 +1,14 @@ +import React from 'react'; + +import { translate } from '@gqlapp/i18n-client-react'; +// import { message } from 'antd'; +import { moreBlogs } from '../demoData'; +import MyBlogsView from '../components/MyBlogsView'; + +class MyBlogs extends React.Component { + render() { + return ; + } +} + +export default translate('blog')(MyBlogs); diff --git a/modules/blog/client-react/containers/Myblogs.jsx b/modules/blog/client-react/containers/Myblogs.jsx deleted file mode 100644 index fb78a1adb..000000000 --- a/modules/blog/client-react/containers/Myblogs.jsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react'; - -import { translate } from '@gqlapp/i18n-client-react'; -// import { message } from 'antd'; -import { blog, moreBlogs } from '../demoData'; -import BlogView from '../components/BlogView'; - -class NewBlog extends React.Component { - state = { blog, moreBlogs }; - - setClap = () => { - let val = !this.state.blog.clapFlag; - let clap = this.state.blog.claps + (val ? 1 : -1); - let tempBlog = this.state.blog; - tempBlog.clapFlag = val; - - tempBlog.claps = clap; - console.log(tempBlog, blog); - this.setState({ blog: tempBlog }); - }; - render() { - return ; - } -} - -export default translate('blog')(NewBlog); diff --git a/modules/blog/client-react/demoData/index.jsx b/modules/blog/client-react/demoData/index.jsx index afc17faf2..d664876a3 100644 --- a/modules/blog/client-react/demoData/index.jsx +++ b/modules/blog/client-react/demoData/index.jsx @@ -1,3 +1,5 @@ +import { status } from '../constants'; + export const blog = { id: 1, title: 'Boruto', @@ -49,6 +51,7 @@ export const moreBlogs = [ lastname: 'Singh', username: 'PCTB' }, + status: status[0], createdAt: '2013-02-10', readTime: '15 min', claps: 136, @@ -69,6 +72,7 @@ export const moreBlogs = [ lastname: 'Roy', username: 'runankaroy' }, + status: status[2], createdAt: '2011-11-10', readTime: '2 min', claps: 15, @@ -89,6 +93,7 @@ export const moreBlogs = [ lastname: 'Deka', username: 'ananD' }, + status: status[1], createdAt: '2019-11-10', readTime: '7 min', claps: 12, diff --git a/modules/blog/client-react/index.tsx b/modules/blog/client-react/index.tsx index d3e7f305a..0e695aff8 100644 --- a/modules/blog/client-react/index.tsx +++ b/modules/blog/client-react/index.tsx @@ -26,7 +26,7 @@ const NavLinkMyBookmarksWithI18n = translate('blog')(({ t }: { t: TranslateFunct export default new ClientModule({ route: [ import('./containers/NewBlog').then(c => c.default))} />, - import('./containers/Myblogs').then(c => c.default))} />, + import('./containers/MyBlogs').then(c => c.default))} />, Date: Sat, 28 Dec 2019 21:56:08 +0530 Subject: [PATCH 019/100] Some changes. --- .../components/MiniBlogsCardComponent.jsx | 9 ++++---- .../components/MyMiniBlogsCardComponent.jsx | 8 +++---- modules/blog/client-react/demoData/index.jsx | 21 +++++++++++++++++++ 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/modules/blog/client-react/components/MiniBlogsCardComponent.jsx b/modules/blog/client-react/components/MiniBlogsCardComponent.jsx index fa57ad078..fe0624d2c 100644 --- a/modules/blog/client-react/components/MiniBlogsCardComponent.jsx +++ b/modules/blog/client-react/components/MiniBlogsCardComponent.jsx @@ -81,21 +81,22 @@ const MiniBlogsCardComponent = ({ blog, moreFlag }) => { }; const blogImage = () => {blog.title}; return ( -
+
{blogData()} - + -

{`${moreFlag == false ? 'More from' : 'Category:'} ${blog.model.name}`}

+

{`${moreFlag == true ? 'More from' : 'Category:'} ${blog.model.name}`}

{blogData()} diff --git a/modules/blog/client-react/components/MyMiniBlogsCardComponent.jsx b/modules/blog/client-react/components/MyMiniBlogsCardComponent.jsx index c6689e503..e70ede477 100644 --- a/modules/blog/client-react/components/MyMiniBlogsCardComponent.jsx +++ b/modules/blog/client-react/components/MyMiniBlogsCardComponent.jsx @@ -77,14 +77,14 @@ const MyMiniBlogsCardComponent = ({ blog }) => { }; const blogImage = () => {blog.title}; return ( -
+
- - {blogData()} + +
{blogData()}
- +

{`Category: ${blog.model.name}`}

diff --git a/modules/blog/client-react/demoData/index.jsx b/modules/blog/client-react/demoData/index.jsx index d664876a3..32e6d173a 100644 --- a/modules/blog/client-react/demoData/index.jsx +++ b/modules/blog/client-react/demoData/index.jsx @@ -98,6 +98,27 @@ export const moreBlogs = [ readTime: '7 min', claps: 12, clapFlag: true + }, + { + id: 5, + title: 'Sarada', + image: + 'data:image/jpeg;base64,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', + model: { + id: 1, + name: 'Anime' + }, + author: { + image: 'https://miro.medium.com/fit/c/40/40/2*_KGzadiy9s83D4vzhsCyyg.png', + firstname: 'Prajjwal', + lastname: 'Singh', + username: 'PCTB' + }, + status: status[1], + createdAt: '2013-02-10', + readTime: '15 min', + claps: 136, + clapFlag: true } ]; From a3bc24244a2a0fbf9cbe586681002cb29a14c0fc Mon Sep 17 00:00:00 2001 From: Bishal Deb Date: Sat, 28 Dec 2019 22:47:33 +0530 Subject: [PATCH 020/100] Some changes 2.0 --- .../client-react/components/MyMiniBlogsCardComponent.jsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/blog/client-react/components/MyMiniBlogsCardComponent.jsx b/modules/blog/client-react/components/MyMiniBlogsCardComponent.jsx index e70ede477..169fda07f 100644 --- a/modules/blog/client-react/components/MyMiniBlogsCardComponent.jsx +++ b/modules/blog/client-react/components/MyMiniBlogsCardComponent.jsx @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { translate } from '@gqlapp/i18n-client-react'; -import { Col, Row, Card, Button, Tooltip } from 'antd'; +import { Col, Row, Card, Button, Tooltip, Alert } from 'antd'; import { status } from '../constants'; const MyMiniBlogsCardComponent = ({ blog }) => { @@ -43,6 +43,12 @@ const MyMiniBlogsCardComponent = ({ blog }) => { Delete + {blog.status != status[1] && ( + +
+ + + )}
@@ -81,11 +80,16 @@ const MyMiniBlogsCardComponent = ({ blog }) => { ); }; - const blogImage = () => {blog.title}; + return (
- + } + style={{ marginBottom: '20px' }} + >
{blogData()}
@@ -97,7 +101,7 @@ const MyMiniBlogsCardComponent = ({ blog }) => { {blogData()} - {blogImage()} +
diff --git a/modules/blog/client-react/index.tsx b/modules/blog/client-react/index.tsx index 3fc93f273..aa9748210 100644 --- a/modules/blog/client-react/index.tsx +++ b/modules/blog/client-react/index.tsx @@ -18,6 +18,11 @@ const NavLinkMyBlogsWithI18n = translate('blog')(({ t }: { t: TranslateFunction {'My Blogs'} )); +const NavLinkBlogWithI18n = translate('blog')(({ t }: { t: TranslateFunction }) => ( + + {'Blogs'} + +)); const NavLinkMyBookmarksWithI18n = translate('blog')(({ t }: { t: TranslateFunction }) => ( {'My Bookmarks'} @@ -43,6 +48,9 @@ export default new ClientModule({ , + + + , , From 70b3250e55df8c807402ea827fac67b24d665efb Mon Sep 17 00:00:00 2001 From: Bishal Deb Date: Wed, 1 Jan 2020 18:29:36 +0530 Subject: [PATCH 023/100] Blog Actions component extracted. --- .../components/BlogActionsComponent.jsx | 59 +++++++++++++++++++ .../client-react/components/BlogComponent.jsx | 21 ++----- .../blog/client-react/components/BlogView.jsx | 1 - .../components/MiniBlogsCardComponent.jsx | 51 ++-------------- modules/blog/client-react/containers/Blog.jsx | 14 +---- 5 files changed, 68 insertions(+), 78 deletions(-) create mode 100644 modules/blog/client-react/components/BlogActionsComponent.jsx diff --git a/modules/blog/client-react/components/BlogActionsComponent.jsx b/modules/blog/client-react/components/BlogActionsComponent.jsx new file mode 100644 index 000000000..22ac75c1e --- /dev/null +++ b/modules/blog/client-react/components/BlogActionsComponent.jsx @@ -0,0 +1,59 @@ +import React, { useState } from 'react'; +import PropTypes from 'prop-types'; +import { Menu, Col, Row, Button, Tooltip, Icon, Dropdown } from 'antd'; + +const BlogActionsComponent = ({ blog }) => { + const [clap, increClap] = useState(blog.claps); + const [clapFlag, increclapFlag] = useState(blog.clapFlag); + const setClap = () => { + increClap(clap + (!clapFlag ? 1 : -1)); + increclapFlag(!clapFlag); + }; + + const menu = ( + + Share the blog + Report the blog + + ); + + return ( + + + + + + ); +}; +CommentFormComponent.propTypes = { + handleSubmit: PropTypes.func, + onSubmit: PropTypes.func, + values: PropTypes.object, + errors: PropTypes.object, + comment: PropTypes.object, + t: PropTypes.func +}; +const CommentFormWithFormik = withFormik({ + enableReinitialize: true, + mapPropsToValues: props => ({ + content: props.comment && props.comment.content + }), + async handleSubmit( + values + // { + // setErrors, + // props: { onSubmit } + // } + ) { + // message.loading("Please wait...", 0); + console.log(values); + // onSubmit(values).catch(e => { + // if (isFormError(e)) { + // setErrors(e.errors); + // } else { + // throw e; + // } + // }); + }, + validate: values => validate(values, CommentFormComponentSchema), + displayName: 'CommentForm ' // helps with React DevTools +}); + +export default translate('liveSearch')(CommentFormWithFormik(CommentFormComponent)); diff --git a/modules/comment/client-react/components/CommentSectionComponent.jsx b/modules/comment/client-react/components/CommentSectionComponent.jsx index a67d072a9..3a54efa2a 100644 --- a/modules/comment/client-react/components/CommentSectionComponent.jsx +++ b/modules/comment/client-react/components/CommentSectionComponent.jsx @@ -16,11 +16,7 @@ const CommentSectionComponent = props => { {flag ? ( {props.header}} key="1"> - - - - - + ) : ( diff --git a/modules/comment/client-react/containers/CommentData.jsx b/modules/comment/client-react/containers/CommentData.jsx index 172bee857..59e359664 100644 --- a/modules/comment/client-react/containers/CommentData.jsx +++ b/modules/comment/client-react/containers/CommentData.jsx @@ -3,10 +3,12 @@ import React from 'react'; import { translate } from '@gqlapp/i18n-client-react'; // import { message } from 'antd'; import { commentData } from '../demoData'; -import CommentDataView from '../components/CommentDataView'; +import CommentDataComponent from '../components/CommentDataComponent'; class CommentData extends React.Component { - state = commentData; + state = { + comments: [commentData, commentData, commentData, commentData, commentData] + }; like = () => { this.setState({ @@ -25,7 +27,9 @@ class CommentData extends React.Component { }; render() { - return ; + return ( + + ); } } diff --git a/modules/comment/client-react/demoData/index.jsx b/modules/comment/client-react/demoData/index.jsx index 40fafd91a..b9dc0b858 100644 --- a/modules/comment/client-react/demoData/index.jsx +++ b/modules/comment/client-react/demoData/index.jsx @@ -11,7 +11,8 @@ export const commentData = { time: '2020-01-04 12:33:12', likes: 0, dislikes: 0, - action: null + action: null, + replies: [] }; export const user = { From a199901e2a4b1a6439243d6f776e838557b12817 Mon Sep 17 00:00:00 2001 From: Bishal Deb Date: Sat, 11 Jan 2020 00:50:53 +0530 Subject: [PATCH 031/100] Add and Delete Comment added and working. --- .../components/CommentComponent.jsx | 12 ++-- .../components/CommentDataComponent.jsx | 9 ++- .../components/CommentFormComponent.jsx | 26 +++---- .../client-react/containers/CommentData.jsx | 47 +++++++++++-- .../comment/client-react/demoData/index.jsx | 70 +++++++++++++++++++ 5 files changed, 136 insertions(+), 28 deletions(-) diff --git a/modules/comment/client-react/components/CommentComponent.jsx b/modules/comment/client-react/components/CommentComponent.jsx index 1112169b4..36dbcaf9c 100644 --- a/modules/comment/client-react/components/CommentComponent.jsx +++ b/modules/comment/client-react/components/CommentComponent.jsx @@ -5,8 +5,8 @@ import moment from 'moment'; export default class CommentDataComponent extends React.Component { render() { - const { likes, dislikes, action, content, time, user } = this.props.comment; - const { like, dislike, children } = this.props; + const { likes, dislikes, action, content, time, user, id } = this.props.comment; + const { like, dislike, children, deleteComment } = this.props; const actions = [ @@ -15,13 +15,16 @@ export default class CommentDataComponent extends React.Component { {likes} , - + {dislikes} , - Reply + Reply, + deleteComment(id)}> + Delete + ]; return ( @@ -46,5 +49,6 @@ CommentDataComponent.propTypes = { comment: PropTypes.object, children: PropTypes.object, like: PropTypes.func, + deleteComment: PropTypes.func, dislike: PropTypes.func }; diff --git a/modules/comment/client-react/components/CommentDataComponent.jsx b/modules/comment/client-react/components/CommentDataComponent.jsx index 5188655a1..e735521d9 100644 --- a/modules/comment/client-react/components/CommentDataComponent.jsx +++ b/modules/comment/client-react/components/CommentDataComponent.jsx @@ -13,9 +13,13 @@ const CommentDataComponent = props => { {flag ? ( <> - + {props.comments.map(item => ( - + + {item.replies.map(reply => ( + + ))} + ))} ) : ( @@ -27,6 +31,7 @@ const CommentDataComponent = props => { CommentDataComponent.propTypes = { t: PropTypes.func, + addComment: PropTypes.func, comments: PropTypes.array }; diff --git a/modules/comment/client-react/components/CommentFormComponent.jsx b/modules/comment/client-react/components/CommentFormComponent.jsx index 54277708a..b09dd7b72 100644 --- a/modules/comment/client-react/components/CommentFormComponent.jsx +++ b/modules/comment/client-react/components/CommentFormComponent.jsx @@ -1,13 +1,10 @@ import React from 'react'; import PropTypes from 'prop-types'; import { withFormik } from 'formik'; -import { - // isFormError, - FieldAdapter as Field -} from '@gqlapp/forms-client-react'; +import { FieldAdapter as Field } from '@gqlapp/forms-client-react'; import { translate } from '@gqlapp/i18n-client-react'; import { required, validate } from '@gqlapp/validation-common-react'; -// import { message } from 'antd'; +import { message } from 'antd'; import { Form, RenderField, Button, Alert } from '@gqlapp/look-client-react'; const CommentFormComponentSchema = { @@ -39,21 +36,14 @@ const CommentFormWithFormik = withFormik({ content: props.comment && props.comment.content }), async handleSubmit( - values - // { - // setErrors, - // props: { onSubmit } - // } + values, + { + props: { onSubmit } + } ) { - // message.loading("Please wait...", 0); + message.loading('Please wait...', 0); console.log(values); - // onSubmit(values).catch(e => { - // if (isFormError(e)) { - // setErrors(e.errors); - // } else { - // throw e; - // } - // }); + onSubmit(values); }, validate: values => validate(values, CommentFormComponentSchema), displayName: 'CommentForm ' // helps with React DevTools diff --git a/modules/comment/client-react/containers/CommentData.jsx b/modules/comment/client-react/containers/CommentData.jsx index 59e359664..299edb1cf 100644 --- a/modules/comment/client-react/containers/CommentData.jsx +++ b/modules/comment/client-react/containers/CommentData.jsx @@ -1,13 +1,15 @@ import React from 'react'; // import PropTypes from "prop-types"; import { translate } from '@gqlapp/i18n-client-react'; -// import { message } from 'antd'; -import { commentData } from '../demoData'; +import { message } from 'antd'; +import moment from 'moment'; +import { comments, user } from '../demoData'; import CommentDataComponent from '../components/CommentDataComponent'; class CommentData extends React.Component { state = { - comments: [commentData, commentData, commentData, commentData, commentData] + comments: comments, + count: 10 }; like = () => { @@ -26,9 +28,46 @@ class CommentData extends React.Component { }); }; + addComment = val => { + let commentContent = { + id: this.state.count + 1, + user: user, + content: val.content, + time: moment().format('YYYY-MM-DD HH:mm:ss'), + likes: 0, + dislikes: 0, + action: null, + replies: [] + }; + if (val.id) { + console.log('Doing Nothing!'); + } else { + let tempCom = this.state.comments; + tempCom.push(commentContent); + this.setState({ comments: tempCom, count: this.state.count + 1 }); + } + message.destroy(); + }; + + deleteComment = id => { + // if (val.id) { + // } else { + let tempCom = this.state.comments.filter(item => item.id !== id); + this.setState({ comments: tempCom }); + // } + message.destroy(); + }; + render() { return ( - + ); } } diff --git a/modules/comment/client-react/demoData/index.jsx b/modules/comment/client-react/demoData/index.jsx index b9dc0b858..749e1bbc0 100644 --- a/modules/comment/client-react/demoData/index.jsx +++ b/modules/comment/client-react/demoData/index.jsx @@ -15,6 +15,76 @@ export const commentData = { replies: [] }; +export const comments = [ + { + user: { + image: 'https://miro.medium.com/fit/c/40/40/2*_KGzadiy9s83D4vzhsCyyg.png', + firstname: 'Bishal', + lastname: 'Deb', + username: 'Zalophus1', + desc: 'Just another normal human being here!' + }, + id: 1, + content: + 'We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.', + time: '2020-01-04 12:33:12', + likes: 0, + dislikes: 0, + action: null, + replies: [] + }, + { + user: { + image: 'https://miro.medium.com/fit/c/40/40/2*_KGzadiy9s83D4vzhsCyyg.png', + firstname: 'Bishal', + lastname: 'Deb', + username: 'Zalophus4', + desc: 'Just another normal human being here!' + }, + id: 4, + content: + 'We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.', + time: '2020-01-04 12:33:12', + likes: 0, + dislikes: 0, + action: null, + replies: [ + { + user: { + image: 'https://miro.medium.com/fit/c/40/40/2*_KGzadiy9s83D4vzhsCyyg.png', + firstname: 'Bishal', + lastname: 'Deb', + username: 'Zalophus3', + desc: 'Just another normal human being here!' + }, + id: 5, + content: + 'We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.', + time: '2020-01-04 12:33:12', + likes: 0, + dislikes: 0, + action: null + }, + { + user: { + image: 'https://miro.medium.com/fit/c/40/40/2*_KGzadiy9s83D4vzhsCyyg.png', + firstname: 'Bishal', + lastname: 'Deb', + username: 'Zalophus4', + desc: 'Just another normal human being here!' + }, + id: 6, + content: + 'We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.', + time: '2020-01-04 12:33:12', + likes: 0, + dislikes: 0, + action: null + } + ] + } +]; + export const user = { image: 'https://miro.medium.com/fit/c/40/40/2*_KGzadiy9s83D4vzhsCyyg.png', firstname: 'Bishal', From 8a1f7187044eb368a88960671c0e33f675dcd5f5 Mon Sep 17 00:00:00 2001 From: Bishal Deb Date: Sun, 12 Jan 2020 19:10:24 +0530 Subject: [PATCH 032/100] Comment modal added. --- .../components/CommentComponent.jsx | 19 +++++++-- .../components/CommentDataComponent.jsx | 14 ++++++- .../components/CommentFormComponent.jsx | 41 ++++++++++++++----- .../ui-antd/components/RenderField.jsx | 5 ++- 4 files changed, 60 insertions(+), 19 deletions(-) diff --git a/modules/comment/client-react/components/CommentComponent.jsx b/modules/comment/client-react/components/CommentComponent.jsx index 36dbcaf9c..b7ba51dd8 100644 --- a/modules/comment/client-react/components/CommentComponent.jsx +++ b/modules/comment/client-react/components/CommentComponent.jsx @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Comment, Icon, Tooltip, Avatar } from 'antd'; +import { Comment, Icon, Tooltip, Avatar, Menu, Dropdown } from 'antd'; import moment from 'moment'; export default class CommentDataComponent extends React.Component { @@ -8,6 +8,15 @@ export default class CommentDataComponent extends React.Component { const { likes, dislikes, action, content, time, user, id } = this.props.comment; const { like, dislike, children, deleteComment } = this.props; + const menu = ( + + Edit + deleteComment(id)}> + Delete + + + ); + const actions = [ @@ -22,9 +31,11 @@ export default class CommentDataComponent extends React.Component { {dislikes} , Reply, - deleteComment(id)}> - Delete - + + + + + ]; return ( diff --git a/modules/comment/client-react/components/CommentDataComponent.jsx b/modules/comment/client-react/components/CommentDataComponent.jsx index e735521d9..38588bd03 100644 --- a/modules/comment/client-react/components/CommentDataComponent.jsx +++ b/modules/comment/client-react/components/CommentDataComponent.jsx @@ -1,11 +1,12 @@ import React, { useState, useEffect } from 'react'; import PropTypes from 'prop-types'; -import { Loading } from '@gqlapp/look-client-react'; +import { Loading, Button } from '@gqlapp/look-client-react'; import CommentComponent from './CommentComponent'; import CommentFormComponent from './CommentFormComponent'; const CommentDataComponent = props => { const [flag, setflag] = useState(false); + const [modalVisible, setModalVisible] = useState(false); useEffect(() => { setflag(true); }, []); @@ -13,7 +14,16 @@ const CommentDataComponent = props => { {flag ? ( <> - + {' '} + + {props.comments.map(item => ( {item.replies.map(reply => ( diff --git a/modules/comment/client-react/components/CommentFormComponent.jsx b/modules/comment/client-react/components/CommentFormComponent.jsx index b09dd7b72..8fd626b7f 100644 --- a/modules/comment/client-react/components/CommentFormComponent.jsx +++ b/modules/comment/client-react/components/CommentFormComponent.jsx @@ -4,32 +4,50 @@ import { withFormik } from 'formik'; import { FieldAdapter as Field } from '@gqlapp/forms-client-react'; import { translate } from '@gqlapp/i18n-client-react'; import { required, validate } from '@gqlapp/validation-common-react'; -import { message } from 'antd'; +import { message, Modal } from 'antd'; import { Form, RenderField, Button, Alert } from '@gqlapp/look-client-react'; const CommentFormComponentSchema = { content: [required] }; -const CommentFormComponent = ({ values, handleSubmit, errors }) => { +const CommentFormComponent = ({ values, handleSubmit, modalVisible, setModalVisible, errors, title }) => { return ( -
- - {errors && errors.errorMsg && {errors.errorMsg}} - - + setModalVisible(false)} + onCancel={() => setModalVisible(false)} + footer={null} + > +
+ + {errors && errors.errorMsg && {errors.errorMsg}} + + +
); }; CommentFormComponent.propTypes = { handleSubmit: PropTypes.func, onSubmit: PropTypes.func, + setModalVisible: PropTypes.func, values: PropTypes.object, errors: PropTypes.object, comment: PropTypes.object, + title: PropTypes.string, + modalVisible: PropTypes.bool, t: PropTypes.func }; + const CommentFormWithFormik = withFormik({ enableReinitialize: true, mapPropsToValues: props => ({ @@ -38,15 +56,16 @@ const CommentFormWithFormik = withFormik({ async handleSubmit( values, { - props: { onSubmit } + props: { onSubmit, setModalVisible } } ) { message.loading('Please wait...', 0); console.log(values); onSubmit(values); + setModalVisible(false); }, validate: values => validate(values, CommentFormComponentSchema), displayName: 'CommentForm ' // helps with React DevTools }); -export default translate('liveSearch')(CommentFormWithFormik(CommentFormComponent)); +export default translate('comment')(CommentFormWithFormik(CommentFormComponent)); diff --git a/modules/look/client-react/ui-antd/components/RenderField.jsx b/modules/look/client-react/ui-antd/components/RenderField.jsx index dc9d7e84d..49b00b6a3 100644 --- a/modules/look/client-react/ui-antd/components/RenderField.jsx +++ b/modules/look/client-react/ui-antd/components/RenderField.jsx @@ -5,7 +5,7 @@ import { Form, Input } from 'antd'; const FormItem = Form.Item; const { TextArea } = Input; -const RenderField = ({ input, label, type, meta: { touched, error }, placeholder }) => { +const RenderField = ({ rows, input, label, type, meta: { touched, error }, placeholder }) => { let validateStatus = ''; if (touched && error) { validateStatus = 'error'; @@ -14,7 +14,7 @@ const RenderField = ({ input, label, type, meta: { touched, error }, placeholder {type != 'textarea' ? : null} - {type == 'textarea' ?