From f9f6f6fe94550e667c70fedf335777b9409c5ca8 Mon Sep 17 00:00:00 2001 From: Frida Klockmann Date: Thu, 25 Jul 2019 13:25:26 +0200 Subject: [PATCH 1/8] featuredContent on cards --- packages/admin-frontend/pages/_app.js | 4 +- .../admin-frontend/pages/admin/featured.js | 329 +++++++++--------- .../admin-frontend/pages/admin/featuredAdd.js | 54 +++ .../pages/admin/featuredEdit.js | 236 +++++++++++++ 4 files changed, 454 insertions(+), 169 deletions(-) create mode 100644 packages/admin-frontend/pages/admin/featuredAdd.js create mode 100644 packages/admin-frontend/pages/admin/featuredEdit.js diff --git a/packages/admin-frontend/pages/_app.js b/packages/admin-frontend/pages/_app.js index 0ff7cee22..a74b1927e 100644 --- a/packages/admin-frontend/pages/_app.js +++ b/packages/admin-frontend/pages/_app.js @@ -50,9 +50,9 @@ class App extends NextApp { pageProps = await Component.getInitialProps(ctx); } - const userHasAuthToken = hasAuthToken(ctx.req); + const userHasAuthToken = true; // hasAuthToken(ctx.req); - const userHasAdminPrivileges = hasClaim(claims.readAdmin, ctx.req); + const userHasAdminPrivileges = true; //hasClaim(claims.readAdmin, ctx.req); // If we have response object, set a proper HTTP status code if (!userHasAdminPrivileges && ctx.res) { diff --git a/packages/admin-frontend/pages/admin/featured.js b/packages/admin-frontend/pages/admin/featured.js index ddb604e37..08515e03c 100644 --- a/packages/admin-frontend/pages/admin/featured.js +++ b/packages/admin-frontend/pages/admin/featured.js @@ -14,7 +14,11 @@ import { InputLabel, FormControl, TextField, - Typography + Typography, + Card, + CardContent, + CardMedia, + CardActions } from '@material-ui/core'; import { Form, Field, FormSpy } from 'react-final-form'; import { @@ -31,13 +35,16 @@ import Row from '../../components/Row'; import Container from '../../components/Container'; import isEmptyString from '../../lib/isEmptyString'; import type { FeaturedContent, Language } from '../../types'; - +/** @jsx jsx */ +import { css, jsx } from '@emotion/core'; +import FeaturedEdit from './featuredEdit'; +import FeatureAdd from './featuredAdd'; type Props = { languages: Array }; type State = { - featuredContent: ?FeaturedContent, + featuredContentList: Array, selectedLanguage: string, file: ?File }; @@ -52,26 +59,33 @@ export default class EditFeaturedContent extends React.Component { } state = { - featuredContent: null, selectedLanguage: '', croppedParameters: null, - file: null + file: null, + featuredContentList: [] }; getFeaturedContent = async (languageCode: string) => { const featuredContentRes = await fetchFeaturedContent(languageCode); - const featuredContent = featuredContentRes.isOk - ? featuredContentRes.data[0] - : null; + const featContList = []; + let i = 0; + while (true) { + if (featuredContentRes.data[i]) { + featContList.push(featuredContentRes.data[i]); + } else { + break; + } + i++; + } - if (featuredContent) { - if (featuredContent.language.code !== languageCode) { + if (featuredContentRes.isOk) { + if (featContList[0].language.code !== languageCode) { this.setState({ - featuredContent: null + featuredContentList: [] }); } else { this.setState({ - featuredContent: featuredContent + featuredContentList: featContList }); } } @@ -87,20 +101,28 @@ export default class EditFeaturedContent extends React.Component { this.state.selectedLanguage ); if (result.isOk) { - this.setState(prevState => ({ - featuredContent: { ...prevState.featuredContent, id: result.data.id } - })); + this.setState(() => { + const featuredContentList = this.state.featuredContentList.map(item => { + if (item.id === content.id) { + return content; + } else { + return item; + } + }); + return { + featuredContentList + }; + }); } }; - - handleSaveButtonClick = (defaultReturned: boolean) => ( - content: FeaturedContent - ) => { - defaultReturned - ? this.postFeaturedContent(content) - : this.putFeaturedContent(content); - - this.setState({ featuredContent: content }); + postNewFeaturedContent = async (content: FeaturedContent) => { + const result = await saveFeaturedContent( + content, + this.state.selectedLanguage + ); + if (result.isOk) { + this.getFeaturedContent(this.state.selectedLanguage); + } }; handleLanguageSelect = (event: SyntheticInputEvent) => { @@ -111,15 +133,20 @@ export default class EditFeaturedContent extends React.Component { this.getFeaturedContent(event.target.value); }; - deleteFeaturedContent = async (id: number) => { + deleteFeaturedContent = async (id: string) => { await deleteFeaturedContent(id); }; - handleDelete = () => { - if (this.state.featuredContent) { - this.deleteFeaturedContent(this.state.featuredContent.id); - this.setState({ featuredContent: null }); - } + handleDelete = (id: string, index: number) => { + this.deleteFeaturedContent(this.state.featuredContentList[index].id); + this.setState(state => { + const featuredContentList = this.state.featuredContentList.filter( + item => item.id !== id + ); + return { + featuredContentList + }; + }); }; handleOnUpload = ( @@ -139,18 +166,50 @@ export default class EditFeaturedContent extends React.Component { file: event.target.files[0] }); }; + addFeatureContent = () => { + console.log('ADDING'); + }; + handleSaveButtonClick = ( + defaultReturned: boolean, + content: FeaturedContent + ) => { + defaultReturned + ? this.postFeaturedContent(content) + : this.putFeaturedContent(content); + + this.setState(() => { + const featuredContentList = this.state.featuredContentList.map(item => { + if (item.id === content.id) { + return content; + } else { + return item; + } + }); + return { + featuredContentList + }; + }); + }; + + handleSaveButtonClickNew = ( + defaultReturned: boolean, + content: FeaturedContent + ) => { + this.postNewFeaturedContent(content); + }; render() { - const { featuredContent, selectedLanguage } = this.state; + const { selectedLanguage, featuredContentList } = this.state; // If the language of the featured content is different from what we expected to fetch, there is no featured content for that language. A request defaults to english if it does not exist. let defaultReturned = true; if ( - featuredContent && - featuredContent.language && - featuredContent.language.code + featuredContentList[0] && + featuredContentList[0].language && + featuredContentList[0].language.code ) { - defaultReturned = featuredContent.language.code !== selectedLanguage; + defaultReturned = + featuredContentList[0].language.code !== selectedLanguage; } return ( @@ -180,143 +239,79 @@ export default class EditFeaturedContent extends React.Component { ; -
( - - ( - - )} - /> - ( - - )} - /> - ( - <> - - {meta.error && meta.touched && ( - {meta.error} - )} - - )} - /> - -
- ( - <> - - {meta.error && meta.touched && ( - {meta.error} - )} - - )} - /> -
- - or - - this.handleFileChosen(event)} + {featuredContentList.length === 0 && selectedLanguage !== '' ? ( +

+ There is no featured content for the language{' '} + {selectedLanguage} +

+ ) : null} +
+ {featuredContentList.map((content, i) => { + return ( + + - {this.state.file && ( - this.handleOnUpload(url, form.change)} + +

{content.title}

+

{content.description}

+
+ + + Edit + + } + featuredContentList={featuredContentList} + selectedLanguage={selectedLanguage} + i={i} + defaultReturned={defaultReturned} + handleSaveButtonClick={this.handleSaveButtonClick} + handleFileChosen={this.handleFileChosen} + handleOnCancel={this.handleOnCancel} + file={this.state.file} + handleOnUpload={this.handleOnUpload} /> - )} - - - - // $FlowFixMe - values.imageUrl ? ( - - ) : null - } - /> - - - - - )} - /> + + +
+ ); + })} + {selectedLanguage !== '' + ? FeatureAdd( + defaultReturned, + this.handleSaveButtonClickNew, + this.handleFileChosen, + this.handleOnCancel, + this.state.file, + this.handleOnUpload, + this.state.featuredContentList + ) + : null} +
); diff --git a/packages/admin-frontend/pages/admin/featuredAdd.js b/packages/admin-frontend/pages/admin/featuredAdd.js new file mode 100644 index 000000000..fc40a791f --- /dev/null +++ b/packages/admin-frontend/pages/admin/featuredAdd.js @@ -0,0 +1,54 @@ +import React from 'react'; +import { Card } from '@material-ui/core'; +import { Add } from '@material-ui/icons'; +import FeaturedEdit from './featuredEdit'; + +export default function FeatureAdd( + defaultReturned: boolean, + handleSaveButtonClick: any, + handleFileChosen: any, + handleOnCancel: any, + file: any, + handleOnUpload: any, + featuredContentList: Array +) { + return ( + +
+ +

+ ADD +

+
+ + } + i={featuredContentList.length} + featuredContentList={featuredContentList} + defaultReturned={defaultReturned} + handleSaveButtonClick={handleSaveButtonClick} + handleFileChosen={handleFileChosen} + handleOnCancel={handleOnCancel} + file={file} + handleOnUpload={handleOnUpload} + /> + ); +} diff --git a/packages/admin-frontend/pages/admin/featuredEdit.js b/packages/admin-frontend/pages/admin/featuredEdit.js new file mode 100644 index 000000000..1b9c9b000 --- /dev/null +++ b/packages/admin-frontend/pages/admin/featuredEdit.js @@ -0,0 +1,236 @@ +//@flow +import React from 'react'; +import { Button, Dialog, TextField, FormHelperText } from '@material-ui/core'; +import { Form, Field, FormSpy } from 'react-final-form'; +import isEmptyString from '../../lib/isEmptyString'; +import UploadFileDialog from '../../components/UploadFileDialog'; +import Row from '../../components/Row'; +import FeaturedImage from '../../components/FeaturedImage'; +import type { FeaturedContent } from '../../types'; +import { + fetchLanguages, + fetchFeaturedContent, + updateFeaturedContent, + saveFeaturedContent, + deleteFeaturedContent +} from '../../lib/fetch'; + +type Props = { + i: number, + button: any, + featuredContentList: Array, + selectedLanguage: string, + defaultReturned: boolean, + handleSaveButtonClick: any, + handleFileChosen: any, + handleOnCancel: any, + file: any, + handleOnUpload: any +}; +type State = { + open: boolean +}; +function handleValidate(values) { + const errors = {}; + + if (isEmptyString(values.title)) { + errors.title = 'Required'; + } + + if (isEmptyString(values.description)) { + errors.description = 'Required'; + } + + const regex = /http(s)?:\/\/.*/; + if (isEmptyString(values.link) || !values.link.match(regex)) { + errors.link = 'Must be a valid URL e.g "https://digitallibrary.io"'; + } + + if (isEmptyString(values.imageUrl) || !values.imageUrl.match(regex)) { + errors.imageUrl = + 'Must be a valid URL image url e.g "https://images.digitallibrary.io/imageId.png'; + } + + return errors; +} + +export default class FeaturedEdit extends React.Component { + constructor(props: Props) { + super(props); + this.state = { + open: false + }; + } + + handleClickOpen() { + this.setState({ + open: true + }); + } + handleClose() { + this.setState({ + open: false + }); + } + + handleSaveButtonClick = (defaultReturned: boolean) => ( + content: FeaturedContent + ) => { + this.props.handleSaveButtonClick(defaultReturned, content); + this.setState({ open: false }); + }; + render() { + return ( + <> +
{this.props.button}
+ + +
+ <> +
( + + ( + + )} + /> + ( + + )} + /> + ( + <> + + {meta.error && meta.touched && ( + {meta.error} + )} + + )} + /> + + +
+ ( + <> + + {meta.error && meta.touched && ( + + {meta.error} + + )} + + )} + /> +
+ + or + + this.props.handleFileChosen(event)} + /> + + {this.props.file && ( + + this.props.handleOnUpload(url, form.change) + } + /> + )} +
+ + + // $FlowFixMe + values.imageUrl ? ( + + ) : null + } + /> + + + + + )} + /> + +
+
+ + ); + } +} From f8dfd40c82f1d15b644db9025e270a71ed227503 Mon Sep 17 00:00:00 2001 From: Frida Klockmann Date: Fri, 26 Jul 2019 12:26:01 +0200 Subject: [PATCH 2/8] dialogbox on delete++ --- packages/admin-frontend/pages/_app.js | 5 +- .../admin-frontend/pages/admin/featured.js | 133 +++++++++++------- .../admin-frontend/pages/admin/featuredAdd.js | 17 ++- .../pages/admin/featuredEdit.js | 15 +- 4 files changed, 105 insertions(+), 65 deletions(-) diff --git a/packages/admin-frontend/pages/_app.js b/packages/admin-frontend/pages/_app.js index a74b1927e..3072e2313 100644 --- a/packages/admin-frontend/pages/_app.js +++ b/packages/admin-frontend/pages/_app.js @@ -50,9 +50,10 @@ class App extends NextApp { pageProps = await Component.getInitialProps(ctx); } - const userHasAuthToken = true; // hasAuthToken(ctx.req); + const userHasAuthToken = hasAuthToken(ctx.req); //true - const userHasAdminPrivileges = true; //hasClaim(claims.readAdmin, ctx.req); + const userHasAdminPrivileges = hasClaim(claims.readAdmin, ctx.req); //true + console.log(hasAuthToken(ctx.req), hasClaim(claims.readAdmin, ctx.req)); // If we have response object, set a proper HTTP status code if (!userHasAdminPrivileges && ctx.res) { diff --git a/packages/admin-frontend/pages/admin/featured.js b/packages/admin-frontend/pages/admin/featured.js index 08515e03c..4cf9e7a14 100644 --- a/packages/admin-frontend/pages/admin/featured.js +++ b/packages/admin-frontend/pages/admin/featured.js @@ -10,17 +10,18 @@ import * as React from 'react'; import { Select, Button, - FormHelperText, InputLabel, FormControl, - TextField, Typography, Card, CardContent, CardMedia, - CardActions + CardActions, + Dialog, + DialogActions, + DialogContent, + DialogTitle } from '@material-ui/core'; -import { Form, Field, FormSpy } from 'react-final-form'; import { fetchLanguages, fetchFeaturedContent, @@ -28,17 +29,14 @@ import { saveFeaturedContent, deleteFeaturedContent } from '../../lib/fetch'; -import UploadFileDialog from '../../components/UploadFileDialog'; -import FeaturedImage from '../../components/FeaturedImage'; import Layout from '../../components/Layout'; -import Row from '../../components/Row'; import Container from '../../components/Container'; -import isEmptyString from '../../lib/isEmptyString'; import type { FeaturedContent, Language } from '../../types'; /** @jsx jsx */ import { css, jsx } from '@emotion/core'; import FeaturedEdit from './featuredEdit'; import FeatureAdd from './featuredAdd'; + type Props = { languages: Array }; @@ -46,7 +44,10 @@ type Props = { type State = { featuredContentList: Array, selectedLanguage: string, - file: ?File + file: ?File, + openDeleteDialog: boolean, + placementOfSelectedContent: number, + selectedContent: null | FeaturedContent }; export default class EditFeaturedContent extends React.Component { @@ -62,14 +63,17 @@ export default class EditFeaturedContent extends React.Component { selectedLanguage: '', croppedParameters: null, file: null, - featuredContentList: [] + featuredContentList: [], + openDeleteDialog: false, + selectedContent: null, + placementOfSelectedContent: 0 }; getFeaturedContent = async (languageCode: string) => { const featuredContentRes = await fetchFeaturedContent(languageCode); const featContList = []; let i = 0; - while (true) { + while (featuredContentRes.isOk) { if (featuredContentRes.data[i]) { featContList.push(featuredContentRes.data[i]); } else { @@ -133,18 +137,33 @@ export default class EditFeaturedContent extends React.Component { this.getFeaturedContent(event.target.value); }; - deleteFeaturedContent = async (id: string) => { + deleteFeaturedContent = async (id: number) => { await deleteFeaturedContent(id); }; + handleCloseDeleteDialog = () => { + this.setState({ + openDeleteDialog: false, + selectedContent: null + }); + }; - handleDelete = (id: string, index: number) => { + handleOpenDeleteDialog = (content: FeaturedContent, i: number) => { + this.setState({ + openDeleteDialog: true, + selectedContent: content, + placementOfSelectedContent: i + }); + }; + handleDelete = (id: number, index: number) => { this.deleteFeaturedContent(this.state.featuredContentList[index].id); this.setState(state => { const featuredContentList = this.state.featuredContentList.filter( item => item.id !== id ); return { - featuredContentList + featuredContentList, + openDeleteDialog: false, + selectedContent: null }; }); }; @@ -166,9 +185,6 @@ export default class EditFeaturedContent extends React.Component { file: event.target.files[0] }); }; - addFeatureContent = () => { - console.log('ADDING'); - }; handleSaveButtonClick = ( defaultReturned: boolean, content: FeaturedContent @@ -198,6 +214,42 @@ export default class EditFeaturedContent extends React.Component { this.postNewFeaturedContent(content); }; + getDialog = () => { + if (this.state.selectedContent) { + const contentId = this.state.selectedContent.id; + return ( + + + + Do you want to delete {this.state.selectedContent.title} form + featured content? + + + + + + + + ); + } + }; + render() { const { selectedLanguage, featuredContentList } = this.state; @@ -261,24 +313,24 @@ export default class EditFeaturedContent extends React.Component { > {featuredContentList.map((content, i) => { return ( - + -

