Initial commit
This commit is contained in:
17
.circleci/config.yml
Normal file
17
.circleci/config.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
version: 2.1
|
||||
orbs:
|
||||
node: circleci/node@1.1.6
|
||||
jobs:
|
||||
build-and-test:
|
||||
executor:
|
||||
name: node/default
|
||||
steps:
|
||||
- checkout
|
||||
- node/with-cache:
|
||||
steps:
|
||||
- run: npm install
|
||||
- run: npm test
|
||||
workflows:
|
||||
build-and-test:
|
||||
jobs:
|
||||
- build-and-test
|
||||
31
.github/workflows/nodejs.yml
vendored
Normal file
31
.github/workflows/nodejs.yml
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
|
||||
|
||||
name: Node.js CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ development ]
|
||||
pull_request:
|
||||
branches: [ development ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [10.x, 12.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- run: npm ci
|
||||
- run: npm run build --if-present
|
||||
- run: npm test
|
||||
env:
|
||||
CI: true
|
||||
104
.gitignore
vendored
Normal file
104
.gitignore
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# TypeScript v1 declaration files
|
||||
typings/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
.env.test
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and *not* Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
201
LICENSE
Normal file
201
LICENSE
Normal file
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
3
README.md
Normal file
3
README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# subset_trello
|
||||
|
||||
Application demonstrating a subset of TODO manager features.
|
||||
18385
package-lock.json
generated
Normal file
18385
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
68
package.json
Normal file
68
package.json
Normal file
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"name": "subset_trello",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"homepage": "http://mohiit1502.github.io/subset_trello",
|
||||
"dependencies": {
|
||||
"@material-ui/core": "4.9.9",
|
||||
"@material-ui/icons": "4.9.1",
|
||||
"@material-ui/lab": "^4.0.0-alpha.48",
|
||||
"@testing-library/jest-dom": "^4.2.4",
|
||||
"@testing-library/react": "^9.5.0",
|
||||
"@testing-library/user-event": "^7.2.1",
|
||||
"bootstrap": "^4.4.1",
|
||||
"jquery": "^3.5.0",
|
||||
"node-sass": "^4.13.1",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-loadable": "^5.5.0",
|
||||
"react-redux": "^7.2.0",
|
||||
"react-router-dom": "^5.1.2",
|
||||
"react-scripts": "3.4.1",
|
||||
"redux": "^4.0.5",
|
||||
"redux-actions": "^2.6.5",
|
||||
"redux-analytics": "^0.3.1",
|
||||
"redux-thunk": "^2.3.0",
|
||||
"reselect": "^4.0.0",
|
||||
"reselect-immutable-helpers": "^1.2.2",
|
||||
"sass-loader": "8.0.2"
|
||||
},
|
||||
"scripts": {
|
||||
"install": "cd server && npm install",
|
||||
"clientstart": "react-scripts start",
|
||||
"serverstart": "cd server && npm start",
|
||||
"start": "run-p clientstart serverstart",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject",
|
||||
"generate": "plop",
|
||||
"predeploy": "npm run build",
|
||||
"deploy": "gh-pages -d build"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "react-app"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.8.4",
|
||||
"@babel/core": "^7.9.0",
|
||||
"@babel/plugin-transform-react-jsx": "^7.9.4",
|
||||
"@babel/preset-env": "^7.9.0",
|
||||
"@babel/preset-react": "^7.9.4",
|
||||
"gh-pages": "^2.2.0",
|
||||
"plop": "^2.6.0",
|
||||
"typescript": "3.3.3"
|
||||
}
|
||||
}
|
||||
3
plop-templates/Component/Component.component.scss.hbs
Normal file
3
plop-templates/Component/Component.component.scss.hbs
Normal file
@@ -0,0 +1,3 @@
|
||||
.c-{{pascalCase name}} {
|
||||
|
||||
}
|
||||
17
plop-templates/Component/Component.jsx.hbs
Normal file
17
plop-templates/Component/Component.jsx.hbs
Normal file
@@ -0,0 +1,17 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import './{{pascalCase name}}.component.scss';
|
||||
|
||||
const {{pascalCase name}} = props => {
|
||||
return (
|
||||
<div className='c-{{pascalCase name}}'>
|
||||
In Component {{pascalCase name}}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
{{pascalCase name}}.propTypes = {
|
||||
|
||||
};
|
||||
|
||||
export default {{pascalCase name}};
|
||||
8
plop-templates/Component/Component.test.js.hbs
Normal file
8
plop-templates/Component/Component.test.js.hbs
Normal file
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import {{pascalCase name}} from './{{pascalCase name}}';
|
||||
|
||||
describe('{{pascalCase name}}', () => {
|
||||
it('renders without error', () => {
|
||||
|
||||
});
|
||||
});
|
||||
3
plop-templates/Component/index.js.hbs
Normal file
3
plop-templates/Component/index.js.hbs
Normal file
@@ -0,0 +1,3 @@
|
||||
import {{pascalCase name}} from './{{pascalCase name}}.jsx';
|
||||
|
||||
export default {{pascalCase name}};
|
||||
17
plop-templates/Page/Page.jsx.hbs
Normal file
17
plop-templates/Page/Page.jsx.hbs
Normal file
@@ -0,0 +1,17 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import './{{pascalCase name}}.module.scss';
|
||||
|
||||
const {{pascalCase name}} = props => {
|
||||
return (
|
||||
<div className="c-{{pascalCase name}}">
|
||||
In Page {{pascalCase name}}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
{{pascalCase name}}.propTypes = {
|
||||
|
||||
};
|
||||
|
||||
export default {{pascalCase name}};
|
||||
3
plop-templates/Page/Page.module.scss.hbs
Normal file
3
plop-templates/Page/Page.module.scss.hbs
Normal file
@@ -0,0 +1,3 @@
|
||||
.c-{{pascalCase name}} {
|
||||
|
||||
}
|
||||
8
plop-templates/Page/Page.test.js.hbs
Normal file
8
plop-templates/Page/Page.test.js.hbs
Normal file
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import {{pascalCase name}} from './{{pascalCase name}}';
|
||||
|
||||
describe('{{pascalCase name}}', () => {
|
||||
it('renders without error', () => {
|
||||
|
||||
});
|
||||
});
|
||||
16
plop-templates/Page/actions.js.hbs
Normal file
16
plop-templates/Page/actions.js.hbs
Normal file
@@ -0,0 +1,16 @@
|
||||
export const UPDATE_FORM_VALUES = 'UPDATE_{{constantCase name}}_FORM_VALUES'
|
||||
export const UPDATE_FORM_ERRORS = 'UPDATE_{{constantCase name}}_FORM_ERRORS'
|
||||
|
||||
export const updateFormValues = (formValues) => {
|
||||
return {
|
||||
type: UPDATE_FORM_VALUES,
|
||||
payload: formValues
|
||||
}
|
||||
}
|
||||
|
||||
export const updateFormErrors = (formErrors) => {
|
||||
return {
|
||||
type: UPDATE_FORM_ERRORS,
|
||||
payload: formErrors
|
||||
}
|
||||
}
|
||||
3
plop-templates/Page/index.js.hbs
Normal file
3
plop-templates/Page/index.js.hbs
Normal file
@@ -0,0 +1,3 @@
|
||||
import {{pascalCase name}} from './{{pascalCase name}}.jsx';
|
||||
|
||||
export default {{pascalCase name}};
|
||||
16
plop-templates/Page/reducer.js.hbs
Normal file
16
plop-templates/Page/reducer.js.hbs
Normal file
@@ -0,0 +1,16 @@
|
||||
import Immutable from 'immutable'
|
||||
import {UPDATE_FORM_ERRORS, UPDATE_FORM_VALUES} from './actions'
|
||||
|
||||
const initialState = Immutable.Map()
|
||||
|
||||
const reducer = (state = initialState, action) => {
|
||||
switch (action.type) {
|
||||
case UPDATE_FORM_ERRORS:
|
||||
case UPDATE_FORM_VALUES:
|
||||
return state.mergeDeep(action.payload)
|
||||
default:
|
||||
return state
|
||||
}
|
||||
}
|
||||
|
||||
export default reducer
|
||||
14
plop-templates/Page/selectors.js.hbs
Normal file
14
plop-templates/Page/selectors.js.hbs
Normal file
@@ -0,0 +1,14 @@
|
||||
import {createSelector} from 'reselect'
|
||||
import {createGetSelector} from 'reselect-immutable-helpers'
|
||||
|
||||
const getData = ({data}) => data
|
||||
|
||||
export const get{{pascalCase name}} = createSelector(
|
||||
getData,
|
||||
(dataState) => {
|
||||
return dataState.pages.{{camelCase name}}
|
||||
}
|
||||
)
|
||||
|
||||
export const getFormErrors = createGetSelector(get{{pascalCase name}}, 'formErrors')
|
||||
export const getFormValues = createGetSelector(get{{pascalCase name}}, 'formValues')
|
||||
5
plop-templates/hook.js.hbs
Normal file
5
plop-templates/hook.js.hbs
Normal file
@@ -0,0 +1,5 @@
|
||||
const {{camelCase name}} = () => {
|
||||
|
||||
};
|
||||
|
||||
export default {{camelCase name}};
|
||||
5
plop-templates/injectable-index.js.hbs
Normal file
5
plop-templates/injectable-index.js.hbs
Normal file
@@ -0,0 +1,5 @@
|
||||
/* PLOP_INJECT_IMPORT */
|
||||
|
||||
export {
|
||||
/* PLOP_INJECT_EXPORT */
|
||||
}
|
||||
17
plop-templates/service.js.hbs
Normal file
17
plop-templates/service.js.hbs
Normal file
@@ -0,0 +1,17 @@
|
||||
const create{{pascalCase name}} = () => {
|
||||
let examplePrivateVariable = 0
|
||||
|
||||
return {
|
||||
getExamplePrivateVariable: () => {
|
||||
return examplePrivateVariable
|
||||
},
|
||||
setExamplePrivateVariable: (n) => {
|
||||
examplePrivateVariable = n
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const singleton = create{{pascalCase name}}();
|
||||
Object.freeze(singleton);
|
||||
|
||||
export default singleton;
|
||||
210
plopfile.js
Normal file
210
plopfile.js
Normal file
@@ -0,0 +1,210 @@
|
||||
module.exports = plop => {
|
||||
plop.setGenerator('component', {
|
||||
description: 'Create a component',
|
||||
// User input prompts provided as arguments to the template
|
||||
prompts: [
|
||||
{
|
||||
// Raw text input
|
||||
type: 'input',
|
||||
// Variable name for this input
|
||||
name: 'name',
|
||||
// Prompt to display on command line
|
||||
message: 'What is your component name?'
|
||||
},
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
type: 'add',
|
||||
// Plop will create directories for us if they do not exist
|
||||
// so it's okay to add files in nested locations.
|
||||
path: 'src/app/components/{{pascalCase name}}/{{pascalCase name}}.jsx',
|
||||
templateFile:
|
||||
'plop-templates/Component/Component.jsx.hbs',
|
||||
},
|
||||
{
|
||||
type: 'add',
|
||||
path: 'src/app/components/{{pascalCase name}}/{{pascalCase name}}.test.js',
|
||||
templateFile:
|
||||
'plop-templates/Component/Component.test.js.hbs',
|
||||
},
|
||||
{
|
||||
type: 'add',
|
||||
path:
|
||||
'src/app/components/{{pascalCase name}}/{{pascalCase name}}.component.scss',
|
||||
templateFile:
|
||||
'plop-templates/Component/Component.component.scss.hbs',
|
||||
},
|
||||
{
|
||||
type: 'add',
|
||||
path: 'src/app/components/{{pascalCase name}}/index.js',
|
||||
templateFile: 'plop-templates/Component/index.js.hbs',
|
||||
},
|
||||
{
|
||||
// Adds an index.js file if it does not already exist
|
||||
type: 'add',
|
||||
path: 'src/app/components/index.js',
|
||||
templateFile: 'plop-templates/injectable-index.js.hbs',
|
||||
// If index.js already exists in this location, skip this action
|
||||
skipIfExists: true,
|
||||
},
|
||||
{
|
||||
// Action type 'append' injects a template into an existing file
|
||||
type: 'append',
|
||||
path: 'src/app/components/index.js',
|
||||
// Pattern tells plop where in the file to inject the template
|
||||
pattern: `/* PLOP_INJECT_IMPORT */`,
|
||||
template: `import {{pascalCase name}} from './{{pascalCase name}}';`,
|
||||
},
|
||||
{
|
||||
type: 'append',
|
||||
path: 'src/app/components/index.js',
|
||||
pattern: `/* PLOP_INJECT_EXPORT */`,
|
||||
template: `\t{{pascalCase name}},`,
|
||||
},
|
||||
],
|
||||
});
|
||||
plop.setGenerator('page', {
|
||||
description: 'Create a page',
|
||||
prompts: [
|
||||
{
|
||||
type: 'input',
|
||||
name: 'name',
|
||||
message: 'What is your page name?',
|
||||
},
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
type: 'add',
|
||||
path: 'src/app/pages/{{pascalCase name}}/{{pascalCase name}}.jsx',
|
||||
templateFile:
|
||||
'plop-templates/Page/Page.jsx.hbs',
|
||||
},
|
||||
{
|
||||
type: 'add',
|
||||
path: 'src/app/pages/{{pascalCase name}}/{{pascalCase name}}.test.js',
|
||||
templateFile:
|
||||
'plop-templates/Page/Page.test.js.hbs',
|
||||
},
|
||||
{
|
||||
type: 'add',
|
||||
path:
|
||||
'src/app/pages/{{pascalCase name}}/{{pascalCase name}}.module.scss',
|
||||
templateFile:
|
||||
'plop-templates/Page/Page.module.scss.hbs',
|
||||
},
|
||||
{
|
||||
type: 'add',
|
||||
path: 'src/app/pages/{{pascalCase name}}/reducer.js',
|
||||
templateFile: 'plop-templates/Page/reducer.js.hbs',
|
||||
skipIfExists: true,
|
||||
},
|
||||
{
|
||||
type: 'add',
|
||||
path: 'src/app/pages/{{pascalCase name}}/selectors.js',
|
||||
templateFile: 'plop-templates/Page/selectors.js.hbs',
|
||||
skipIfExists: true,
|
||||
},
|
||||
{
|
||||
type: 'add',
|
||||
path: 'src/app/pages/{{pascalCase name}}/actions.js',
|
||||
templateFile: 'plop-templates/Page/actions.js.hbs',
|
||||
skipIfExists: true,
|
||||
},
|
||||
{
|
||||
type: 'add',
|
||||
path: 'src/app/pages/{{pascalCase name}}/index.js',
|
||||
templateFile: 'plop-templates/Page/index.js.hbs',
|
||||
},
|
||||
{
|
||||
type: 'add',
|
||||
path: 'src/app/pages/index.js',
|
||||
templateFile: 'plop-templates/injectable-index.js.hbs',
|
||||
skipIfExists: true,
|
||||
},
|
||||
{
|
||||
type: 'append',
|
||||
path: 'src/app/pages/index.js',
|
||||
pattern: `/* PLOP_INJECT_IMPORT */`,
|
||||
template: `import {{pascalCase name}} from './{{pascalCase name}}';`,
|
||||
},
|
||||
{
|
||||
type: 'append',
|
||||
path: 'src/app/pages/index.js',
|
||||
pattern: `/* PLOP_INJECT_EXPORT */`,
|
||||
template: `\t{{pascalCase name}},`,
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
plop.setGenerator('service', {
|
||||
description: 'Create service',
|
||||
prompts: [
|
||||
{
|
||||
type: 'input',
|
||||
name: 'name',
|
||||
message: 'What is your service name?',
|
||||
},
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
type: 'add',
|
||||
path: 'src/services/{{camelCase name}}.js',
|
||||
templateFile: 'plop-templates/service.js.hbs',
|
||||
},
|
||||
{
|
||||
type: 'add',
|
||||
path: 'src/services/index.js',
|
||||
templateFile: 'plop-templates/injectable-index.js.hbs',
|
||||
skipIfExists: true,
|
||||
},
|
||||
{
|
||||
type: 'append',
|
||||
path: 'src/services/index.js',
|
||||
pattern: `/* PLOP_INJECT_IMPORT */`,
|
||||
template: `import {{camelCase name}} from './{{camelCase name}}';`,
|
||||
},
|
||||
{
|
||||
type: 'append',
|
||||
path: 'src/services/index.js',
|
||||
pattern: `/* PLOP_INJECT_EXPORT */`,
|
||||
template: `\t{{camelCase name}},`,
|
||||
}
|
||||
],
|
||||
})
|
||||
|
||||
plop.setGenerator('hook', {
|
||||
description: 'Create a custom react hook',
|
||||
prompts: [
|
||||
{
|
||||
type: 'input',
|
||||
name: 'name',
|
||||
message: 'What is your hook name?',
|
||||
},
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
type: 'add',
|
||||
path: 'src/hooks/{{camelCase name}}.js',
|
||||
templateFile: 'plop-templates/hook.js.hbs',
|
||||
},
|
||||
{
|
||||
type: 'add',
|
||||
path: 'src/hooks/index.js',
|
||||
templateFile: 'plop-templates/injectable-index.js.hbs',
|
||||
skipIfExists: true,
|
||||
},
|
||||
{
|
||||
type: 'append',
|
||||
path: 'src/hooks/index.js',
|
||||
pattern: `/* PLOP_INJECT_IMPORT */`,
|
||||
template: `import {{camelCase name}} from './{{camelCase name}}';`,
|
||||
},
|
||||
{
|
||||
type: 'append',
|
||||
path: 'src/hooks/index.js',
|
||||
pattern: `/* PLOP_INJECT_EXPORT */`,
|
||||
template: `\t{{camelCase name}},`,
|
||||
}
|
||||
],
|
||||
})
|
||||
};
|
||||
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
43
public/index.html
Normal file
43
public/index.html
Normal file
@@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Web site created using create-react-app"
|
||||
/>
|
||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is installed on a
|
||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>React App</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
BIN
public/logo192.png
Normal file
BIN
public/logo192.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.2 KiB |
BIN
public/logo512.png
Normal file
BIN
public/logo512.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.4 KiB |
25
public/manifest.json
Normal file
25
public/manifest.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
},
|
||||
{
|
||||
"src": "logo192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
},
|
||||
{
|
||||
"src": "logo512.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
||||
3
public/robots.txt
Normal file
3
public/robots.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
Disallow:
|
||||
145
server/data/todos.json
Normal file
145
server/data/todos.json
Normal file
@@ -0,0 +1,145 @@
|
||||
[
|
||||
{
|
||||
"img_url": "https://guesseu.scene7.com/is/image/GuessEU/M63H24W7JF0-L302-ALTGHOST?wid=1500&fmt=jpeg&qlt=80&op_sharpen=0&op_usm=1.0,1.0,5,0&iccEmbed=0",
|
||||
"name": "CHECK PRINT SHIRT - 2",
|
||||
"id": "product-111",
|
||||
"category": "Clothing",
|
||||
"price": {
|
||||
"display": 900,
|
||||
"actual": 324
|
||||
},
|
||||
"discount": 30
|
||||
},
|
||||
{
|
||||
"img_url": "https://guesseu.scene7.com/is/image/GuessEU/AW6308VIS03-SAP?wid=700&fmt=jpeg&qlt=80&op_sharpen=0&op_usm=1.0,1.0,5,0&iccEmbed=0",
|
||||
"name": "'70s RETRO GLAM KEFIAH - 3",
|
||||
"id": "product-112",
|
||||
"category": "Clothing",
|
||||
"price": {
|
||||
"display": 2084,
|
||||
"actual": 324
|
||||
},
|
||||
"discount": 24
|
||||
},
|
||||
{
|
||||
"img_url": "https://guesseu.scene7.com/is/image/GuessEU/FLGLO4FAL12-BEIBR?wid=700&fmt=jpeg&qlt=80&op_sharpen=0&op_usm=1.0,1.0,5,0&iccEmbed=0",
|
||||
"name": "GLORIA HIGH LOGO SNEAKER - 1",
|
||||
"id": "product-113",
|
||||
"category": "Footwear",
|
||||
"price": {
|
||||
"display": 650,
|
||||
"actual": 324
|
||||
},
|
||||
"discount": 64
|
||||
},
|
||||
{
|
||||
"img_url": "https://guesseu.scene7.com/is/image/GuessEU/AW6308VIS03-SAP?wid=700&fmt=jpeg&qlt=80&op_sharpen=0&op_usm=1.0,1.0,5,0&iccEmbed=0",
|
||||
"name": "'70s RETRO GLAM KEFIAH - 4",
|
||||
"id": "product-114",
|
||||
"category": "Clothing",
|
||||
"price": {
|
||||
"display": 3284,
|
||||
"actual": 324
|
||||
},
|
||||
"discount": 80
|
||||
},
|
||||
{
|
||||
"img_url": "https://guesseu.scene7.com/is/image/GuessEU/HWVG6216060-TAN?wid=700&fmt=jpeg&qlt=80&op_sharpen=0&op_usm=1.0,1.0,5,0&iccEmbed=0",
|
||||
"name": "CATE RIGID BAG - 1",
|
||||
"id": "product-115",
|
||||
"category": "Accessories",
|
||||
"price": {
|
||||
"display": 1838,
|
||||
"actual": 324
|
||||
},
|
||||
"discount": 45
|
||||
},
|
||||
{
|
||||
"img_url": "https://guesseu.scene7.com/is/image/GuessEU/AW6308VIS03-SAP?wid=700&fmt=jpeg&qlt=80&op_sharpen=0&op_usm=1.0,1.0,5,0&iccEmbed=0",
|
||||
"name": "'70s RETRO GLAM KEFIAH - 6",
|
||||
"id": "product-116",
|
||||
"category": "Clothing",
|
||||
"price": {
|
||||
"display": 8884,
|
||||
"actual": 324
|
||||
},
|
||||
"discount": 38
|
||||
},
|
||||
{
|
||||
"img_url": "http://guesseu.scene7.com/is/image/GuessEU/WC0001FMSWC-G5?wid=520&fmt=jpeg&qlt=80&op_sharpen=0&op_usm=1.0,1.0,5,0&iccEmbed=0",
|
||||
"name": "GUESS CONNECT WATCH - 1",
|
||||
"id": "product-117",
|
||||
"category": "Electronics",
|
||||
"price": {
|
||||
"display": 290,
|
||||
"actual": 324
|
||||
},
|
||||
"discount": 22
|
||||
},
|
||||
{
|
||||
"img_url": "https://guesseu.scene7.com/is/image/GuessEU/AW6308VIS03-SAP?wid=700&fmt=jpeg&qlt=80&op_sharpen=0&op_usm=1.0,1.0,5,0&iccEmbed=0",
|
||||
"name": "'70s RETRO GLAM KEFIAH - 1",
|
||||
"id": "product-118",
|
||||
"category": "Clothing",
|
||||
"price": {
|
||||
"display": 1284,
|
||||
"actual": 324
|
||||
},
|
||||
"discount": 52
|
||||
},
|
||||
{
|
||||
"img_url": "https://guesseu.scene7.com/is/image/GuessEU/M63H24W7JF0-L302-ALTGHOST?wid=1500&fmt=jpeg&qlt=80&op_sharpen=0&op_usm=1.0,1.0,5,0&iccEmbed=0",
|
||||
"name": "CHECK PRINT SHIRT - 1",
|
||||
"id": "product-119",
|
||||
"category": "Clothing",
|
||||
"price": {
|
||||
"display": 900,
|
||||
"actual": 324
|
||||
},
|
||||
"discount": 19
|
||||
},
|
||||
{
|
||||
"img_url": "https://guesseu.scene7.com/is/image/GuessEU/AW6308VIS03-SAP?wid=700&fmt=jpeg&qlt=80&op_sharpen=0&op_usm=1.0,1.0,5,0&iccEmbed=0",
|
||||
"name": "'70s RETRO GLAM KEFIAH - 2",
|
||||
"id": "product-120",
|
||||
"category": "Clothing",
|
||||
"price": {
|
||||
"display": 584,
|
||||
"actual": 324
|
||||
},
|
||||
"discount": 32
|
||||
},
|
||||
{
|
||||
"img_url": "https://guesseu.scene7.com/is/image/GuessEU/AW6308VIS03-SAP?wid=700&fmt=jpeg&qlt=80&op_sharpen=0&op_usm=1.0,1.0,5,0&iccEmbed=0",
|
||||
"name": "'70s RETRO GLAM KEFIAH - 5",
|
||||
"id": "product-121",
|
||||
"category": "Clothing",
|
||||
"price": {
|
||||
"display": 984,
|
||||
"actual": 324
|
||||
},
|
||||
"discount": 60
|
||||
},
|
||||
{
|
||||
"img_url": "https://guesseu.scene7.com/is/image/GuessEU/FLGLO4FAL12-BEIBR?wid=700&fmt=jpeg&qlt=80&op_sharpen=0&op_usm=1.0,1.0,5,0&iccEmbed=0",
|
||||
"name": "GLORIA HIGH LOGO SNEAKER - 1",
|
||||
"id": "product-122",
|
||||
"category": "Footwear",
|
||||
"price": {
|
||||
"display": 6650,
|
||||
"actual": 324
|
||||
},
|
||||
"discount": 5
|
||||
},
|
||||
{
|
||||
"img_url": "https://guesseu.scene7.com/is/image/GuessEU/HWVG6216060-TAN?wid=700&fmt=jpeg&qlt=80&op_sharpen=0&op_usm=1.0,1.0,5,0&iccEmbed=0",
|
||||
"name": "CATE RIGID BAG - 2",
|
||||
"id": "product-123",
|
||||
"category": "Accessories",
|
||||
"price": {
|
||||
"display": 838,
|
||||
"actual": 324
|
||||
},
|
||||
"discount": 20
|
||||
}
|
||||
]
|
||||
32
server/index.js
Normal file
32
server/index.js
Normal file
@@ -0,0 +1,32 @@
|
||||
const fs = require('fs');
|
||||
const express = require('express');
|
||||
const bodyParser = require('body-parser');
|
||||
const cors = require('cors')
|
||||
|
||||
var corsOptions = {origin: '*', optionsSuccessStatus: 200,}
|
||||
const app = express();
|
||||
app.use(cors(corsOptions))
|
||||
app.use(bodyParser.json());
|
||||
|
||||
app.get('/todos', (req, res) => {
|
||||
fs.readFile("data/todos.json", "utf8", function(err, data) {
|
||||
if (err) {
|
||||
return res.json(err);
|
||||
}
|
||||
return res.json(data)
|
||||
});
|
||||
})
|
||||
|
||||
app.post('/todos', (req, res) => {
|
||||
fs.appendFile("data/products.json", "utf8", function(err, data) {
|
||||
if (err) {
|
||||
return res.json(err);
|
||||
}
|
||||
return res.json(data)
|
||||
});
|
||||
})
|
||||
|
||||
|
||||
app.listen(3001, () => {
|
||||
console.log("App running on the port 3001");
|
||||
})
|
||||
388
server/package-lock.json
generated
Normal file
388
server/package-lock.json
generated
Normal file
@@ -0,0 +1,388 @@
|
||||
{
|
||||
"name": "subset_trello_backend",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"accepts": {
|
||||
"version": "1.3.7",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
|
||||
"integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
|
||||
"requires": {
|
||||
"mime-types": "~2.1.24",
|
||||
"negotiator": "0.6.2"
|
||||
}
|
||||
},
|
||||
"array-flatten": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
|
||||
},
|
||||
"body-parser": {
|
||||
"version": "1.19.0",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
|
||||
"integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
|
||||
"requires": {
|
||||
"bytes": "3.1.0",
|
||||
"content-type": "~1.0.4",
|
||||
"debug": "2.6.9",
|
||||
"depd": "~1.1.2",
|
||||
"http-errors": "1.7.2",
|
||||
"iconv-lite": "0.4.24",
|
||||
"on-finished": "~2.3.0",
|
||||
"qs": "6.7.0",
|
||||
"raw-body": "2.4.0",
|
||||
"type-is": "~1.6.17"
|
||||
}
|
||||
},
|
||||
"bytes": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
|
||||
"integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
|
||||
},
|
||||
"content-disposition": {
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
|
||||
"integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
|
||||
"requires": {
|
||||
"safe-buffer": "5.1.2"
|
||||
}
|
||||
},
|
||||
"content-type": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
|
||||
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
|
||||
},
|
||||
"cookie": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
|
||||
"integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
|
||||
},
|
||||
"cookie-signature": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
|
||||
},
|
||||
"cors": {
|
||||
"version": "2.8.5",
|
||||
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
|
||||
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
|
||||
"requires": {
|
||||
"object-assign": "^4",
|
||||
"vary": "^1"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"depd": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
|
||||
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
|
||||
},
|
||||
"destroy": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
|
||||
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
|
||||
},
|
||||
"ee-first": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
|
||||
},
|
||||
"encodeurl": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
|
||||
},
|
||||
"escape-html": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
|
||||
},
|
||||
"etag": {
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
||||
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
|
||||
},
|
||||
"express": {
|
||||
"version": "4.17.1",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
|
||||
"integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
|
||||
"requires": {
|
||||
"accepts": "~1.3.7",
|
||||
"array-flatten": "1.1.1",
|
||||
"body-parser": "1.19.0",
|
||||
"content-disposition": "0.5.3",
|
||||
"content-type": "~1.0.4",
|
||||
"cookie": "0.4.0",
|
||||
"cookie-signature": "1.0.6",
|
||||
"debug": "2.6.9",
|
||||
"depd": "~1.1.2",
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"etag": "~1.8.1",
|
||||
"finalhandler": "~1.1.2",
|
||||
"fresh": "0.5.2",
|
||||
"merge-descriptors": "1.0.1",
|
||||
"methods": "~1.1.2",
|
||||
"on-finished": "~2.3.0",
|
||||
"parseurl": "~1.3.3",
|
||||
"path-to-regexp": "0.1.7",
|
||||
"proxy-addr": "~2.0.5",
|
||||
"qs": "6.7.0",
|
||||
"range-parser": "~1.2.1",
|
||||
"safe-buffer": "5.1.2",
|
||||
"send": "0.17.1",
|
||||
"serve-static": "1.14.1",
|
||||
"setprototypeof": "1.1.1",
|
||||
"statuses": "~1.5.0",
|
||||
"type-is": "~1.6.18",
|
||||
"utils-merge": "1.0.1",
|
||||
"vary": "~1.1.2"
|
||||
}
|
||||
},
|
||||
"finalhandler": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
|
||||
"integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
|
||||
"requires": {
|
||||
"debug": "2.6.9",
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"on-finished": "~2.3.0",
|
||||
"parseurl": "~1.3.3",
|
||||
"statuses": "~1.5.0",
|
||||
"unpipe": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"forwarded": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
|
||||
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
|
||||
},
|
||||
"fresh": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
||||
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
|
||||
},
|
||||
"http-errors": {
|
||||
"version": "1.7.2",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
|
||||
"integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
|
||||
"requires": {
|
||||
"depd": "~1.1.2",
|
||||
"inherits": "2.0.3",
|
||||
"setprototypeof": "1.1.1",
|
||||
"statuses": ">= 1.5.0 < 2",
|
||||
"toidentifier": "1.0.0"
|
||||
}
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
||||
"requires": {
|
||||
"safer-buffer": ">= 2.1.2 < 3"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||
},
|
||||
"ipaddr.js": {
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
||||
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
|
||||
},
|
||||
"media-typer": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
|
||||
},
|
||||
"merge-descriptors": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
||||
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
|
||||
},
|
||||
"methods": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
|
||||
},
|
||||
"mime": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
|
||||
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.43.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz",
|
||||
"integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ=="
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.26",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz",
|
||||
"integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==",
|
||||
"requires": {
|
||||
"mime-db": "1.43.0"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
},
|
||||
"negotiator": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
|
||||
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
|
||||
},
|
||||
"on-finished": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
|
||||
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
|
||||
"requires": {
|
||||
"ee-first": "1.1.1"
|
||||
}
|
||||
},
|
||||
"parseurl": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
|
||||
},
|
||||
"path-to-regexp": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
|
||||
},
|
||||
"proxy-addr": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
|
||||
"integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
|
||||
"requires": {
|
||||
"forwarded": "~0.1.2",
|
||||
"ipaddr.js": "1.9.1"
|
||||
}
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.7.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
||||
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
|
||||
},
|
||||
"range-parser": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
|
||||
},
|
||||
"raw-body": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
|
||||
"integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
|
||||
"requires": {
|
||||
"bytes": "3.1.0",
|
||||
"http-errors": "1.7.2",
|
||||
"iconv-lite": "0.4.24",
|
||||
"unpipe": "1.0.0"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||
},
|
||||
"send": {
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
|
||||
"integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
|
||||
"requires": {
|
||||
"debug": "2.6.9",
|
||||
"depd": "~1.1.2",
|
||||
"destroy": "~1.0.4",
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"etag": "~1.8.1",
|
||||
"fresh": "0.5.2",
|
||||
"http-errors": "~1.7.2",
|
||||
"mime": "1.6.0",
|
||||
"ms": "2.1.1",
|
||||
"on-finished": "~2.3.0",
|
||||
"range-parser": "~1.2.1",
|
||||
"statuses": "~1.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ms": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
|
||||
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve-static": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
|
||||
"integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
|
||||
"requires": {
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"parseurl": "~1.3.3",
|
||||
"send": "0.17.1"
|
||||
}
|
||||
},
|
||||
"setprototypeof": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
|
||||
"integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
|
||||
},
|
||||
"statuses": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
|
||||
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
|
||||
},
|
||||
"toidentifier": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
|
||||
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
|
||||
},
|
||||
"type-is": {
|
||||
"version": "1.6.18",
|
||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
|
||||
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
|
||||
"requires": {
|
||||
"media-typer": "0.3.0",
|
||||
"mime-types": "~2.1.24"
|
||||
}
|
||||
},
|
||||
"unpipe": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
|
||||
},
|
||||
"utils-merge": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
|
||||
},
|
||||
"vary": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
|
||||
}
|
||||
}
|
||||
}
|
||||
17
server/package.json
Normal file
17
server/package.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "subset_trello_backend",
|
||||
"version": "1.0.0",
|
||||
"description": "Server to save and retrieve TODO lists",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "node .",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "mohiit1502",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"body-parser": "^1.19.0",
|
||||
"cors": "^2.8.5",
|
||||
"express": "^4.17.1"
|
||||
}
|
||||
}
|
||||
3
src/app/components/Header/Header.component.scss
Normal file
3
src/app/components/Header/Header.component.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
.c-Header {
|
||||
|
||||
}
|
||||
21
src/app/components/Header/Header.jsx
Normal file
21
src/app/components/Header/Header.jsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import './Header.component.scss';
|
||||
|
||||
const Header = props => {
|
||||
return (
|
||||
<div className='c-Header'>
|
||||
In Component Header
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Header.defaultProps = {
|
||||
|
||||
};
|
||||
|
||||
Header.propTypes = {
|
||||
|
||||
};
|
||||
|
||||
export default Header;
|
||||
8
src/app/components/Header/Header.test.js
Normal file
8
src/app/components/Header/Header.test.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import Header from './Header';
|
||||
|
||||
describe('Header', () => {
|
||||
it('renders without error', () => {
|
||||
|
||||
});
|
||||
});
|
||||
3
src/app/components/Header/index.js
Normal file
3
src/app/components/Header/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import Header from './Header.jsx';
|
||||
|
||||
export default Header;
|
||||
82
src/app/components/PageLoader/PageLoader.component.scss
Normal file
82
src/app/components/PageLoader/PageLoader.component.scss
Normal file
@@ -0,0 +1,82 @@
|
||||
@import url('https://fonts.googleapis.com/css?family=Indie+Flower');
|
||||
|
||||
.c-PageLoader {
|
||||
margin-top: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.is-animate {
|
||||
background: #ffb200;
|
||||
box-sizing: border-box;
|
||||
font-size: 66px;
|
||||
display: -webkit-inline-box;
|
||||
padding: 14px;
|
||||
border-radius: 7px;
|
||||
}
|
||||
.is-animate > div {
|
||||
animation-name: style;
|
||||
display: -webkit-inline-box;
|
||||
color: #fff;
|
||||
padding: 9px;
|
||||
background: #ffb200;
|
||||
font-family: 'Indie Flower', cursive;
|
||||
box-shadow: 2px 2px 9px 2px;
|
||||
}
|
||||
.l{
|
||||
animation: letterspacing 1s infinite alternate cubic-bezier(.2, 0, 0, 1);
|
||||
}
|
||||
|
||||
.is-animate > div {
|
||||
animation-duration: 1s;
|
||||
animation-fill-mode: both;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
.is-animate > div:nth-child(1) { animation-delay: 0.0s }
|
||||
.is-animate > div:nth-child(2) { animation-delay: 0.1s }
|
||||
.is-animate > div:nth-child(3) { animation-delay: 0.2s }
|
||||
.is-animate > div:nth-child(4) { animation-delay: 0.3s }
|
||||
.is-animate > div:nth-child(5) { animation-delay: 0.4s }
|
||||
.is-animate > div:nth-child(6) { animation-delay: 0.5s }
|
||||
.is-animate > div:nth-child(7) { animation-delay: 0.6s }
|
||||
|
||||
|
||||
@keyframes style {
|
||||
from {
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
30% {
|
||||
box-shadow: 0px 0px 0px 0px;
|
||||
transform: scale3d(1.25, 0.75, 1);
|
||||
}
|
||||
40% {
|
||||
transform: scale3d(0.75, 1.25, 1);
|
||||
}
|
||||
50% {
|
||||
transform: scale3d(1.15, 0.85, 1);
|
||||
}
|
||||
65% {
|
||||
transform: scale3d(.95, 1.05, 1);
|
||||
}
|
||||
75% {
|
||||
transform: scale3d(1.05, .95, 1);
|
||||
}
|
||||
to {
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@keyframes letterspacing {
|
||||
0% {
|
||||
filter: blur(0.1rem);
|
||||
}
|
||||
100% {
|
||||
filter: blur(0.5rem);
|
||||
}
|
||||
to {
|
||||
letter-spacing: none;
|
||||
filter: blur(0rem);
|
||||
}
|
||||
}
|
||||
}
|
||||
27
src/app/components/PageLoader/PageLoader.jsx
Normal file
27
src/app/components/PageLoader/PageLoader.jsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
|
||||
const PageLoader = props => {
|
||||
return (
|
||||
<div className='c-PageLoader'>
|
||||
<div className='is-animate'>
|
||||
<div className='l'>l</div>
|
||||
<div className='l'>o</div>
|
||||
<div className='l'>a</div>
|
||||
<div className='l'>d</div>
|
||||
<div className='l'>i</div>
|
||||
<div className='l'>n</div>
|
||||
<div className='l'>g</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
};
|
||||
|
||||
PageLoader.defaultProps = {
|
||||
|
||||
};
|
||||
|
||||
PageLoader.propTypes = {
|
||||
|
||||
};
|
||||
|
||||
export default PageLoader;
|
||||
8
src/app/components/PageLoader/PageLoader.test.js
Normal file
8
src/app/components/PageLoader/PageLoader.test.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import PageLoader from './PageLoader';
|
||||
|
||||
describe('PageLoader', () => {
|
||||
it('renders without error', () => {
|
||||
|
||||
});
|
||||
});
|
||||
3
src/app/components/PageLoader/index.js
Normal file
3
src/app/components/PageLoader/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import PageLoader from './PageLoader.jsx';
|
||||
|
||||
export default PageLoader;
|
||||
7
src/app/components/index.js
Normal file
7
src/app/components/index.js
Normal file
@@ -0,0 +1,7 @@
|
||||
/* PLOP_INJECT_IMPORT */
|
||||
import Header from './Header';
|
||||
|
||||
export {
|
||||
/* PLOP_INJECT_EXPORT */
|
||||
Header,
|
||||
}
|
||||
28
src/app/main.js
Normal file
28
src/app/main.js
Normal file
@@ -0,0 +1,28 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import thunk from 'redux-thunk'
|
||||
import Immutable from 'immutable'
|
||||
import {createStore, applyMiddleware, compose} from 'redux'
|
||||
import reducer from './reducer';
|
||||
import Router from "./router";
|
||||
import 'bootstrap/dist/css/bootstrap.min.css'
|
||||
import './main.scss'
|
||||
import * as serviceWorker from './serviceWorker';
|
||||
|
||||
const composeEnhancers =
|
||||
typeof window === 'object' &&
|
||||
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
|
||||
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
|
||||
serialize: { // prettier-ignore
|
||||
immutable: Immutable
|
||||
}
|
||||
}) : compose;
|
||||
const store = createStore(reducer, composeEnhancers(applyMiddleware(thunk)))
|
||||
|
||||
ReactDOM.render(<Router store={store} />, document.getElementById("root"));
|
||||
|
||||
// If you want your app to work offline and load faster, you can change
|
||||
// unregister() to register() below. Note this comes with some pitfalls.
|
||||
// Learn more about service workers: https://bit.ly/CRA-PWA
|
||||
// serviceWorker.unregister();
|
||||
serviceWorker.register();
|
||||
20
src/app/main.scss
Normal file
20
src/app/main.scss
Normal file
@@ -0,0 +1,20 @@
|
||||
@import "./styles/variables";
|
||||
@import "./styles/general";
|
||||
@import "./styles/components";
|
||||
@import "./styles/pages";
|
||||
|
||||
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
monospace;
|
||||
}
|
||||
45
src/app/pages/Home/Home.jsx
Normal file
45
src/app/pages/Home/Home.jsx
Normal file
@@ -0,0 +1,45 @@
|
||||
import React, {useEffect} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {connect} from 'react-redux';
|
||||
import {createPropsSelector} from 'reselect-immutable-helpers';
|
||||
import {isMobile} from './selectors';
|
||||
import {dispatchDeviceType} from './actions';
|
||||
import './Home.module.scss';
|
||||
|
||||
const Home = props => {
|
||||
const {dispatchDeviceType} = props
|
||||
useEffect(() => {
|
||||
dispatchDeviceType({isMobile: isMobile()})
|
||||
}, [dispatchDeviceType])
|
||||
|
||||
/* eslint no-useless-escape: 0 */
|
||||
const isMobile = (() => {
|
||||
var check = false;
|
||||
(function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera);
|
||||
return check;
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="c-Home">
|
||||
In Page Home
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Home.propTypes = {
|
||||
isMobile: PropTypes.bool,
|
||||
dispatchDeviceType: PropTypes.func
|
||||
}
|
||||
|
||||
const mapStateToProps = createPropsSelector({
|
||||
isMobile: isMobile
|
||||
})
|
||||
|
||||
const mapDispatchToProps = {
|
||||
dispatchDeviceType
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Home);
|
||||
3
src/app/pages/Home/Home.module.scss
Normal file
3
src/app/pages/Home/Home.module.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
.c-Home {
|
||||
|
||||
}
|
||||
8
src/app/pages/Home/Home.test.js
Normal file
8
src/app/pages/Home/Home.test.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import Home from './Home';
|
||||
|
||||
describe('Home', () => {
|
||||
it('renders without error', () => {
|
||||
|
||||
});
|
||||
});
|
||||
24
src/app/pages/Home/actions.js
Normal file
24
src/app/pages/Home/actions.js
Normal file
@@ -0,0 +1,24 @@
|
||||
export const UPDATE_FORM_VALUES = 'UPDATE_SECTION_DISPLAY_FORM_VALUES'
|
||||
export const UPDATE_FORM_ERRORS = 'UPDATE_SECTION_DISPLAY_FORM_ERRORS'
|
||||
export const IS_MOBILE = 'IS_MOBILE';
|
||||
|
||||
export const dispatchDeviceType = (isMobile) => {
|
||||
return {
|
||||
type: IS_MOBILE,
|
||||
payload: isMobile
|
||||
}
|
||||
}
|
||||
|
||||
export const updateFormValues = (formValues) => {
|
||||
return {
|
||||
type: UPDATE_FORM_VALUES,
|
||||
payload: formValues
|
||||
}
|
||||
}
|
||||
|
||||
export const updateFormErrors = (formErrors) => {
|
||||
return {
|
||||
type: UPDATE_FORM_ERRORS,
|
||||
payload: formErrors
|
||||
}
|
||||
}
|
||||
3
src/app/pages/Home/index.js
Normal file
3
src/app/pages/Home/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import Home from './Home.jsx';
|
||||
|
||||
export default Home;
|
||||
17
src/app/pages/Home/reducer.js
Normal file
17
src/app/pages/Home/reducer.js
Normal file
@@ -0,0 +1,17 @@
|
||||
import Immutable from 'immutable'
|
||||
import {IS_MOBILE, UPDATE_FORM_ERRORS, UPDATE_FORM_VALUES} from './actions'
|
||||
|
||||
const initialState = Immutable.Map()
|
||||
|
||||
const reducer = (state = initialState, action) => {
|
||||
switch (action.type) {
|
||||
case IS_MOBILE:
|
||||
case UPDATE_FORM_ERRORS:
|
||||
case UPDATE_FORM_VALUES:
|
||||
return state.mergeDeep(action.payload)
|
||||
default:
|
||||
return state
|
||||
}
|
||||
}
|
||||
|
||||
export default reducer
|
||||
15
src/app/pages/Home/selectors.js
Normal file
15
src/app/pages/Home/selectors.js
Normal file
@@ -0,0 +1,15 @@
|
||||
import {createSelector} from 'reselect'
|
||||
import {createGetSelector} from 'reselect-immutable-helpers'
|
||||
|
||||
const getData = ({data}) => data
|
||||
|
||||
export const getHome = createSelector(
|
||||
getData,
|
||||
(dataState) => {
|
||||
return dataState.pages.home
|
||||
}
|
||||
)
|
||||
|
||||
export const isMobile = createGetSelector(getHome, 'isMobile')
|
||||
export const getFormErrors = createGetSelector(getHome, 'formErrors')
|
||||
export const getFormValues = createGetSelector(getHome, 'formValues')
|
||||
9
src/app/pages/index.js
Normal file
9
src/app/pages/index.js
Normal file
@@ -0,0 +1,9 @@
|
||||
/* PLOP_INJECT_IMPORT */
|
||||
import LoginForm from './LoginForm';
|
||||
import Home from './Home';
|
||||
|
||||
export {
|
||||
/* PLOP_INJECT_EXPORT */
|
||||
LoginForm,
|
||||
Home,
|
||||
}
|
||||
10
src/app/reducer.js
Normal file
10
src/app/reducer.js
Normal file
@@ -0,0 +1,10 @@
|
||||
import {combineReducers} from 'redux'
|
||||
import homeReducer from './pages/Home/reducer'
|
||||
|
||||
export default combineReducers({
|
||||
data: combineReducers({
|
||||
pages: combineReducers({
|
||||
home: homeReducer
|
||||
})
|
||||
})
|
||||
})
|
||||
32
src/app/router.jsx
Normal file
32
src/app/router.jsx
Normal file
@@ -0,0 +1,32 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import {Provider} from 'react-redux'
|
||||
import {BrowserRouter, Route} from 'react-router-dom';
|
||||
import Loadable from 'react-loadable'
|
||||
import PageLoader from './components/PageLoader';
|
||||
|
||||
export const LoadableHome = Loadable({
|
||||
loader: () => import('./pages/Home'),
|
||||
loading: PageLoader
|
||||
})
|
||||
|
||||
class Router extends React.Component {
|
||||
|
||||
render() {
|
||||
const {store} = this.props
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<BrowserRouter basename="subset_trello">
|
||||
<Route exact path="/" component={LoadableHome} />
|
||||
<Route exact path="/todos/manage" component={LoadableHome} />
|
||||
</BrowserRouter>
|
||||
</Provider>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Router.propTypes = {
|
||||
store: PropTypes.object
|
||||
}
|
||||
|
||||
export default Router
|
||||
141
src/app/serviceWorker.js
Normal file
141
src/app/serviceWorker.js
Normal file
@@ -0,0 +1,141 @@
|
||||
// This optional code is used to register a service worker.
|
||||
// register() is not called by default.
|
||||
|
||||
// This lets the app load faster on subsequent visits in production, and gives
|
||||
// it offline capabilities. However, it also means that developers (and users)
|
||||
// will only see deployed updates on subsequent visits to a page, after all the
|
||||
// existing tabs open on the page have been closed, since previously cached
|
||||
// resources are updated in the background.
|
||||
|
||||
// To learn more about the benefits of this model and instructions on how to
|
||||
// opt-in, read https://bit.ly/CRA-PWA
|
||||
|
||||
const isLocalhost = Boolean(
|
||||
window.location.hostname === 'localhost' ||
|
||||
// [::1] is the IPv6 localhost address.
|
||||
window.location.hostname === '[::1]' ||
|
||||
// 127.0.0.0/8 are considered localhost for IPv4.
|
||||
window.location.hostname.match(
|
||||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
|
||||
)
|
||||
);
|
||||
|
||||
export function register(config) {
|
||||
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
|
||||
// The URL constructor is available in all browsers that support SW.
|
||||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
|
||||
if (publicUrl.origin !== window.location.origin) {
|
||||
// Our service worker won't work if PUBLIC_URL is on a different origin
|
||||
// from what our page is served on. This might happen if a CDN is used to
|
||||
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
|
||||
return;
|
||||
}
|
||||
|
||||
window.addEventListener('load', () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
|
||||
|
||||
if (isLocalhost) {
|
||||
// This is running on localhost. Let's check if a service worker still exists or not.
|
||||
checkValidServiceWorker(swUrl, config);
|
||||
|
||||
// Add some additional logging to localhost, pointing developers to the
|
||||
// service worker/PWA documentation.
|
||||
navigator.serviceWorker.ready.then(() => {
|
||||
console.log(
|
||||
'This web app is being served cache-first by a service ' +
|
||||
'worker. To learn more, visit https://bit.ly/CRA-PWA'
|
||||
);
|
||||
});
|
||||
} else {
|
||||
// Is not localhost. Just register service worker
|
||||
registerValidSW(swUrl, config);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function registerValidSW(swUrl, config) {
|
||||
navigator.serviceWorker
|
||||
.register(swUrl)
|
||||
.then(registration => {
|
||||
registration.onupdatefound = () => {
|
||||
const installingWorker = registration.installing;
|
||||
if (installingWorker == null) {
|
||||
return;
|
||||
}
|
||||
installingWorker.onstatechange = () => {
|
||||
if (installingWorker.state === 'installed') {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
// At this point, the updated precached content has been fetched,
|
||||
// but the previous service worker will still serve the older
|
||||
// content until all client tabs are closed.
|
||||
console.log(
|
||||
'New content is available and will be used when all ' +
|
||||
'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
|
||||
);
|
||||
|
||||
// Execute callback
|
||||
if (config && config.onUpdate) {
|
||||
config.onUpdate(registration);
|
||||
}
|
||||
} else {
|
||||
// At this point, everything has been precached.
|
||||
// It's the perfect time to display a
|
||||
// "Content is cached for offline use." message.
|
||||
console.log('Content is cached for offline use.');
|
||||
|
||||
// Execute callback
|
||||
if (config && config.onSuccess) {
|
||||
config.onSuccess(registration);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error during service worker registration:', error);
|
||||
});
|
||||
}
|
||||
|
||||
function checkValidServiceWorker(swUrl, config) {
|
||||
// Check if the service worker can be found. If it can't reload the page.
|
||||
fetch(swUrl, {
|
||||
headers: { 'Service-Worker': 'script' },
|
||||
})
|
||||
.then(response => {
|
||||
// Ensure service worker exists, and that we really are getting a JS file.
|
||||
const contentType = response.headers.get('content-type');
|
||||
if (
|
||||
response.status === 404 ||
|
||||
(contentType != null && contentType.indexOf('javascript') === -1)
|
||||
) {
|
||||
// No service worker found. Probably a different app. Reload the page.
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister().then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// Service worker found. Proceed as normal.
|
||||
registerValidSW(swUrl, config);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
console.log(
|
||||
'No internet connection found. App is running in offline mode.'
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
export function unregister() {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.ready
|
||||
.then(registration => {
|
||||
registration.unregister();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(error.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
5
src/app/setupTests.js
Normal file
5
src/app/setupTests.js
Normal file
@@ -0,0 +1,5 @@
|
||||
// jest-dom adds custom jest matchers for asserting on DOM nodes.
|
||||
// allows you to do things like:
|
||||
// expect(element).toHaveTextContent(/react/i)
|
||||
// learn more: https://github.com/testing-library/jest-dom
|
||||
import '@testing-library/jest-dom/extend-expect';
|
||||
0
src/app/styles/_components.scss
Normal file
0
src/app/styles/_components.scss
Normal file
0
src/app/styles/_general.scss
Normal file
0
src/app/styles/_general.scss
Normal file
0
src/app/styles/_pages.scss
Normal file
0
src/app/styles/_pages.scss
Normal file
0
src/app/styles/_variables.scss
Normal file
0
src/app/styles/_variables.scss
Normal file
1
src/index.js
Normal file
1
src/index.js
Normal file
@@ -0,0 +1 @@
|
||||
import './app/main';
|
||||
Reference in New Issue
Block a user