Skip to content

Commit

Permalink
Feat/add settings modal to folder card (#245)
Browse files Browse the repository at this point in the history
* Fix: updated styling for folder

* Fix: updated styling for media card

* Fix: handle modal closing on blur for OverviewCard

* Feat: add folderModal to allow users to change name of folders

* Fix: remove resource room name change from settings

* Feat: add dropdown to FolderCard

* Fix: close dropdown on OverviewCard when delete button is used

* Fix: adjust FolderModal proptypes

* Fix: right align modal buttons
  • Loading branch information
alexanderleegs authored Nov 23, 2020
1 parent 77add6c commit 49a6eee
Show file tree
Hide file tree
Showing 7 changed files with 197 additions and 44 deletions.
130 changes: 104 additions & 26 deletions src/components/FolderCard.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
import React from 'react';
import React, { useEffect, useRef, useState } from 'react';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';
import axios from 'axios';

import FolderModal from './FolderModal';
import DeleteWarningModal from './DeleteWarningModal'

import elementStyles from '../styles/isomer-cms/Elements.module.scss';
import contentStyles from '../styles/isomer-cms/pages/Content.module.scss';

// axios settings
axios.defaults.withCredentials = true

const FolderCard = ({
displayText,
settingsToggle,
Expand All @@ -13,38 +21,108 @@ const FolderCard = ({
siteName,
category,
}) => {
const [isFolderModalOpen, setIsFolderModalOpen] = useState(false)
const [canShowDropdown, setCanShowDropdown] = useState(false)
const [canShowDeleteWarningModal, setCanShowDeleteWarningModal] = useState(false)
const dropdownRef = useRef(null)

useEffect(() => {
if (canShowDropdown) dropdownRef.current.focus()
}, [canShowDropdown])

const generateLink = () => {
if (isHomepage) return `/sites/${siteName}/homepage`
if (isCollection) return `/sites/${siteName}/collections/${category}`
return `/sites/${siteName}/resources/${category}`
}

return (
<Link className={`${contentStyles.component} ${contentStyles.card} ${elementStyles.folderCard}`} to={generateLink()}>
<div id={itemIndex} className={contentStyles.folderInfo}>
<i className={`bx bx-md text-dark ${isHomepage ? 'bxs-home-circle' : 'bxs-folder'}`} />
<span className={`${contentStyles.componentFolderName} align-self-center ml-4 mr-auto`}>{displayText}</span>
{
isHomepage
? ''
: (
<div className={contentStyles.componentIcon}>
<button
className={contentStyles.componentIcon}
type="button"
id={`settings-folder-${itemIndex}`}
onClick={(e) => {
e.preventDefault();
settingsToggle(e)}}
className={contentStyles.componentIcon}
>
<i id={`settingsIcon-${itemIndex}`} className="bx bx-dots-vertical-rounded" />
</button>
</div>
)
}
const MenuItem = ({handler, id, children}) => {
return (
<div
id={id}
onClick={(e) => {
e.stopPropagation();
e.preventDefault();
if (handler) handler(e);
}}
className={`${elementStyles.dropdownItem}`}
>
{children}
</div>
</Link>
)
}

const deleteHandler = async () => {
try {
const apiUrl = `${process.env.REACT_APP_BACKEND_URL}/sites/${siteName}/${isCollection ? `/collections/${category}` : `/resources/${category}`}`
await axios.delete(apiUrl);

// Refresh page
window.location.reload();
} catch (err) {
console.log(err);
}
}

return (
<>
{ isFolderModalOpen &&
<FolderModal
displayTitle={isCollection ? 'Rename Collection' : 'Rename Resource Category'}
displayText={isCollection ? 'Collection name' : "Resource category name"}
onClose={() => setIsFolderModalOpen(false)}
category={category}
siteName={siteName}
isCollection={isCollection}
/>
}
{ canShowDeleteWarningModal &&
<DeleteWarningModal
onCancel={() => setCanShowDeleteWarningModal(false)}
onDelete={deleteHandler}
type="folder"
/>
}
<Link className={`${contentStyles.component} ${contentStyles.card} ${elementStyles.folderCard}`} to={generateLink()}>
<div id={itemIndex} className={`${contentStyles.folderInfo}`}>
<i className={`bx bx-md text-dark ${isHomepage ? 'bxs-home-circle' : 'bxs-folder'} ${contentStyles.componentIcon}`} />
<span className={`${contentStyles.componentFolderName} align-self-center ml-4 mr-auto`}>{displayText}</span>
{
isHomepage
? ''
: (
<div className={`position-relative`}>
<button
className={contentStyles.componentIcon}
type="button"
id={`settings-folder-${itemIndex}`}
onClick={(e) => {
e.preventDefault();
settingsToggle(e);
setCanShowDropdown(true)
}}
className={contentStyles.componentIcon}
>
<i id={`settingsIcon-${itemIndex}`} className="bx bx-dots-vertical-rounded" />
</button>
{ canShowDropdown &&
<div className={`position-absolute ${elementStyles.dropdown}`} ref={dropdownRef} tabIndex={2} onBlur={()=>setCanShowDropdown(false)}>
<MenuItem handler={(e) => {dropdownRef.current.blur(); setIsFolderModalOpen(true)}} id={`folderSettings-${itemIndex}`}>
<i id={`settingsIcon-${itemIndex}`} className="bx bx-sm bx-edit"/>
<div className={elementStyles.dropdownText}>Rename</div>
</MenuItem>
<MenuItem handler={() => {dropdownRef.current.blur(); setCanShowDeleteWarningModal(true)}} id={`folderDelete-${itemIndex}`}>
<i className="bx bx-sm bx-trash text-danger"/>
<div className={elementStyles.dropdownText}>Delete folder</div>
</MenuItem>
</div>
}
</div>
)
}
</div>
</Link>
</>
)
}

Expand Down
67 changes: 67 additions & 0 deletions src/components/FolderModal.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import React, { useState } from 'react';
import axios from 'axios';
import PropTypes from 'prop-types';
import elementStyles from '../styles/isomer-cms/Elements.module.scss';
import SaveDeleteButtons from './SaveDeleteButtons';
import FormField from './FormField';

// axios settings
axios.defaults.withCredentials = true

const FolderModal = ({ displayTitle, displayText, onClose, category, siteName, isCollection }) => {
const [newCategoryName, setNewCategoryName] = useState(category)

const folderNameChangeHandler = (event) => {
const { value } = event.target
setNewCategoryName(value)
}

const saveHandler = async () => {
try {
await axios.post(`${process.env.REACT_APP_BACKEND_URL}/sites/${siteName}/${isCollection ? 'collections' : 'resources'}/${category}/rename/${newCategoryName}`)
// Refresh page
window.location.reload();
} catch (err) {
console.log(err);
}
}

return (
<div className={elementStyles.overlay}>
<div className={elementStyles['modal-settings']}>
<div className={elementStyles.modalHeader}>
<h1>
{displayTitle}
</h1>
<button type="button" onClick={onClose}>
<i className="bx bx-x" />
</button>
</div>
<form className={elementStyles.modalContent}>
<FormField
title={displayText}
id="newCategoryName"
value={newCategoryName}
onFieldChange={folderNameChangeHandler}
/>
<SaveDeleteButtons
isDisabled={false}
hasDeleteButton={false}
saveCallback={saveHandler}
/>
</form>
</div>
</div>
)
};

FolderModal.propTypes = {
displayTitle: PropTypes.string.isRequired,
displayText: PropTypes.string.isRequired,
onClose: PropTypes.func.isRequired,
category: PropTypes.string.isRequired,
siteName: PropTypes.string.isRequired,
isCollection: PropTypes.bool,
};

export default FolderModal;
4 changes: 2 additions & 2 deletions src/components/OverviewCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -215,13 +215,13 @@ const OverviewCard = ({
<div className={elementStyles.dropdownText}>Move to</div>
<i className="bx bx-sm bx-chevron-right ml-auto"/>
</MenuItem>
<MenuItem handler={() => setCanShowDeleteWarningModal(true)}>
<MenuItem handler={() => {dropdownRef.current.blur(); setCanShowDeleteWarningModal(true)}}>
<i className="bx bx-sm bx-trash text-danger"/>
<div className={elementStyles.dropdownText}>Delete item</div>
</MenuItem>
</div>}
{canShowFileMoveDropdown &&
<div className={`position-absolute ${elementStyles.dropdown}`} ref={fileMoveDropdownRef} tabIndex={1} >
<div className={`position-absolute ${elementStyles.dropdown}`} ref={fileMoveDropdownRef} tabIndex={1} onBlur={handleBlur}>
<MenuItem className={`d-flex`} handler={toggleDropdownModals}>
<i className="bx bx-sm bx-arrow-back"/>
<div className={elementStyles.dropdownText}>Move to</div>
Expand Down
16 changes: 1 addition & 15 deletions src/layouts/Settings.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { validateSocialMedia } from '../utils/validators';
const stateFields = {
title: '',
favicon: '',
resources_name: '',
colors: {
'primary-color': '',
'secondary-color': '',
Expand Down Expand Up @@ -218,14 +217,11 @@ export default class Settings extends Component {
const {
title,
favicon,
// eslint-disable-next-line camelcase
resources_name,
colors,
} = this.state;
const configSettings = {
title,
favicon,
resources_name,
colors,
};

Expand Down Expand Up @@ -349,7 +345,6 @@ export default class Settings extends Component {
siteName,
title,
favicon,
resources_name: resourcesName,
colors,
socialMediaContent,
otherFooterSettings,
Expand All @@ -365,7 +360,7 @@ export default class Settings extends Component {
const { location } = this.props;

// retrieve errors
const hasConfigErrors = _.some([errors.title, errors.favicon, errors.resources_name]);
const hasConfigErrors = _.some([errors.favicon]);
const hasColorErrors = _.some([errors.colors.primaryColor, errors.colors.secondaryColor]);
const hasMediaColorErrors = _.some(errors.colors['media-colors'].map((mediaColor) => mediaColor.color));
const hasSocialMediaErrors = _.some(Object.values(errors.socialMediaContent));
Expand Down Expand Up @@ -410,15 +405,6 @@ export default class Settings extends Component {
placeholder=" "
type="image"
/>
{/* Resource room name field */}
<FormField
title="Resource Room Name"
id="resources_name"
value={resourcesName}
errorMessage={errors.resources_name}
isRequired
onFieldChange={this.changeHandler}
/>
{/* Color fields */}
<div id="color-fields">
<p className={elementStyles.formSectionHeader}>Colors</p>
Expand Down
1 change: 1 addition & 0 deletions src/styles/isomer-cms/elements/modal.scss
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
display: flex;
flex-direction: row;
justify-content: flex-start;
margin-left: auto;
}
}
}
Expand Down
20 changes: 19 additions & 1 deletion src/styles/isomer-cms/pages/Content.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@

.boxesContainer{
@include cardFormat;
overflow: hidden;

.card{
width: $component-card-width;
Expand Down Expand Up @@ -161,6 +162,17 @@
margin-bottom: $component-folder-margin;
min-width: 250px;
color:black;
text-overflow: ellipsis;
.componentIcon{
display: flex;
flex-direction: column;
justify-content: center;
align-content: flex-end;

.bx{
font-size: 20px;
}
}
}
}
}
Expand All @@ -179,7 +191,6 @@
flex-direction: column;
justify-content: space-between;
align-content: center;
overflow: hidden;

.componentCategory{
text-transform: uppercase;
Expand Down Expand Up @@ -241,6 +252,13 @@
@extend .componentInfo;
flex-direction: row;
width: 100%;
height: 100%;
white-space: nowrap;
text-overflow: ellipsis;
i {
vertical-align: middle;
line-height:inherit;
}
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/styles/isomer-cms/pages/Media.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@
font-size: .9em;
color: $body-text;
margin-bottom: 5px;
overflow:hidden;
white-space: nowrap;
text-overflow: ellipsis;
}

.mediaCardDate{
Expand Down

0 comments on commit 49a6eee

Please sign in to comment.