{content.title}

{content.description}

- + - Edit - - } + button={} featuredContentList={featuredContentList} selectedLanguage={selectedLanguage} i={i} @@ -291,8 +343,8 @@ export default class EditFeaturedContent extends React.Component { /> @@ -308,35 +360,14 @@ export default class EditFeaturedContent extends React.Component { this.handleOnCancel, this.state.file, this.handleOnUpload, - this.state.featuredContentList + this.state.featuredContentList, + this.state.selectedLanguage ) : null} + {this.getDialog()} ); } } -function handleValidate(values) { - const errors = {}; - - if (isEmptyString(values.title)) { - errors.title = 'Required'; - } - - if (isEmptyString(values.description)) { - errors.description = 'Required'; - } - - const regex = /http(s)?:\/\/.*/; - if (isEmptyString(values.link) || !values.link.match(regex)) { - errors.link = 'Must be a valid URL e.g "https://digitallibrary.io"'; - } - - if (isEmptyString(values.imageUrl) || !values.imageUrl.match(regex)) { - errors.imageUrl = - 'Must be a valid URL image url e.g "https://images.digitallibrary.io/imageId.png'; - } - - return errors; -} diff --git a/packages/admin-frontend/pages/admin/featuredAdd.js b/packages/admin-frontend/pages/admin/featuredAdd.js index fc40a791f..d8c72a18c 100644 --- a/packages/admin-frontend/pages/admin/featuredAdd.js +++ b/packages/admin-frontend/pages/admin/featuredAdd.js @@ -1,7 +1,9 @@ -import React from 'react'; +//@flow import { Card } from '@material-ui/core'; import { Add } from '@material-ui/icons'; import FeaturedEdit from './featuredEdit'; +/** @jsx jsx */ +import { css, jsx } from '@emotion/core'; export default function FeatureAdd( defaultReturned: boolean, @@ -10,13 +12,21 @@ export default function FeatureAdd( handleOnCancel: any, file: any, handleOnUpload: any, - featuredContentList: Array + featuredContentList: Array, + selectedLanguage: string ) { return (
); } diff --git a/packages/admin-frontend/pages/admin/featuredEdit.js b/packages/admin-frontend/pages/admin/featuredEdit.js index 1b9c9b000..f06bfe68a 100644 --- a/packages/admin-frontend/pages/admin/featuredEdit.js +++ b/packages/admin-frontend/pages/admin/featuredEdit.js @@ -7,13 +7,6 @@ import UploadFileDialog from '../../components/UploadFileDialog'; import Row from '../../components/Row'; import FeaturedImage from '../../components/FeaturedImage'; import type { FeaturedContent } from '../../types'; -import { - fetchLanguages, - fetchFeaturedContent, - updateFeaturedContent, - saveFeaturedContent, - deleteFeaturedContent -} from '../../lib/fetch'; type Props = { i: number, @@ -215,14 +208,18 @@ export default class FeaturedEdit extends React.Component { type="submit" onClick={handleSubmit} > - Save changes + {this.props.featuredContentList.length > this.props.i + ? 'Save changes' + : 'Save'} )} From 00f1b16701f05b29827908bc5cd11a94e44050a6 Mon Sep 17 00:00:00 2001 From: Frida Klockmann Date: Wed, 31 Jul 2019 13:11:01 +0200 Subject: [PATCH 3/8] type on function props --- packages/admin-frontend/pages/_app.js | 6 +- .../admin-frontend/pages/admin/featured.js | 16 +---- .../admin-frontend/pages/admin/featuredAdd.js | 13 +++-- .../pages/admin/featuredEdit.js | 58 ++++++++++--------- 4 files changed, 42 insertions(+), 51 deletions(-) diff --git a/packages/admin-frontend/pages/_app.js b/packages/admin-frontend/pages/_app.js index 3072e2313..8a8d307bf 100644 --- a/packages/admin-frontend/pages/_app.js +++ b/packages/admin-frontend/pages/_app.js @@ -50,10 +50,8 @@ class App extends NextApp { pageProps = await Component.getInitialProps(ctx); } - const userHasAuthToken = hasAuthToken(ctx.req); //true - - const userHasAdminPrivileges = hasClaim(claims.readAdmin, ctx.req); //true - console.log(hasAuthToken(ctx.req), hasClaim(claims.readAdmin, ctx.req)); + const userHasAuthToken = hasAuthToken(ctx.req); + const userHasAdminPrivileges = hasClaim(claims.readAdmin, ctx.req); // If we have response object, set a proper HTTP status code if (!userHasAdminPrivileges && ctx.res) { diff --git a/packages/admin-frontend/pages/admin/featured.js b/packages/admin-frontend/pages/admin/featured.js index 4cf9e7a14..898ccd563 100644 --- a/packages/admin-frontend/pages/admin/featured.js +++ b/packages/admin-frontend/pages/admin/featured.js @@ -71,25 +71,15 @@ export default class EditFeaturedContent extends React.Component { getFeaturedContent = async (languageCode: string) => { const featuredContentRes = await fetchFeaturedContent(languageCode); - const featContList = []; - let i = 0; - while (featuredContentRes.isOk) { - if (featuredContentRes.data[i]) { - featContList.push(featuredContentRes.data[i]); - } else { - break; - } - i++; - } - if (featuredContentRes.isOk) { - if (featContList[0].language.code !== languageCode) { + if (featuredContentRes.isOk && featuredContentRes.data[0]) { + if (featuredContentRes.data[0].language.code !== languageCode) { this.setState({ featuredContentList: [] }); } else { this.setState({ - featuredContentList: featContList + featuredContentList: featuredContentRes.data }); } } diff --git a/packages/admin-frontend/pages/admin/featuredAdd.js b/packages/admin-frontend/pages/admin/featuredAdd.js index d8c72a18c..250df3b9c 100644 --- a/packages/admin-frontend/pages/admin/featuredAdd.js +++ b/packages/admin-frontend/pages/admin/featuredAdd.js @@ -4,15 +4,16 @@ import { Add } from '@material-ui/icons'; import FeaturedEdit from './featuredEdit'; /** @jsx jsx */ import { css, jsx } from '@emotion/core'; +import type { FeaturedContent } from '../../types'; export default function FeatureAdd( defaultReturned: boolean, - handleSaveButtonClick: any, - handleFileChosen: any, - handleOnCancel: any, - file: any, - handleOnUpload: any, - featuredContentList: Array, + handleSaveButtonClick: (boolean, FeaturedContent) => void, + handleFileChosen: (SyntheticInputEvent) => void, + handleOnCancel: () => void, + file: ?File, + handleOnUpload: (string, (string, any) => void) => void, + featuredContentList: Array, selectedLanguage: string ) { return ( diff --git a/packages/admin-frontend/pages/admin/featuredEdit.js b/packages/admin-frontend/pages/admin/featuredEdit.js index f06bfe68a..75fcd14fd 100644 --- a/packages/admin-frontend/pages/admin/featuredEdit.js +++ b/packages/admin-frontend/pages/admin/featuredEdit.js @@ -11,14 +11,14 @@ import type { FeaturedContent } from '../../types'; type Props = { i: number, button: any, - featuredContentList: Array, + featuredContentList: Array, selectedLanguage: string, defaultReturned: boolean, - handleSaveButtonClick: any, - handleFileChosen: any, - handleOnCancel: any, - file: any, - handleOnUpload: any + handleSaveButtonClick: (boolean, FeaturedContent) => void, + handleFileChosen: (SyntheticInputEvent) => void, + handleOnCancel: () => void, + file: ?File, + handleOnUpload: (string, (string, any) => void) => void }; type State = { open: boolean @@ -55,11 +55,11 @@ export default class FeaturedEdit extends React.Component { }; } - handleClickOpen() { + handleClickOpen = () => { this.setState({ open: true }); - } + }; handleClose() { this.setState({ open: false @@ -73,9 +73,17 @@ export default class FeaturedEdit extends React.Component { this.setState({ open: false }); }; render() { + const { + button, + featuredContentList, + selectedLanguage, + i, + defaultReturned, + file + } = this.props; return ( <> -
{this.props.button}
+
{button}
{
<>
( @@ -101,7 +105,7 @@ export default class FeaturedEdit extends React.Component { fullWidth error={meta.error && meta.touched} margin="normal" - disabled={this.props.selectedLanguage === ''} + disabled={selectedLanguage === ''} label="Title" {...input} /> @@ -114,7 +118,7 @@ export default class FeaturedEdit extends React.Component { fullWidth margin="normal" error={meta.error && meta.touched} - disabled={this.props.selectedLanguage === ''} + disabled={selectedLanguage === ''} label="Description" {...input} multiline @@ -130,7 +134,7 @@ export default class FeaturedEdit extends React.Component { type="url" error={meta.error && meta.touched} margin="normal" - disabled={this.props.selectedLanguage === ''} + disabled={selectedLanguage === ''} label="Link" {...input} /> @@ -155,7 +159,7 @@ export default class FeaturedEdit extends React.Component { margin="normal" error={meta.error && meta.touched} type="url" - disabled={this.props.selectedLanguage === ''} + disabled={selectedLanguage === ''} label="Image Url" {...input} /> @@ -172,18 +176,18 @@ export default class FeaturedEdit extends React.Component { or this.props.handleFileChosen(event)} /> - {this.props.file && ( + {file && ( this.props.handleOnUpload(url, form.change) @@ -208,16 +212,14 @@ export default class FeaturedEdit extends React.Component { type="submit" onClick={handleSubmit} > - {this.props.featuredContentList.length > this.props.i - ? 'Save changes' - : 'Save'} + {featuredContentList.length > i ? 'Save changes' : 'Save'} From df60835f004a471ba85298469216ce4a48948af2 Mon Sep 17 00:00:00 2001 From: camilve Date: Fri, 2 Aug 2019 13:00:23 +0200 Subject: [PATCH 4/8] commit to save --- .../components/EditBook/EditBookForm.js | 80 ++++++++++++++++++- packages/admin-frontend/pages/_app.js | 4 +- 2 files changed, 80 insertions(+), 4 deletions(-) diff --git a/packages/admin-frontend/components/EditBook/EditBookForm.js b/packages/admin-frontend/components/EditBook/EditBookForm.js index 23e68948a..0ee658670 100644 --- a/packages/admin-frontend/components/EditBook/EditBookForm.js +++ b/packages/admin-frontend/components/EditBook/EditBookForm.js @@ -6,7 +6,8 @@ import { Button, TextField, Typography, - Select + Select, + Checkbox } from '@material-ui/core'; import * as React from 'react'; import Link from 'next/link'; @@ -20,14 +21,36 @@ import Container from '../Container'; import Row from '../Row'; import BookCover from './BookCover'; +import { fetchFeaturedContent, deleteFeaturedContent } from '../../lib/fetch'; +import type { FeaturedContent, Language } from '../../types'; + const PUBLISHING_STATUS = ['PUBLISHED', 'FLAGGED', 'UNLISTED']; const PAGE_ORIENTATIONS = ['PORTRAIT', 'LANDSCAPE']; type Props = { book: BookDetails }; +type State = { + featuredContentList: Array, + isFeaturedContent: boolean, + featuredContent: FeaturedContent +}; -export default class EditBookForm extends React.Component { +export default class EditBookForm extends React.Component { + state = { + featuredContentList: [], + isFeaturedContent: false, + featuredContent: { + id: this.props.book.id, + title: this.props.book.title, + description: this.props.book.description, + link: `/${this.props.book.language.code}/books/details/${ + this.props.book.id + }`, + imageUrl: this.props.book.coverImage.url, + language: this.props.book.language + } + }; handleSubmit = (content: BookDetails) => { this.updateBook(content); }; @@ -43,8 +66,55 @@ export default class EditBookForm extends React.Component { } }; + async componentDidMount() { + console.log('test'); + try { + this.inFeaturedContent(); + } catch (error) {} + } + + getFeaturedContent = async (languageCode: string) => { + const featuredContentRes = await fetchFeaturedContent(languageCode); + + if (featuredContentRes.isOk && featuredContentRes.data[0]) { + if (featuredContentRes.data[0].language.code !== languageCode) { + this.setState({ + featuredContentList: [] + }); + } else { + this.setState({ + featuredContentList: featuredContentRes.data + }); + } + } + }; + + inFeaturedContent = async () => { + try { + await this.getFeaturedContent(this.props.book.language.code); + } catch (error) { + console.log(error); + } + console.log(this.state.featuredContentList); + this.state.featuredContentList.some(item => item.id === this.props.book.id) + ? this.setState({ isFeaturedContent: true }) + : this.setState({ isFeaturedContent: false }); + }; + + addRemoveFeaturedContent = async () => { + if (this.state.isFeaturedContent) { + this.setState({ isFeaturedContent: false }); + // await deleteFeaturedContent(this.props.book.id); + } else { + this.setState({ isFeaturedContent: true }); + } + + console.log(this.state.featuredContent); + }; + render() { const book = this.props.book; + console.log(book); return ( {' '} @@ -161,6 +231,12 @@ export default class EditBookForm extends React.Component {
+ )} /> diff --git a/packages/admin-frontend/pages/_app.js b/packages/admin-frontend/pages/_app.js index 8a8d307bf..fe84b2141 100644 --- a/packages/admin-frontend/pages/_app.js +++ b/packages/admin-frontend/pages/_app.js @@ -50,8 +50,8 @@ class App extends NextApp { pageProps = await Component.getInitialProps(ctx); } - const userHasAuthToken = hasAuthToken(ctx.req); - const userHasAdminPrivileges = hasClaim(claims.readAdmin, ctx.req); + const userHasAuthToken = true; //hasAuthToken(ctx.req); + const userHasAdminPrivileges = true; //hasClaim(claims.readAdmin, ctx.req); // If we have response object, set a proper HTTP status code if (!userHasAdminPrivileges && ctx.res) { From c8bd245f0ecab1b872ad05522d86f87679daf415 Mon Sep 17 00:00:00 2001 From: camilve Date: Mon, 5 Aug 2019 11:43:36 +0200 Subject: [PATCH 5/8] save for later --- .../components/EditBook/EditBookForm.js | 130 +++++++++--------- packages/admin-frontend/config.js | 16 ++- packages/admin-frontend/pages/_app.js | 4 +- .../admin-frontend/pages/admin/featured.js | 3 +- 4 files changed, 86 insertions(+), 67 deletions(-) diff --git a/packages/admin-frontend/components/EditBook/EditBookForm.js b/packages/admin-frontend/components/EditBook/EditBookForm.js index 0ee658670..b74f1097f 100644 --- a/packages/admin-frontend/components/EditBook/EditBookForm.js +++ b/packages/admin-frontend/components/EditBook/EditBookForm.js @@ -7,7 +7,7 @@ import { TextField, Typography, Select, - Checkbox + Snackbar } from '@material-ui/core'; import * as React from 'react'; import Link from 'next/link'; @@ -21,8 +21,13 @@ import Container from '../Container'; import Row from '../Row'; import BookCover from './BookCover'; -import { fetchFeaturedContent, deleteFeaturedContent } from '../../lib/fetch'; -import type { FeaturedContent, Language } from '../../types'; +import { saveFeaturedContent } from '../../lib/fetch'; +import type { FeaturedContent } from '../../types'; +import getConfig from 'next/config'; + +const { + publicRuntimeConfig: { baseUrl } +} = getConfig(); const PUBLISHING_STATUS = ['PUBLISHED', 'FLAGGED', 'UNLISTED']; const PAGE_ORIENTATIONS = ['PORTRAIT', 'LANDSCAPE']; @@ -33,23 +38,14 @@ type Props = { type State = { featuredContentList: Array, isFeaturedContent: boolean, - featuredContent: FeaturedContent + snackbarMessage: ?string }; export default class EditBookForm extends React.Component { state = { featuredContentList: [], isFeaturedContent: false, - featuredContent: { - id: this.props.book.id, - title: this.props.book.title, - description: this.props.book.description, - link: `/${this.props.book.language.code}/books/details/${ - this.props.book.id - }`, - imageUrl: this.props.book.coverImage.url, - language: this.props.book.language - } + snackbarMessage: null }; handleSubmit = (content: BookDetails) => { this.updateBook(content); @@ -66,55 +62,50 @@ export default class EditBookForm extends React.Component { } }; - async componentDidMount() { - console.log('test'); - try { - this.inFeaturedContent(); - } catch (error) {} - } - - getFeaturedContent = async (languageCode: string) => { - const featuredContentRes = await fetchFeaturedContent(languageCode); - - if (featuredContentRes.isOk && featuredContentRes.data[0]) { - if (featuredContentRes.data[0].language.code !== languageCode) { - this.setState({ - featuredContentList: [] - }); - } else { - this.setState({ - featuredContentList: featuredContentRes.data - }); - } - } - }; - - inFeaturedContent = async () => { - try { - await this.getFeaturedContent(this.props.book.language.code); - } catch (error) { - console.log(error); - } - console.log(this.state.featuredContentList); - this.state.featuredContentList.some(item => item.id === this.props.book.id) - ? this.setState({ isFeaturedContent: true }) - : this.setState({ isFeaturedContent: false }); - }; - - addRemoveFeaturedContent = async () => { - if (this.state.isFeaturedContent) { - this.setState({ isFeaturedContent: false }); - // await deleteFeaturedContent(this.props.book.id); - } else { - this.setState({ isFeaturedContent: true }); + postNewFeaturedContent = async (content: FeaturedContent) => { + /* let content = { + title: this.props.book.title, + description: this.props.book.description, + imageUrl: + this.props.book.coverImage !== undefined + ? this.props.book.coverImage.url + : 'https://res.cloudinary.com/dwqxoowxi/f_auto,q_auto/e7ad2d851664f1485743e157c46f7142', + link: `${baseUrl}/${this.props.book.language.code}/books/details/${ + this.props.book.id + }` + }; */ + console.log(content); + /* content.title = this.props.book.title; + content.description = this.props.book.description; + content.imageUrl = this.props.book.coverImage.url; + content.link = `${baseUrl}/${this.props.book.language.code}/books/details/${ + this.props.book.id + }`; */ + const result = await saveFeaturedContent( + content, + this.props.book.language.code + ); + if (result.isOk) { + this.setState({ + snackbarMessage: `${this.props.book.title} is added to featured content` + }); } - - console.log(this.state.featuredContent); }; render() { const book = this.props.book; - console.log(book); + const { snackbarMessage } = this.state; + const content = { + title: this.props.book.title, + description: this.props.book.description, + imageUrl: + this.props.book.coverImage !== undefined + ? this.props.book.coverImage.url + : 'https://res.cloudinary.com/dwqxoowxi/f_auto,q_auto/e7ad2d851664f1485743e157c46f7142', + link: `${baseUrl}/${this.props.book.language.code}/books/details/${ + this.props.book.id + }` + }; return ( {' '} @@ -231,16 +222,29 @@ export default class EditBookForm extends React.Component {
- )} /> + this.setState({ snackbarMessage: null })} + ContentProps={{ + 'aria-describedby': 'offline-snack-msg' + }} + message={ + + {snackbarMessage} + + } + /> ); } diff --git a/packages/admin-frontend/config.js b/packages/admin-frontend/config.js index 4f5f8de93..71c68cf1b 100644 --- a/packages/admin-frontend/config.js +++ b/packages/admin-frontend/config.js @@ -46,6 +46,19 @@ const imageApiUrl = () => { } }; +const baseUrl = () => { + switch (GDL_ENVIRONMENT) { + case 'local': + return 'http://localhost:3000'; + case 'dev': + return 'https://test.digitallibrary.io'; + case 'prod': + return 'https://digitallibrary.io'; + default: + return `https://${GDL_ENVIRONMENT}.digitallibrary.io`; + } +}; + module.exports = { serverRuntimeConfig: { port: process.env.ADMIN_FRONTEND_PORT || 3010 @@ -53,6 +66,7 @@ module.exports = { publicRuntimeConfig: { imageApiUrl: imageApiUrl(), bookApiUrl: bookApiUrl(), - statisticsUrl: statisticsUrl() + statisticsUrl: statisticsUrl(), + baseUrl: baseUrl() } }; diff --git a/packages/admin-frontend/pages/_app.js b/packages/admin-frontend/pages/_app.js index fe84b2141..8a8d307bf 100644 --- a/packages/admin-frontend/pages/_app.js +++ b/packages/admin-frontend/pages/_app.js @@ -50,8 +50,8 @@ class App extends NextApp { pageProps = await Component.getInitialProps(ctx); } - const userHasAuthToken = true; //hasAuthToken(ctx.req); - const userHasAdminPrivileges = true; //hasClaim(claims.readAdmin, ctx.req); + const userHasAuthToken = hasAuthToken(ctx.req); + const userHasAdminPrivileges = hasClaim(claims.readAdmin, ctx.req); // If we have response object, set a proper HTTP status code if (!userHasAdminPrivileges && ctx.res) { diff --git a/packages/admin-frontend/pages/admin/featured.js b/packages/admin-frontend/pages/admin/featured.js index 898ccd563..5d32f8374 100644 --- a/packages/admin-frontend/pages/admin/featured.js +++ b/packages/admin-frontend/pages/admin/featured.js @@ -110,6 +110,7 @@ export default class EditFeaturedContent extends React.Component { } }; postNewFeaturedContent = async (content: FeaturedContent) => { + console.log(content); const result = await saveFeaturedContent( content, this.state.selectedLanguage @@ -215,7 +216,7 @@ export default class EditFeaturedContent extends React.Component { > - Do you want to delete {this.state.selectedContent.title} form + Do you want to delete {this.state.selectedContent.title} from featured content? From b3b0e2d5aecee0e2b1b37d55a6df7f2727461538 Mon Sep 17 00:00:00 2001 From: camilve Date: Mon, 5 Aug 2019 14:35:15 +0200 Subject: [PATCH 6/8] add as featured content from book --- .../components/EditBook/EditBookForm.js | 34 +++++-------------- 1 file changed, 8 insertions(+), 26 deletions(-) diff --git a/packages/admin-frontend/components/EditBook/EditBookForm.js b/packages/admin-frontend/components/EditBook/EditBookForm.js index b74f1097f..ceffa77f8 100644 --- a/packages/admin-frontend/components/EditBook/EditBookForm.js +++ b/packages/admin-frontend/components/EditBook/EditBookForm.js @@ -63,24 +63,6 @@ export default class EditBookForm extends React.Component { }; postNewFeaturedContent = async (content: FeaturedContent) => { - /* let content = { - title: this.props.book.title, - description: this.props.book.description, - imageUrl: - this.props.book.coverImage !== undefined - ? this.props.book.coverImage.url - : 'https://res.cloudinary.com/dwqxoowxi/f_auto,q_auto/e7ad2d851664f1485743e157c46f7142', - link: `${baseUrl}/${this.props.book.language.code}/books/details/${ - this.props.book.id - }` - }; */ - console.log(content); - /* content.title = this.props.book.title; - content.description = this.props.book.description; - content.imageUrl = this.props.book.coverImage.url; - content.link = `${baseUrl}/${this.props.book.language.code}/books/details/${ - this.props.book.id - }`; */ const result = await saveFeaturedContent( content, this.props.book.language.code @@ -96,15 +78,16 @@ export default class EditBookForm extends React.Component { const book = this.props.book; const { snackbarMessage } = this.state; const content = { - title: this.props.book.title, - description: this.props.book.description, + id: 0, + title: book.title, + description: book.description, + language: book.language, + //default image (Grace in Space) if book does not have cover image imageUrl: - this.props.book.coverImage !== undefined - ? this.props.book.coverImage.url + book.coverImage !== undefined + ? book.coverImage.url : 'https://res.cloudinary.com/dwqxoowxi/f_auto,q_auto/e7ad2d851664f1485743e157c46f7142', - link: `${baseUrl}/${this.props.book.language.code}/books/details/${ - this.props.book.id - }` + link: `${baseUrl}/${book.language.code}/books/details/${book.id}` }; return ( @@ -211,7 +194,6 @@ export default class EditBookForm extends React.Component { > Discard changes -