diff --git a/.circleci/config.yml b/.circleci/config.yml index f9b033e0..0f8356ee 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -11,7 +11,7 @@ install_yarn_packages: &install_yarn_packages run: name: install dependencies command: | - yarn --cwd client/package.json install + yarn --cwd clientV2/package.json install attach_workspace: &attach_workspace attach_workspace: @@ -77,7 +77,7 @@ jobs: - run: name: Verify and Check Yarn packages for vulnerabilities command: | - yarn --cwd client/package.json check --integrity + yarn --cwd clientV2/package.json check --integrity # If lint check is required uncomment the block of code below # lint: @@ -100,9 +100,9 @@ jobs: - run: name: Run frontend test command: | - yarn --cwd client/package.json test - ls ./client/ - ./tmp/cc-test-reporter format-coverage -t lcov -o tmp/codeclimate.frontend.json ./client/coverage/lcov.info + yarn --cwd clientV2/package.json test + ls ./clientV2/ + ./tmp/cc-test-reporter format-coverage -t lcov -o tmp/codeclimate.frontend.json ./clientV2/coverage/lcov.info - persist_to_workspace: root: tmp paths: diff --git a/.gitignore b/.gitignore index 97f51cd8..b1b6b61e 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,7 @@ cypress.json yarn-error.log .coverage /client/coverage +/clientV2/coverage .tox warning.log client/dist diff --git a/clientV2/__mocks__/fileMock.js b/clientV2/__mocks__/fileMock.js new file mode 100644 index 00000000..86059f36 --- /dev/null +++ b/clientV2/__mocks__/fileMock.js @@ -0,0 +1 @@ +module.exports = 'test-file-stub'; diff --git a/clientV2/__mocks__/styleMock.js b/clientV2/__mocks__/styleMock.js new file mode 100644 index 00000000..f053ebf7 --- /dev/null +++ b/clientV2/__mocks__/styleMock.js @@ -0,0 +1 @@ +module.exports = {}; diff --git a/clientV2/__tests__/component/Avatar.test.js b/clientV2/__tests__/component/Avatar.test.js new file mode 100644 index 00000000..d173ae01 --- /dev/null +++ b/clientV2/__tests__/component/Avatar.test.js @@ -0,0 +1,15 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import { Avatar } from '../../component/Avatar'; + +describe('Avatar Component', () => { + it('should render correctly', () => { + const props = { + imgUrl: '//http:/img.jpg' + }; + + const wrapper = shallow(); + + expect(wrapper).toMatchSnapshot(); + }); +}); diff --git a/clientV2/__tests__/component/AvatarGroup.test.js b/clientV2/__tests__/component/AvatarGroup.test.js new file mode 100644 index 00000000..3d865d9c --- /dev/null +++ b/clientV2/__tests__/component/AvatarGroup.test.js @@ -0,0 +1,46 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import { AvatarGroup } from '../../component/AvatarGroup'; +import { Avatar } from '../../component/Avatar'; + +describe('AvatarGroup Component', () => { + let wrapper; + const imgList = () => { + const imgArr = []; + for (let i = 0; i < 10; i++) { + imgArr.push({ imgUrl: `//http:/img.jpg${i + 1}` }); + } + return imgArr; + }; + + beforeEach(() => { + const props = { + imgList: imgList() + }; + wrapper = shallow(); + }); + + it('should render correctly', () => { + expect(wrapper).toMatchSnapshot(); + }); + + it('should display Avatar Component', () => { + const avatar = wrapper.find(Avatar); + expect(avatar.length).toBe(7); + expect(wrapper).toMatchSnapshot(); + }); + + it('should display Avatar count if Avatar length is more than 8', () => { + const avatarCount = wrapper.find('.img-count'); + expect(avatarCount.text()).toContain(3); + }); + + it('should not display Avatar count if Avatar length is less than 8', () => { + const props = { + imgList: [{ imgUrl: '//http:/img.jpg1' }] + }; + const wrapper = shallow(); + const avatarCount = wrapper.find('.img-count'); + expect(avatarCount.length).toBe(0); + }); +}); diff --git a/clientV2/__tests__/component/__snapshots__/Avatar.test.js.snap b/clientV2/__tests__/component/__snapshots__/Avatar.test.js.snap new file mode 100644 index 00000000..13d86ba0 --- /dev/null +++ b/clientV2/__tests__/component/__snapshots__/Avatar.test.js.snap @@ -0,0 +1,75 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Avatar Component should render correctly 1`] = ` +ShallowWrapper { + Symbol(enzyme.__root__): [Circular], + Symbol(enzyme.__unrendered__): , + Symbol(enzyme.__renderer__): Object { + "batchedUpdates": [Function], + "checkPropTypes": [Function], + "getNode": [Function], + "render": [Function], + "simulateError": [Function], + "simulateEvent": [Function], + "unmount": [Function], + }, + Symbol(enzyme.__node__): Object { + "instance": null, + "key": undefined, + "nodeType": "host", + "props": Object { + "alt": "", + "className": "avatar ", + "src": "//http:/img.jpg", + }, + "ref": null, + "rendered": null, + "type": "img", + }, + Symbol(enzyme.__nodes__): Array [ + Object { + "instance": null, + "key": undefined, + "nodeType": "host", + "props": Object { + "alt": "", + "className": "avatar ", + "src": "//http:/img.jpg", + }, + "ref": null, + "rendered": null, + "type": "img", + }, + ], + Symbol(enzyme.__options__): Object { + "adapter": ReactSixteenAdapter { + "options": Object { + "enableComponentDidUpdateOnSetState": true, + "legacyContextMode": "parent", + "lifecycles": Object { + "componentDidUpdate": Object { + "onSetState": true, + }, + "getChildContext": Object { + "calledByRenderer": false, + }, + "getDerivedStateFromError": false, + "getDerivedStateFromProps": Object { + "hasShouldComponentUpdateBug": false, + }, + "getSnapshotBeforeUpdate": true, + "setState": Object { + "skipsComponentDidUpdateOnNullish": true, + }, + }, + }, + }, + Symbol(enzyme.__providerValues__): undefined, + }, + Symbol(enzyme.__providerValues__): Map {}, +} +`; diff --git a/clientV2/__tests__/component/__snapshots__/AvatarGroup.test.js.snap b/clientV2/__tests__/component/__snapshots__/AvatarGroup.test.js.snap new file mode 100644 index 00000000..02b8b55b --- /dev/null +++ b/clientV2/__tests__/component/__snapshots__/AvatarGroup.test.js.snap @@ -0,0 +1,1353 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AvatarGroup Component should display Avatar Component 1`] = ` +ShallowWrapper { + Symbol(enzyme.__root__): [Circular], + Symbol(enzyme.__unrendered__): , + Symbol(enzyme.__renderer__): Object { + "batchedUpdates": [Function], + "checkPropTypes": [Function], + "getNode": [Function], + "render": [Function], + "simulateError": [Function], + "simulateEvent": [Function], + "unmount": [Function], + }, + Symbol(enzyme.__node__): Object { + "instance": null, + "key": undefined, + "nodeType": "host", + "props": Object { + "children": Array [ + Array [ +
+ +
, +
+ +
, +
+ +
, +
+ +
, +
+ +
, +
+ +
, +
+ +
, + undefined, + undefined, + undefined, + ], + + +3 + , + ], + "className": "avatar-group", + }, + "ref": null, + "rendered": Array [ + Object { + "instance": null, + "key": "img0", + "nodeType": "host", + "props": Object { + "children": , + "className": "avatar-item ", + }, + "ref": null, + "rendered": Object { + "instance": null, + "key": undefined, + "nodeType": "function", + "props": Object { + "altText": "", + "classes": "", + "imgUrl": "//http:/img.jpg1", + }, + "ref": null, + "rendered": null, + "type": [Function], + }, + "type": "div", + }, + Object { + "instance": null, + "key": "img1", + "nodeType": "host", + "props": Object { + "children": , + "className": "avatar-item ", + }, + "ref": null, + "rendered": Object { + "instance": null, + "key": undefined, + "nodeType": "function", + "props": Object { + "altText": "", + "classes": "", + "imgUrl": "//http:/img.jpg2", + }, + "ref": null, + "rendered": null, + "type": [Function], + }, + "type": "div", + }, + Object { + "instance": null, + "key": "img2", + "nodeType": "host", + "props": Object { + "children": , + "className": "avatar-item ", + }, + "ref": null, + "rendered": Object { + "instance": null, + "key": undefined, + "nodeType": "function", + "props": Object { + "altText": "", + "classes": "", + "imgUrl": "//http:/img.jpg3", + }, + "ref": null, + "rendered": null, + "type": [Function], + }, + "type": "div", + }, + Object { + "instance": null, + "key": "img3", + "nodeType": "host", + "props": Object { + "children": , + "className": "avatar-item ", + }, + "ref": null, + "rendered": Object { + "instance": null, + "key": undefined, + "nodeType": "function", + "props": Object { + "altText": "", + "classes": "", + "imgUrl": "//http:/img.jpg4", + }, + "ref": null, + "rendered": null, + "type": [Function], + }, + "type": "div", + }, + Object { + "instance": null, + "key": "img4", + "nodeType": "host", + "props": Object { + "children": , + "className": "avatar-item ", + }, + "ref": null, + "rendered": Object { + "instance": null, + "key": undefined, + "nodeType": "function", + "props": Object { + "altText": "", + "classes": "", + "imgUrl": "//http:/img.jpg5", + }, + "ref": null, + "rendered": null, + "type": [Function], + }, + "type": "div", + }, + Object { + "instance": null, + "key": "img5", + "nodeType": "host", + "props": Object { + "children": , + "className": "avatar-item ", + }, + "ref": null, + "rendered": Object { + "instance": null, + "key": undefined, + "nodeType": "function", + "props": Object { + "altText": "", + "classes": "", + "imgUrl": "//http:/img.jpg6", + }, + "ref": null, + "rendered": null, + "type": [Function], + }, + "type": "div", + }, + Object { + "instance": null, + "key": "img6", + "nodeType": "host", + "props": Object { + "children": , + "className": "avatar-item ", + }, + "ref": null, + "rendered": Object { + "instance": null, + "key": undefined, + "nodeType": "function", + "props": Object { + "altText": "", + "classes": "", + "imgUrl": "//http:/img.jpg7", + }, + "ref": null, + "rendered": null, + "type": [Function], + }, + "type": "div", + }, + undefined, + undefined, + undefined, + Object { + "instance": null, + "key": undefined, + "nodeType": "host", + "props": Object { + "children": "+3", + "className": "img-count", + }, + "ref": null, + "rendered": "+3", + "type": "span", + }, + ], + "type": "div", + }, + Symbol(enzyme.__nodes__): Array [ + Object { + "instance": null, + "key": undefined, + "nodeType": "host", + "props": Object { + "children": Array [ + Array [ +
+ +
, +
+ +
, +
+ +
, +
+ +
, +
+ +
, +
+ +
, +
+ +
, + undefined, + undefined, + undefined, + ], + + +3 + , + ], + "className": "avatar-group", + }, + "ref": null, + "rendered": Array [ + Object { + "instance": null, + "key": "img0", + "nodeType": "host", + "props": Object { + "children": , + "className": "avatar-item ", + }, + "ref": null, + "rendered": Object { + "instance": null, + "key": undefined, + "nodeType": "function", + "props": Object { + "altText": "", + "classes": "", + "imgUrl": "//http:/img.jpg1", + }, + "ref": null, + "rendered": null, + "type": [Function], + }, + "type": "div", + }, + Object { + "instance": null, + "key": "img1", + "nodeType": "host", + "props": Object { + "children": , + "className": "avatar-item ", + }, + "ref": null, + "rendered": Object { + "instance": null, + "key": undefined, + "nodeType": "function", + "props": Object { + "altText": "", + "classes": "", + "imgUrl": "//http:/img.jpg2", + }, + "ref": null, + "rendered": null, + "type": [Function], + }, + "type": "div", + }, + Object { + "instance": null, + "key": "img2", + "nodeType": "host", + "props": Object { + "children": , + "className": "avatar-item ", + }, + "ref": null, + "rendered": Object { + "instance": null, + "key": undefined, + "nodeType": "function", + "props": Object { + "altText": "", + "classes": "", + "imgUrl": "//http:/img.jpg3", + }, + "ref": null, + "rendered": null, + "type": [Function], + }, + "type": "div", + }, + Object { + "instance": null, + "key": "img3", + "nodeType": "host", + "props": Object { + "children": , + "className": "avatar-item ", + }, + "ref": null, + "rendered": Object { + "instance": null, + "key": undefined, + "nodeType": "function", + "props": Object { + "altText": "", + "classes": "", + "imgUrl": "//http:/img.jpg4", + }, + "ref": null, + "rendered": null, + "type": [Function], + }, + "type": "div", + }, + Object { + "instance": null, + "key": "img4", + "nodeType": "host", + "props": Object { + "children": , + "className": "avatar-item ", + }, + "ref": null, + "rendered": Object { + "instance": null, + "key": undefined, + "nodeType": "function", + "props": Object { + "altText": "", + "classes": "", + "imgUrl": "//http:/img.jpg5", + }, + "ref": null, + "rendered": null, + "type": [Function], + }, + "type": "div", + }, + Object { + "instance": null, + "key": "img5", + "nodeType": "host", + "props": Object { + "children": , + "className": "avatar-item ", + }, + "ref": null, + "rendered": Object { + "instance": null, + "key": undefined, + "nodeType": "function", + "props": Object { + "altText": "", + "classes": "", + "imgUrl": "//http:/img.jpg6", + }, + "ref": null, + "rendered": null, + "type": [Function], + }, + "type": "div", + }, + Object { + "instance": null, + "key": "img6", + "nodeType": "host", + "props": Object { + "children": , + "className": "avatar-item ", + }, + "ref": null, + "rendered": Object { + "instance": null, + "key": undefined, + "nodeType": "function", + "props": Object { + "altText": "", + "classes": "", + "imgUrl": "//http:/img.jpg7", + }, + "ref": null, + "rendered": null, + "type": [Function], + }, + "type": "div", + }, + undefined, + undefined, + undefined, + Object { + "instance": null, + "key": undefined, + "nodeType": "host", + "props": Object { + "children": "+3", + "className": "img-count", + }, + "ref": null, + "rendered": "+3", + "type": "span", + }, + ], + "type": "div", + }, + ], + Symbol(enzyme.__options__): Object { + "adapter": ReactSixteenAdapter { + "options": Object { + "enableComponentDidUpdateOnSetState": true, + "legacyContextMode": "parent", + "lifecycles": Object { + "componentDidUpdate": Object { + "onSetState": true, + }, + "getChildContext": Object { + "calledByRenderer": false, + }, + "getDerivedStateFromError": false, + "getDerivedStateFromProps": Object { + "hasShouldComponentUpdateBug": false, + }, + "getSnapshotBeforeUpdate": true, + "setState": Object { + "skipsComponentDidUpdateOnNullish": true, + }, + }, + }, + }, + Symbol(enzyme.__providerValues__): undefined, + }, + Symbol(enzyme.__providerValues__): Map {}, +} +`; + +exports[`AvatarGroup Component should render correctly 1`] = ` +ShallowWrapper { + Symbol(enzyme.__root__): [Circular], + Symbol(enzyme.__unrendered__): , + Symbol(enzyme.__renderer__): Object { + "batchedUpdates": [Function], + "checkPropTypes": [Function], + "getNode": [Function], + "render": [Function], + "simulateError": [Function], + "simulateEvent": [Function], + "unmount": [Function], + }, + Symbol(enzyme.__node__): Object { + "instance": null, + "key": undefined, + "nodeType": "host", + "props": Object { + "children": Array [ + Array [ +
+ +
, +
+ +
, +
+ +
, +
+ +
, +
+ +
, +
+ +
, +
+ +
, + undefined, + undefined, + undefined, + ], + + +3 + , + ], + "className": "avatar-group", + }, + "ref": null, + "rendered": Array [ + Object { + "instance": null, + "key": "img0", + "nodeType": "host", + "props": Object { + "children": , + "className": "avatar-item ", + }, + "ref": null, + "rendered": Object { + "instance": null, + "key": undefined, + "nodeType": "function", + "props": Object { + "altText": "", + "classes": "", + "imgUrl": "//http:/img.jpg1", + }, + "ref": null, + "rendered": null, + "type": [Function], + }, + "type": "div", + }, + Object { + "instance": null, + "key": "img1", + "nodeType": "host", + "props": Object { + "children": , + "className": "avatar-item ", + }, + "ref": null, + "rendered": Object { + "instance": null, + "key": undefined, + "nodeType": "function", + "props": Object { + "altText": "", + "classes": "", + "imgUrl": "//http:/img.jpg2", + }, + "ref": null, + "rendered": null, + "type": [Function], + }, + "type": "div", + }, + Object { + "instance": null, + "key": "img2", + "nodeType": "host", + "props": Object { + "children": , + "className": "avatar-item ", + }, + "ref": null, + "rendered": Object { + "instance": null, + "key": undefined, + "nodeType": "function", + "props": Object { + "altText": "", + "classes": "", + "imgUrl": "//http:/img.jpg3", + }, + "ref": null, + "rendered": null, + "type": [Function], + }, + "type": "div", + }, + Object { + "instance": null, + "key": "img3", + "nodeType": "host", + "props": Object { + "children": , + "className": "avatar-item ", + }, + "ref": null, + "rendered": Object { + "instance": null, + "key": undefined, + "nodeType": "function", + "props": Object { + "altText": "", + "classes": "", + "imgUrl": "//http:/img.jpg4", + }, + "ref": null, + "rendered": null, + "type": [Function], + }, + "type": "div", + }, + Object { + "instance": null, + "key": "img4", + "nodeType": "host", + "props": Object { + "children": , + "className": "avatar-item ", + }, + "ref": null, + "rendered": Object { + "instance": null, + "key": undefined, + "nodeType": "function", + "props": Object { + "altText": "", + "classes": "", + "imgUrl": "//http:/img.jpg5", + }, + "ref": null, + "rendered": null, + "type": [Function], + }, + "type": "div", + }, + Object { + "instance": null, + "key": "img5", + "nodeType": "host", + "props": Object { + "children": , + "className": "avatar-item ", + }, + "ref": null, + "rendered": Object { + "instance": null, + "key": undefined, + "nodeType": "function", + "props": Object { + "altText": "", + "classes": "", + "imgUrl": "//http:/img.jpg6", + }, + "ref": null, + "rendered": null, + "type": [Function], + }, + "type": "div", + }, + Object { + "instance": null, + "key": "img6", + "nodeType": "host", + "props": Object { + "children": , + "className": "avatar-item ", + }, + "ref": null, + "rendered": Object { + "instance": null, + "key": undefined, + "nodeType": "function", + "props": Object { + "altText": "", + "classes": "", + "imgUrl": "//http:/img.jpg7", + }, + "ref": null, + "rendered": null, + "type": [Function], + }, + "type": "div", + }, + undefined, + undefined, + undefined, + Object { + "instance": null, + "key": undefined, + "nodeType": "host", + "props": Object { + "children": "+3", + "className": "img-count", + }, + "ref": null, + "rendered": "+3", + "type": "span", + }, + ], + "type": "div", + }, + Symbol(enzyme.__nodes__): Array [ + Object { + "instance": null, + "key": undefined, + "nodeType": "host", + "props": Object { + "children": Array [ + Array [ +
+ +
, +
+ +
, +
+ +
, +
+ +
, +
+ +
, +
+ +
, +
+ +
, + undefined, + undefined, + undefined, + ], + + +3 + , + ], + "className": "avatar-group", + }, + "ref": null, + "rendered": Array [ + Object { + "instance": null, + "key": "img0", + "nodeType": "host", + "props": Object { + "children": , + "className": "avatar-item ", + }, + "ref": null, + "rendered": Object { + "instance": null, + "key": undefined, + "nodeType": "function", + "props": Object { + "altText": "", + "classes": "", + "imgUrl": "//http:/img.jpg1", + }, + "ref": null, + "rendered": null, + "type": [Function], + }, + "type": "div", + }, + Object { + "instance": null, + "key": "img1", + "nodeType": "host", + "props": Object { + "children": , + "className": "avatar-item ", + }, + "ref": null, + "rendered": Object { + "instance": null, + "key": undefined, + "nodeType": "function", + "props": Object { + "altText": "", + "classes": "", + "imgUrl": "//http:/img.jpg2", + }, + "ref": null, + "rendered": null, + "type": [Function], + }, + "type": "div", + }, + Object { + "instance": null, + "key": "img2", + "nodeType": "host", + "props": Object { + "children": , + "className": "avatar-item ", + }, + "ref": null, + "rendered": Object { + "instance": null, + "key": undefined, + "nodeType": "function", + "props": Object { + "altText": "", + "classes": "", + "imgUrl": "//http:/img.jpg3", + }, + "ref": null, + "rendered": null, + "type": [Function], + }, + "type": "div", + }, + Object { + "instance": null, + "key": "img3", + "nodeType": "host", + "props": Object { + "children": , + "className": "avatar-item ", + }, + "ref": null, + "rendered": Object { + "instance": null, + "key": undefined, + "nodeType": "function", + "props": Object { + "altText": "", + "classes": "", + "imgUrl": "//http:/img.jpg4", + }, + "ref": null, + "rendered": null, + "type": [Function], + }, + "type": "div", + }, + Object { + "instance": null, + "key": "img4", + "nodeType": "host", + "props": Object { + "children": , + "className": "avatar-item ", + }, + "ref": null, + "rendered": Object { + "instance": null, + "key": undefined, + "nodeType": "function", + "props": Object { + "altText": "", + "classes": "", + "imgUrl": "//http:/img.jpg5", + }, + "ref": null, + "rendered": null, + "type": [Function], + }, + "type": "div", + }, + Object { + "instance": null, + "key": "img5", + "nodeType": "host", + "props": Object { + "children": , + "className": "avatar-item ", + }, + "ref": null, + "rendered": Object { + "instance": null, + "key": undefined, + "nodeType": "function", + "props": Object { + "altText": "", + "classes": "", + "imgUrl": "//http:/img.jpg6", + }, + "ref": null, + "rendered": null, + "type": [Function], + }, + "type": "div", + }, + Object { + "instance": null, + "key": "img6", + "nodeType": "host", + "props": Object { + "children": , + "className": "avatar-item ", + }, + "ref": null, + "rendered": Object { + "instance": null, + "key": undefined, + "nodeType": "function", + "props": Object { + "altText": "", + "classes": "", + "imgUrl": "//http:/img.jpg7", + }, + "ref": null, + "rendered": null, + "type": [Function], + }, + "type": "div", + }, + undefined, + undefined, + undefined, + Object { + "instance": null, + "key": undefined, + "nodeType": "host", + "props": Object { + "children": "+3", + "className": "img-count", + }, + "ref": null, + "rendered": "+3", + "type": "span", + }, + ], + "type": "div", + }, + ], + Symbol(enzyme.__options__): Object { + "adapter": ReactSixteenAdapter { + "options": Object { + "enableComponentDidUpdateOnSetState": true, + "legacyContextMode": "parent", + "lifecycles": Object { + "componentDidUpdate": Object { + "onSetState": true, + }, + "getChildContext": Object { + "calledByRenderer": false, + }, + "getDerivedStateFromError": false, + "getDerivedStateFromProps": Object { + "hasShouldComponentUpdateBug": false, + }, + "getSnapshotBeforeUpdate": true, + "setState": Object { + "skipsComponentDidUpdateOnNullish": true, + }, + }, + }, + }, + Symbol(enzyme.__providerValues__): undefined, + }, + Symbol(enzyme.__providerValues__): Map {}, +} +`; diff --git a/clientV2/__tests__/setup/setupEnzyme.js b/clientV2/__tests__/setup/setupEnzyme.js new file mode 100644 index 00000000..fc7b0dce --- /dev/null +++ b/clientV2/__tests__/setup/setupEnzyme.js @@ -0,0 +1,4 @@ +import Enzyme from 'enzyme'; +import Adapter from 'enzyme-adapter-react-16'; + +Enzyme.configure({ adapter: new Adapter() }); diff --git a/clientV2/assets/base/index.scss b/clientV2/assets/base/index.scss index c7ddc33f..2c3296eb 100644 --- a/clientV2/assets/base/index.scss +++ b/clientV2/assets/base/index.scss @@ -34,6 +34,7 @@ h6 { margin-top: 0; margin-bottom: 0.5rem; } + p, ol, ul, @@ -41,9 +42,11 @@ dl { margin-top: 0; margin-bottom: 1rem; } + .small { margin-top: 0rem; } + body { font-family: 'Open Sans', sans-serif; margin: 0; @@ -53,11 +56,3 @@ body { line-height: 1.6; background-color: #fff; } - -p, -ol, -ul, -dl { - margin-top: 0; - margin-bottom: 1rem; -} diff --git a/clientV2/assets/components/_avatar.scss b/clientV2/assets/components/_avatar.scss index 201a993e..e94b462e 100644 --- a/clientV2/assets/components/_avatar.scss +++ b/clientV2/assets/components/_avatar.scss @@ -1,32 +1,37 @@ .avatar { - width: 32px; - height: 32px; + width: 35px; + height: 35px; object-fit: cover; border-radius: 50%; + &-xs { width: 16px; height: 16px; object-fit: cover; border-radius: 50%; } + &-sm { width: 24px; height: 24px; object-fit: cover; border-radius: 50%; } + &-md { width: 48px; height: 48px; object-fit: cover; border-radius: 50%; } + &-lg { - width: 64px; - height: 64px; + width: 60px; + height: 60px; object-fit: cover; border-radius: 50%; } + &-xl { width: 96px; height: 96px; diff --git a/clientV2/assets/layout/layout.scss b/clientV2/assets/layout/layout.scss index 1353d4e4..f5adbcf4 100644 --- a/clientV2/assets/layout/layout.scss +++ b/clientV2/assets/layout/layout.scss @@ -1,151 +1,150 @@ - .container { - width: 100%; +.container { + width: 100%; + padding: 0 0.9375rem; + margin: 0 auto; + position: relative; + animation: transitionIn 1s; + + &-fluid { padding: 0 0.9375rem; - margin: 0 auto; - position: relative; - animation: transitionIn 1s; + } +} - &-fluid { - padding: 0 0.9375rem; - } +@media (min-width: 75rem) { + .container { + width: 71.25rem; } +} + +.columns { + display: flex; + flex-wrap: wrap; + margin: 0 -0.9375rem; +} + +@media (min-width: 576px) { + .container { + max-width: 540px; + } +} +@media (min-width: 768px) { + .container { + max-width: 720px; + } +} - @media (min-width: 75rem) { - .container { - width: 71.25rem; - } +@media (min-width: 992px) { + .container { + max-width: 960px; } +} - .columns { - display: flex; - flex-wrap: wrap; - margin: 0 -0.9375rem; +@media (min-width: 1200px) { + .container { + max-width: 1140px; } +} + +.col-1, +.col-2, +.col-3, +.col-4, +.col-5, +.col-6, +.col-7, +.col-8, +.col-9, +.col-10, +.col-11, +.col-12, +.col, +.col-auto { + position: relative; + width: 100%; + padding: 0 15px; +} - @media (min-width: 576px) { - .container { - max-width: 540px; - } +@media (min-width: 768px) { + .col { + flex-basis: 0; + flex-grow: 1; + max-width: 100%; } - @media (min-width: 768px) { - .container { - max-width: 720px; - } + .col-auto { + flex: 0 0 auto; + width: auto; + max-width: 100%; } - @media (min-width: 992px) { - .container { - max-width: 960px; - } + .col-1 { + flex: 0 0 8.333333%; + max-width: 8.333333%; } - @media (min-width: 1200px) { - .container { - max-width: 1140px; - } + .col-2 { + flex: 0 0 16.666667%; + max-width: 16.666667%; } - .col-1, - .col-2, - .col-3, - .col-4, - .col-5, - .col-6, - .col-7, - .col-8, - .col-9, - .col-10, - .col-11, - .col-12, - .col, - .col-auto { - position: relative; - width: 100%; - padding: 0 15px; - } - - @media (min-width: 768px) { - .col { - flex-basis: 0; - flex-grow: 1; - max-width: 100%; - } - - .col-auto { - flex: 0 0 auto; - width: auto; - max-width: 100%; - } - - .col-1 { - flex: 0 0 8.333333%; - max-width: 8.333333%; - } - - .col-2 { - flex: 0 0 16.666667%; - max-width: 16.666667%; - } - - .col-3 { - flex: 0 0 25%; - max-width: 25%; - } - - .col-4 { - flex: 0 0 33.333333%; - max-width: 33.333333%; - } - - .col-5 { - flex: 0 0 41.666667%; - max-width: 41.666667%; - } - - .col-6 { - flex: 0 0 50%; - max-width: 50%; - } - - .col-7 { - flex: 0 0 58.333333%; - max-width: 58.333333%; - } - - .col-8 { - flex: 0 0 66.666667%; - max-width: 66.666667%; - } - - .col-9 { - flex: 0 0 75%; - max-width: 75%; - } - - .col-10 { - flex: 0 0 83.333333%; - max-width: 83.333333%; - } - - .col-11 { - flex: 0 0 91.666667%; - max-width: 91.666667%; - } - - .col-12 { - flex: 0 0 100%; - max-width: 100%; - } - - } - - @keyframes transitionIn { + .col-3 { + flex: 0 0 25%; + max-width: 25%; + } + + .col-4 { + flex: 0 0 33.333333%; + max-width: 33.333333%; + } + + .col-5 { + flex: 0 0 41.666667%; + max-width: 41.666667%; + } + + .col-6 { + flex: 0 0 50%; + max-width: 50%; + } + + .col-7 { + flex: 0 0 58.333333%; + max-width: 58.333333%; + } + + .col-8 { + flex: 0 0 66.666667%; + max-width: 66.666667%; + } + + .col-9 { + flex: 0 0 75%; + max-width: 75%; + } + + .col-10 { + flex: 0 0 83.333333%; + max-width: 83.333333%; + } + + .col-11 { + flex: 0 0 91.666667%; + max-width: 91.666667%; + } + + .col-12 { + flex: 0 0 100%; + max-width: 100%; + } +} + +@keyframes transitionIn { from { opacity: 0; transform: translateY(-10px); } + to { opacity: 1; transform: translateY(0); diff --git a/clientV2/assets/theme/_colors.scss b/clientV2/assets/theme/_colors.scss index cc4170f5..479b8340 100644 --- a/clientV2/assets/theme/_colors.scss +++ b/clientV2/assets/theme/_colors.scss @@ -1,8 +1,9 @@ $colors: ( - andela: #365DDC, + andela: #365ddc, yellow: #ffa300, white: #fff, dark: #000, bonjour: #e0dcdc, - silver: #cccccc + silver: #ccc, + grey: #777 ); diff --git a/clientV2/component/Avatar/index.jsx b/clientV2/component/Avatar/index.jsx new file mode 100644 index 00000000..9ac7db4a --- /dev/null +++ b/clientV2/component/Avatar/index.jsx @@ -0,0 +1,24 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +/** + * @description - This component displays a single Avatar + * + * @export Avatar + * @param {object} { imgUrl, classes, altText } + * @returns {JSX} + */ +export const Avatar = ({ imgUrl, classes, altText }) => { + return {altText}; +} + +Avatar.propTypes = { + imgUrl: PropTypes.string.isRequired, + classes: PropTypes.string, + altText: PropTypes.string +}; + +Avatar.defaultProps = { + classes: '', + altText: '' +}; diff --git a/clientV2/component/AvatarGroup/avatar-group.scss b/clientV2/component/AvatarGroup/avatar-group.scss new file mode 100644 index 00000000..754183ad --- /dev/null +++ b/clientV2/component/AvatarGroup/avatar-group.scss @@ -0,0 +1,19 @@ +@import '../../assets/style.scss'; + +.avatar-group { + display: flex; + align-items: center; + z-index: 1; + + .avatar-item { + width: 25px; + } + + .img-count { + display: inline-block; + vertical-align: middle; + margin-left: 25px; + font-size: 1.125rem; + color: map-get($colors, grey); + } +} diff --git a/clientV2/component/AvatarGroup/index.jsx b/clientV2/component/AvatarGroup/index.jsx new file mode 100644 index 00000000..3e082aff --- /dev/null +++ b/clientV2/component/AvatarGroup/index.jsx @@ -0,0 +1,34 @@ +/* eslint-disable array-callback-return */ +import React from 'react'; +import PropTypes from 'prop-types'; + +import { Avatar } from '../Avatar'; +import './avatar-group.scss'; + +/** + * @description - This component displays group of Avatars + * + * @param {object} { classes, imgList } - classes and imgList are props + * @return {JSX} + */ +export const AvatarGroup = ({ classes, imgList }) => ( +
+ {imgList.map((img, index) => { + if (index < 7) { + return ( +
+ +
+ ); + } + })} + {imgList.length > 7 && {`+${imgList.length - 7}`}} +
+); + +AvatarGroup.propTypes = { + classes: PropTypes.string, + imgList: PropTypes.arrayOf(PropTypes.shape).isRequired +}; + +AvatarGroup.defaultProps = { classes: '' }; diff --git a/clientV2/jest.config.js b/clientV2/jest.config.js new file mode 100644 index 00000000..c2b128e2 --- /dev/null +++ b/clientV2/jest.config.js @@ -0,0 +1,16 @@ +module.exports = { + clearMocks: true, + coverageDirectory: 'coverage', + testRegex: '(roots/.*|(\\.|/)(test))\\.(js|jsx)?$', + testEnvironment: 'node', + testPathIgnorePatterns: [ + '/node_modules/', + '/cypress/', + '/__tests__/setup/', + ], + setupTestFrameworkScriptFile: '/__tests__/setup/setupEnzyme.js', + moduleNameMapper: { + '\\.(css|less|sass|scss)$': '/__mocks__/styleMock.js', + '\\.(gif|ttf|eot|svg)$': '/__mocks__/fileMock.js', + }, +}; diff --git a/clientV2/yarn.lock b/clientV2/yarn.lock index dda19e21..4f564a5f 100644 --- a/clientV2/yarn.lock +++ b/clientV2/yarn.lock @@ -2177,9 +2177,9 @@ buffer@^4.3.0: isarray "^1.0.0" buffer@^5.2.1: - version "5.4.0" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.4.0.tgz#33294f5c1f26e08461e528b69fa06de3c45cbd8c" - integrity sha512-Xpgy0IwHK2N01ncykXTy6FpCWuM+CJSHoPVBLyNqyrWxsedpLvwsYUhf0ME3WRFNUhos0dMamz9cOS/xRDtU5g== + version "5.4.2" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.4.2.tgz#2012872776206182480eccb2c0fba5f672a2efef" + integrity sha512-iy9koArjAFCzGnx3ZvNA6Z0clIbbFgbdWQ0mKD3hO0krOrZh8UgA6qMKcZvwLJxS+D6iVR76+5/pV56yMNYTag== dependencies: base64-js "^1.0.2" ieee754 "^1.1.4" @@ -3417,9 +3417,16 @@ dedent@^0.7.0: integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= deep-equal@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" - integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= + version "1.1.0" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.0.tgz#3103cdf8ab6d32cf4a8df7865458f2b8d33f3745" + integrity sha512-ZbfWJq/wN1Z273o7mUSjILYqehAktR2NVoSrOukDkU9kg2v/Uv89yU4Cvz8seJeAmtN5oqiefKq8FPuXOboqLw== + dependencies: + is-arguments "^1.0.4" + is-date-object "^1.0.1" + is-regex "^1.0.4" + object-is "^1.0.1" + object-keys "^1.1.1" + regexp.prototype.flags "^1.2.0" deep-extend@^0.4.1: version "0.4.2" @@ -3787,9 +3794,9 @@ ee-first@1.1.1: integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.47: - version "1.3.237" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.237.tgz#39c5d1da59d6fd16ff705b97e772bb3b5dfda7e4" - integrity sha512-SPAFjDr/7iiVK2kgTluwxela6eaWjjFkS9rO/iYpB/KGXgccUom5YC7OIf19c8m8GGptWxLU0Em8xM64A/N7Fg== + version "1.3.243" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.243.tgz#32f64f00fa121532d1d49f5c0a15fd77f52ae889" + integrity sha512-+edFdHGxLSmAKftXa5xZIg19rHkkJLiW+tRu0VMVG3RKztyeKX7d3pXf707lS6+BxB9uBun3RShbxCI1PtBAgQ== elegant-spinner@^1.0.1: version "1.0.1" @@ -4914,11 +4921,11 @@ flatten@^1.0.2: integrity sha1-2uRqnXj74lKSJYzB54CkHZXAN4I= follow-redirects@^1.0.0, follow-redirects@^1.2.3: - version "1.7.0" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.7.0.tgz#489ebc198dc0e7f64167bd23b03c4c19b5784c76" - integrity sha512-m/pZQy4Gj287eNy94nivy5wchN3Kp+Q5WgUPNy5lJSZ3sgkVKSYV/ZChMAQVIgx1SqfZ2zBZtPA2YlXIWxxJOQ== + version "1.8.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.8.1.tgz#24804f9eaab67160b0e840c085885d606371a35b" + integrity sha512-micCIbldHioIegeKs41DoH0KS3AXfFzgS30qVkM6z/XOE/GJgvmsoc839NUqa1B9udYe9dQxgv7KFwng6+p/dw== dependencies: - debug "^3.2.6" + debug "^3.0.0" for-in@^0.1.3: version "0.1.8" @@ -6107,6 +6114,11 @@ is-alphanumerical@^1.0.0: is-alphabetical "^1.0.0" is-decimal "^1.0.0" +is-arguments@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" + integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== + is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" @@ -7999,9 +8011,9 @@ minimist@~0.0.1: integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= minipass@^2.2.1, minipass@^2.3.5: - version "2.3.5" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" - integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== + version "2.4.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.4.0.tgz#38f0af94f42fb6f34d3d7d82a90e2c99cd3ff485" + integrity sha512-6PmOuSP4NnZXzs2z6rbwzLJu/c5gdzYg1mRI/WIYdx45iiX7T+a4esOzavD6V/KmBzAaopFSTZPZcUx73bqKWA== dependencies: safe-buffer "^5.1.2" yallist "^3.0.0" @@ -8486,7 +8498,7 @@ object-is@^1.0.1: resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.1.tgz#0aa60ec9989a0b3ed795cf4d06f62cf1ad6539b6" integrity sha1-CqYOyZiaCz7Xlc9NBvYs8a1lObY= -object-keys@^1.0.11, object-keys@^1.0.12: +object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== @@ -10102,6 +10114,13 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" +regexp.prototype.flags@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.2.0.tgz#6b30724e306a27833eeb171b66ac8890ba37e41c" + integrity sha512-ztaw4M1VqgMwl9HlPpOuiYgItcHlunW0He2fE6eNfT6E/CF2FtYi9ofOYe4mKntstYk0Fyh/rDRBdS3AnxjlrA== + dependencies: + define-properties "^1.1.2" + regexpp@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-1.1.0.tgz#0e3516dd0b7904f413d2d4193dce4618c3a689ab"