This task evaluates the candidate's skills in React
and Redux
.
Welcome to the Simple Website Builder application. This app is an initial implementation of a WYSIWYG editor that enables users to build a simple website just by picking HTML tags from the widget and filling all the attributes they need.
On the left-hand side, the Component Preview is being displayed, it includes the current content of the page. On the right-hand side, using the Component Picker, the user can choose a new component to be added (headers, links, text paragraphs, images, etc). When a component is chosen, appropriate form is being displayed (Edited Component), for the user to enter relevant data, e.g. when user clicks to add a Link, Link Form is displayed and the user should set link label and href. Moreover:
- while editing, the user can apply, so that the changes are submitted, or remove, if the item should be removed.
- when the user chooses to add a certain component type (e.g. a link, whatever) and the appropriate form gets opened, all other components become locked (disabled). Only when the form gets closed (either element is applied or removed) then the lock is removed (user can choose to add a new component again)
All in all, it's a simple and intuitive UI.
This react application was generated using Create React App. It has all the standard setups.
Follow these steps if you are using zip/git mode (i.e. not available inside Devskiller in-browser IDE):
npm install
– install dependenciesnpm test
– run all tests (this will be used to evaluate your solutions)npm start
– run the project locally
- Make tests pass by implementing missing features in the production code.
- Make the app work in a way described below. The majority of the code is committed, but there are some missing pieces that have to be implemented.
- Fix the reducer setup. Although there is a
componentsSlice
created, it's not being properly configured for redux to use it. Include the slice in the store, so that the content of the slice is available under thecomponents
key in the global redux state object. - Handle all actions in components slice (
store/index.js
):addComponent
action should add the new component to the item's array and store the component as acurrentlyEdited
one.updateComponent
action should update the passed component in the item's array and nullifycurrentlyEdited
property. Make sure to not modify the items array if the updated item doesn't exist in the store.removeComponent
action should remove the passed component from the item's array and nullifycurrentlyEdited
property.setEditedComponent
action should setcurrentlyEdited
property to the passed component.- precise requirements of how the reducer should handle actions are defined in multiple snapshots of the redux state objects.
- Implement the
a
HTML tag (link) in thecomponents/Components/A.js
file (currently implementation is empty). After clicking on the link, a new tab should open. Passvalues
prop object that will containhref
(url to open), andlabel
(link's label) properties. Browsing context that is created by following this link should not have the opener browsing context (for example, new window shouldn't be able to usewindow.opener
JS property to change original page). Furthermore, referrer information shouldn't be passed to the new tab. The component should render just an<a/>
tag with proper attributes and content. - Implement the
img
HTML tag (image) in thecomponents/Components/Img.js
file (currently implementation is empty). Passvalues
prop object that will containalt
(alternative text describing image), andsrc
(url of the image) properties. The component should render just an<img/>
tag withalt
andsrc
attributes. - Update the
ComponentsPicker
:- Pass
lockedPicker
boolean prop toComponentPicker
that will tell it ifcomponents-picker__component--disabled
class should be applied. - Make
lockedPicker
a required prop. - The items of the components picker (
<div/>
elements) should be greyed out with thecomponents-picker__component--disabled
class and they should not be clickable when a component is being edited.
- Pass
All tests shall remain untouched, especially the snapshots shall not be updated. It is the implementation, what should be updated, in order to match test expectations.
Updating snapshots will probably lower your score.
When implementing reducer, feel free to use immer
(it's explicitly added to the dependencies).