├── .eslintrc.js ├── .gitignore ├── .prettierrc.js ├── README.md ├── build └── bundle.js ├── client ├── App.jsx ├── actions │ ├── actionTypes.js │ └── actions.js ├── components │ ├── Homepage.jsx │ ├── NavBar.jsx │ ├── PlantShelf.jsx │ ├── Queries.jsx │ ├── RowQueries.jsx │ └── Signup.jsx ├── index.js ├── reducers │ ├── index.js │ └── plantsReducer.js ├── store.js └── styles.css ├── index.html ├── package-lock.json ├── package.json ├── server ├── controllers │ └── plantController.js ├── models │ └── plantModels.js ├── routes │ └── api.js └── server.js └── webpack.config.js /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['airbnb', 'plugin:prettier/recommended', 'prettier/react'], 3 | env: { 4 | browser: true, 5 | commonjs: true, 6 | es6: true, 7 | jest: true, 8 | node: true, 9 | }, 10 | rules: { 11 | 'no-await-in-loop': 'off', 12 | 'no-param-reassign': 'off', 13 | 'import/extensions': 'off', 14 | 'jsx-a11y/interactive-supports-focus': 'off', 15 | 'jsx-a11y/click-events-have-key-events': 'off', 16 | 'jsx-a11y/click-events-have-key-events': 'off', 17 | 'react/prop-types': 'off', 18 | 'jsx-a11y/label-has-associated-control': 'off', 19 | 'react/self-closing-comp': 'off', 20 | 'react/prefer-stateless-function': 'off', 21 | 'react/button-has-type': 'off', 22 | 'func-names': 'off', 23 | 'one-var': 'off', 24 | 'no-console': 'off', 25 | 'no-plusplus': 'off', 26 | 'jsx-a11y/href-no-hash': ['off'], 27 | 'react/jsx-filename-extension': ['warn', { extensions: ['.js', '.jsx'] }], 28 | 'max-len': [ 29 | 'warn', 30 | { 31 | code: 80, 32 | tabWidth: 2, 33 | comments: 80, 34 | ignoreComments: false, 35 | ignoreTrailingComments: true, 36 | ignoreUrls: true, 37 | ignoreStrings: true, 38 | ignoreTemplateLiterals: true, 39 | ignoreRegExpLiterals: true, 40 | }, 41 | ], 42 | }, 43 | }; 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .vscode/settings.json 3 | config 4 | build 5 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 80, 3 | singleQuote: true, 4 | trailingComma: 'es5', 5 | arrowParens: 'avoid', 6 | }; 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Green Thumb 2 | 3 | Green Thumb is a site for users to look for plants they want to care for. Types of plants can be filtered by factors such as amount of water required, ability for plants to regrow, when plants bloom, how quickly plants can grow, and more. Users can save the plants they are interested on a "plant shelf" and revisit them as consultation for care, or to add personalized notes on the experience caring for the plant. 4 | 5 | By team Red-Lipped Batfish 6 | 7 | ## Getting Started 8 | 9 | Fork the project into your own repo. 10 | 11 | 12 | ### Installation 13 | 14 | To install, in the folder of the project run the following in your terminal: 15 | 16 | ``` 17 | npm install 18 | npm run build 19 | ``` 20 | 21 | To access server, run the following in your terminal. Upon saving, the page should automatically refresh. 22 | 23 | ``` 24 | npm run dev 25 | ``` 26 | 27 | ## Using the MongoDB Database 28 | Add your own Mongo URI to the config/config.env file 29 | 30 | ``` 31 | PORT=3000 32 | 33 | MONGO_URI = 'mongodb+srv://YOUR_USERNAME:YOUR_PASSWORD@cluster0-e8abe.mongodb.net/test?retryWrites=true&w=majority' 34 | 35 | ``` 36 | 37 | ## Built With 38 | 39 | * [React] 40 | * [Redux] 41 | * [Express] 42 | * [MongoDB Atlas] 43 | 44 | 45 | 46 | ## Authors/Contributing 47 | 48 | *[Keriann Lin](https://github.com/keliphan) 49 | *[Lia Pham](https://github.com/lpham598) 50 | *[Tommy Han](https://github.com/simplesifu) 51 | *[Fan Shao](https://github.com/fansfansfansfans) 52 | 53 | 54 | ## License 55 | 56 | This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details 57 | 58 | ## Acknowledgments 59 | 60 | * Shoutout to Codesmith 61 | -------------------------------------------------------------------------------- /build/bundle.js: -------------------------------------------------------------------------------- 1 | !function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=24)}([function(e,t,n){"use strict";e.exports=n(15)},function(e,t,n){"use strict";function r(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}n.d(t,"a",(function(){return r}))},function(e,t,n){"use strict";n.r(t),n.d(t,"__DO_NOT_USE__ActionTypes",(function(){return a})),n.d(t,"applyMiddleware",(function(){return y})),n.d(t,"bindActionCreators",(function(){return f})),n.d(t,"combineReducers",(function(){return c})),n.d(t,"compose",(function(){return h})),n.d(t,"createStore",(function(){return l}));var r=n(8),o=function(){return Math.random().toString(36).substring(7).split("").join(".")},a={INIT:"@@redux/INIT"+o(),REPLACE:"@@redux/REPLACE"+o(),PROBE_UNKNOWN_ACTION:function(){return"@@redux/PROBE_UNKNOWN_ACTION"+o()}};function i(e){if("object"!=typeof e||null===e)return!1;for(var t=e;null!==Object.getPrototypeOf(t);)t=Object.getPrototypeOf(t);return Object.getPrototypeOf(e)===t}function l(e,t,n){var o;if("function"==typeof t&&"function"==typeof n||"function"==typeof n&&"function"==typeof arguments[3])throw new Error("It looks like you are passing several store enhancers to createStore(). This is not supported. Instead, compose them together to a single function.");if("function"==typeof t&&void 0===n&&(n=t,t=void 0),void 0!==n){if("function"!=typeof n)throw new Error("Expected the enhancer to be a function.");return n(l)(e,t)}if("function"!=typeof e)throw new Error("Expected the reducer to be a function.");var u=e,c=t,s=[],f=s,p=!1;function d(){f===s&&(f=s.slice())}function m(){if(p)throw new Error("You may not call store.getState() while the reducer is executing. The reducer has already received the state as an argument. Pass it down from the top reducer instead of reading it from the store.");return c}function h(e){if("function"!=typeof e)throw new Error("Expected the listener to be a function.");if(p)throw new Error("You may not call store.subscribe() while the reducer is executing. If you would like to be notified after the store has been updated, subscribe from a component and invoke store.getState() in the callback to access the latest state. See https://redux.js.org/api-reference/store#subscribelistener for more details.");var t=!0;return d(),f.push(e),function(){if(t){if(p)throw new Error("You may not unsubscribe from a store listener while the reducer is executing. See https://redux.js.org/api-reference/store#subscribelistener for more details.");t=!1,d();var n=f.indexOf(e);f.splice(n,1),s=null}}}function y(e){if(!i(e))throw new Error("Actions must be plain objects. Use custom middleware for async actions.");if(void 0===e.type)throw new Error('Actions may not have an undefined "type" property. Have you misspelled a constant?');if(p)throw new Error("Reducers may not dispatch actions.");try{p=!0,c=u(c,e)}finally{p=!1}for(var t=s=f,n=0;nN.length&&N.push(e)}function M(e,t,n){return null==e?0:function e(t,n,r,o){var l=typeof t;"undefined"!==l&&"boolean"!==l||(t=null);var u=!1;if(null===t)u=!0;else switch(l){case"string":case"number":u=!0;break;case"object":switch(t.$$typeof){case a:case i:u=!0}}if(u)return r(o,t,""===n?"."+I(t,0):n),1;if(u=0,n=""===n?".":n+":",Array.isArray(t))for(var c=0;c