├── Procfile ├── .gitignore ├── frontend ├── .gitignore ├── public │ ├── robots.txt │ ├── favicon.ico │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── index.html ├── src │ ├── images │ │ ├── 1.jpg │ │ ├── 2.jpg │ │ ├── 3.jpg │ │ ├── food.png │ │ ├── food1.png │ │ ├── image1.png │ │ ├── image2.png │ │ ├── image3.png │ │ ├── image4.png │ │ ├── image5.png │ │ ├── image6.png │ │ ├── image7.png │ │ ├── image8.png │ │ ├── image9.jpg │ │ ├── rotli.jpg │ │ ├── cooking.png │ │ ├── dalbhat.jpg │ │ ├── donation.png │ │ ├── image33.jpg │ │ ├── image88.jpg │ │ ├── khicadi.jpg │ │ ├── pavbhaji.jpg │ │ ├── winning.png │ │ ├── chronometer.png │ │ ├── gold-medal.png │ │ ├── image3 - Copy.png │ │ └── restaurant-cutlery-circular-symbol-of-a-spoon-and-a-fork-in-a-circle.png │ ├── context │ │ └── auth-context.js │ ├── setupTests.js │ ├── App.test.js │ ├── api │ │ └── api.js │ ├── components │ │ ├── Footer.js │ │ ├── MapNew.js │ │ ├── MapFood.js │ │ ├── Header.js │ │ ├── Food.js │ │ ├── ViewUser.js │ │ ├── DisplayUserRecFood.js │ │ ├── DisplayUserDonFood.js │ │ ├── DisplayContributors.js │ │ ├── ViewFood.js │ │ ├── MapFoodComp.js │ │ ├── DisplayDetailUserRecFood.js │ │ ├── Map.js │ │ ├── RecViewFood.js │ │ ├── MapComp.js │ │ └── DisplayDetailUserDonFood.js │ ├── index.css │ ├── reportWebVitals.js │ ├── hooks │ │ ├── http-hook.js │ │ └── auth-hook.js │ ├── App.css │ ├── index.js │ ├── screens │ │ ├── ReqForFood.js │ │ ├── Contributors.js │ │ ├── ViewProfile.js │ │ ├── UserDonFood.js │ │ ├── UserRecFood.js │ │ ├── DetailUserDonFood.js │ │ ├── DetailUserRecFood.js │ │ ├── ReqViewFood.js │ │ ├── Timer.js │ │ ├── ResetPassword.js │ │ ├── NewPassword.js │ │ ├── Home.js │ │ ├── Login.js │ │ ├── Contact.js │ │ ├── EditProfile.js │ │ ├── Signup.js │ │ └── Donate.js │ └── App.js ├── package.json └── README.md ├── models ├── http-error.js ├── receive.js ├── user.js └── food.js ├── controllers ├── error-controller.js ├── user-controllers.js └── food-controller.js ├── middleware └── check-auth.js ├── package.json ├── routes └── user-routes.js └── app.js /Procfile: -------------------------------------------------------------------------------- 1 | web:node app.js -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | .env -------------------------------------------------------------------------------- /frontend/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | .env -------------------------------------------------------------------------------- /frontend/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /frontend/src/images/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaheshVegada/Waste-Food-Management-System-MERN-Stack/HEAD/frontend/src/images/1.jpg -------------------------------------------------------------------------------- /frontend/src/images/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaheshVegada/Waste-Food-Management-System-MERN-Stack/HEAD/frontend/src/images/2.jpg -------------------------------------------------------------------------------- /frontend/src/images/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaheshVegada/Waste-Food-Management-System-MERN-Stack/HEAD/frontend/src/images/3.jpg -------------------------------------------------------------------------------- /frontend/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaheshVegada/Waste-Food-Management-System-MERN-Stack/HEAD/frontend/public/favicon.ico -------------------------------------------------------------------------------- /frontend/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaheshVegada/Waste-Food-Management-System-MERN-Stack/HEAD/frontend/public/logo192.png -------------------------------------------------------------------------------- /frontend/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaheshVegada/Waste-Food-Management-System-MERN-Stack/HEAD/frontend/public/logo512.png -------------------------------------------------------------------------------- /frontend/src/images/food.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaheshVegada/Waste-Food-Management-System-MERN-Stack/HEAD/frontend/src/images/food.png -------------------------------------------------------------------------------- /frontend/src/images/food1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaheshVegada/Waste-Food-Management-System-MERN-Stack/HEAD/frontend/src/images/food1.png -------------------------------------------------------------------------------- /frontend/src/images/image1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaheshVegada/Waste-Food-Management-System-MERN-Stack/HEAD/frontend/src/images/image1.png -------------------------------------------------------------------------------- /frontend/src/images/image2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaheshVegada/Waste-Food-Management-System-MERN-Stack/HEAD/frontend/src/images/image2.png -------------------------------------------------------------------------------- /frontend/src/images/image3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaheshVegada/Waste-Food-Management-System-MERN-Stack/HEAD/frontend/src/images/image3.png -------------------------------------------------------------------------------- /frontend/src/images/image4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaheshVegada/Waste-Food-Management-System-MERN-Stack/HEAD/frontend/src/images/image4.png -------------------------------------------------------------------------------- /frontend/src/images/image5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaheshVegada/Waste-Food-Management-System-MERN-Stack/HEAD/frontend/src/images/image5.png -------------------------------------------------------------------------------- /frontend/src/images/image6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaheshVegada/Waste-Food-Management-System-MERN-Stack/HEAD/frontend/src/images/image6.png -------------------------------------------------------------------------------- /frontend/src/images/image7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaheshVegada/Waste-Food-Management-System-MERN-Stack/HEAD/frontend/src/images/image7.png -------------------------------------------------------------------------------- /frontend/src/images/image8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaheshVegada/Waste-Food-Management-System-MERN-Stack/HEAD/frontend/src/images/image8.png -------------------------------------------------------------------------------- /frontend/src/images/image9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaheshVegada/Waste-Food-Management-System-MERN-Stack/HEAD/frontend/src/images/image9.jpg -------------------------------------------------------------------------------- /frontend/src/images/rotli.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaheshVegada/Waste-Food-Management-System-MERN-Stack/HEAD/frontend/src/images/rotli.jpg -------------------------------------------------------------------------------- /frontend/src/images/cooking.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaheshVegada/Waste-Food-Management-System-MERN-Stack/HEAD/frontend/src/images/cooking.png -------------------------------------------------------------------------------- /frontend/src/images/dalbhat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaheshVegada/Waste-Food-Management-System-MERN-Stack/HEAD/frontend/src/images/dalbhat.jpg -------------------------------------------------------------------------------- /frontend/src/images/donation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaheshVegada/Waste-Food-Management-System-MERN-Stack/HEAD/frontend/src/images/donation.png -------------------------------------------------------------------------------- /frontend/src/images/image33.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaheshVegada/Waste-Food-Management-System-MERN-Stack/HEAD/frontend/src/images/image33.jpg -------------------------------------------------------------------------------- /frontend/src/images/image88.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaheshVegada/Waste-Food-Management-System-MERN-Stack/HEAD/frontend/src/images/image88.jpg -------------------------------------------------------------------------------- /frontend/src/images/khicadi.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaheshVegada/Waste-Food-Management-System-MERN-Stack/HEAD/frontend/src/images/khicadi.jpg -------------------------------------------------------------------------------- /frontend/src/images/pavbhaji.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaheshVegada/Waste-Food-Management-System-MERN-Stack/HEAD/frontend/src/images/pavbhaji.jpg -------------------------------------------------------------------------------- /frontend/src/images/winning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaheshVegada/Waste-Food-Management-System-MERN-Stack/HEAD/frontend/src/images/winning.png -------------------------------------------------------------------------------- /frontend/src/images/chronometer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaheshVegada/Waste-Food-Management-System-MERN-Stack/HEAD/frontend/src/images/chronometer.png -------------------------------------------------------------------------------- /frontend/src/images/gold-medal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaheshVegada/Waste-Food-Management-System-MERN-Stack/HEAD/frontend/src/images/gold-medal.png -------------------------------------------------------------------------------- /frontend/src/images/image3 - Copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaheshVegada/Waste-Food-Management-System-MERN-Stack/HEAD/frontend/src/images/image3 - Copy.png -------------------------------------------------------------------------------- /models/http-error.js: -------------------------------------------------------------------------------- 1 | class HttpError extends Error { 2 | constructor(message, errorCode) { 3 | super(message); 4 | this.code = errorCode; 5 | console.log(message); 6 | } 7 | } 8 | 9 | module.exports = HttpError; -------------------------------------------------------------------------------- /frontend/src/context/auth-context.js: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | 3 | export const AuthContext = createContext({ 4 | isLoggedIn: false, 5 | userId: null, 6 | token: null, 7 | login: () => {}, 8 | logout: () => {} 9 | }); 10 | -------------------------------------------------------------------------------- /frontend/src/images/restaurant-cutlery-circular-symbol-of-a-spoon-and-a-fork-in-a-circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaheshVegada/Waste-Food-Management-System-MERN-Stack/HEAD/frontend/src/images/restaurant-cutlery-circular-symbol-of-a-spoon-and-a-fork-in-a-circle.png -------------------------------------------------------------------------------- /frontend/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /frontend/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /frontend/src/api/api.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | 3 | export const BASE_API_URL = 4 | process.env.NODE_ENV === 'production' 5 | ? '/api/users' 6 | : 'http://localhost:5000/api/users' 7 | 8 | axios.defaults.headers.common['authorization'] = localStorage.getItem('token') 9 | 10 | export default axios -------------------------------------------------------------------------------- /controllers/error-controller.js: -------------------------------------------------------------------------------- 1 | const HttpError = require('../models/http-error'); 2 | 3 | const error = (req,res,next) =>{ 4 | const err = new HttpError( 5 | '404 Page Not Found, Please go back!', 6 | 404 7 | ); 8 | console.log(err); 9 | res.send(err); 10 | return(err); 11 | } 12 | exports.error = error; -------------------------------------------------------------------------------- /frontend/src/components/Footer.js: -------------------------------------------------------------------------------- 1 | function Footer() { 2 | return ( 3 | 7 | ) 8 | } 9 | 10 | export default Footer; -------------------------------------------------------------------------------- /frontend/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /frontend/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /frontend/src/components/MapNew.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import MapComp from './MapComp'; 3 | 4 | class MapNew extends Component { 5 | 6 | render() { 7 | return( 8 |
9 | 16 |
17 | ); 18 | } 19 | } 20 | 21 | export default MapNew; 22 | -------------------------------------------------------------------------------- /frontend/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /frontend/src/components/MapFood.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import MapFoodComp from './MapFoodComp'; 3 | 4 | class MapFood extends Component { 5 | constructor() { 6 | super(); 7 | this.state = { 8 | lat: 22.989333000000002, 9 | lng: 72.62911440209957 10 | }; 11 | } 12 | render() { 13 | return( 14 |
15 | 21 |
22 | ); 23 | } 24 | } 25 | 26 | export default MapFood; -------------------------------------------------------------------------------- /models/receive.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | const User = require('./user'); 3 | const Food = require('./food'); 4 | const Schema = mongoose.Schema; 5 | 6 | const receiveSchema = new Schema({ 7 | donId: {type: mongoose.Types.ObjectId, ref: 'User' }, 8 | foodId: {type: mongoose.Types.ObjectId, ref: 'Food' }, 9 | recId: {type: mongoose.Types.ObjectId, ref: 'User' }, 10 | name: { type: String, required: true }, 11 | email: { type: String, required: true }, 12 | mobile: {type: Number, required: true }, 13 | address: { type: String, required: true }, 14 | exptime: { type: Date, required: true} 15 | }); 16 | 17 | module.exports = mongoose.model('Receive', receiveSchema); -------------------------------------------------------------------------------- /frontend/src/hooks/http-hook.js: -------------------------------------------------------------------------------- 1 | import { useCallback } from 'react'; 2 | 3 | export const useHttpClient = () => { 4 | 5 | const sendRequest = useCallback( 6 | async (url, method = 'GET', body = null, headers = {}) => { 7 | 8 | try { 9 | const response = await fetch(url, { 10 | method, 11 | body, 12 | headers 13 | }); 14 | 15 | const responseData = await response.json(); 16 | 17 | if (!response.ok) { 18 | return responseData.message; 19 | } 20 | return responseData; 21 | } 22 | catch (err) { 23 | return err; 24 | } 25 | }, 26 | [] 27 | ); 28 | 29 | return { sendRequest }; 30 | }; 31 | -------------------------------------------------------------------------------- /frontend/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /frontend/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | class Doc extends React.Component{ 8 | componentDidMount(){ 9 | document.title = "We Dont Waste Food" 10 | } 11 | render(){ 12 | return(
) 13 | } 14 | } 15 | 16 | ReactDOM.render( 17 | 18 | 19 | 20 | , 21 | document.getElementById('root') 22 | ); 23 | 24 | // If you want to start measuring performance in your app, pass a function 25 | // to log results (for example: reportWebVitals(console.log)) 26 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 27 | reportWebVitals(); 28 | -------------------------------------------------------------------------------- /middleware/check-auth.js: -------------------------------------------------------------------------------- 1 | const jwt = require('jsonwebtoken'); 2 | const HttpError = require('../models/http-error'); 3 | require('dotenv').config(); 4 | 5 | module.exports = (req, res, next) => { 6 | if (req.method === 'OPTIONS') { 7 | return next(); 8 | } 9 | try { 10 | const token = req.headers.authorization.split(' ')[1]; // Authorization: 'Bearer TOKEN' 11 | if (!token) { 12 | throw new Error('Authentication failed!'); 13 | } 14 | const decodedToken = jwt.verify(token, process.env.SECRET_KEY); 15 | req.userData = { userId: decodedToken.userId }; 16 | console.log("I am Middleware Authentication"); 17 | next(); 18 | } catch (err) { 19 | const error = new HttpError('Authentication failed!', 403); 20 | console.log("Authentication Failed"); 21 | return next(error); 22 | } 23 | }; -------------------------------------------------------------------------------- /frontend/src/screens/ReqForFood.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable react-hooks/exhaustive-deps */ 2 | import React, { useEffect, useState } from 'react'; 3 | import { useHttpClient } from "../hooks/http-hook"; 4 | import Food from '../components/Food'; 5 | import {BASE_API_URL} from '../api/api'; 6 | 7 | const ReqForFood = () => { 8 | 9 | const { sendRequest } = useHttpClient(); 10 | const [loadedFood, setLoadedFood] = useState(); 11 | 12 | useEffect(() => { 13 | const fetchFoods = async () => { 14 | try { 15 | const responseData = await sendRequest( 16 | BASE_API_URL+'/request', 17 | ); 18 | setLoadedFood(responseData.foods); 19 | } catch (err) { } 20 | }; 21 | fetchFoods(); 22 | }, [sendRequest]); 23 | 24 | return ( 25 | 26 | {loadedFood && } 27 | 28 | ); 29 | }; 30 | 31 | export default ReqForFood; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "we-dont-waste-food", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node app.js", 9 | "heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix frontend && npm run build --prefix frontend" 10 | }, 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "axios": "^0.21.4", 15 | "bcryptjs": "^2.4.3", 16 | "body-parser": "^1.19.0", 17 | "cors": "^2.8.5", 18 | "date-and-time": "^0.14.2", 19 | "dotenv": "^8.6.0", 20 | "express": "^4.17.1", 21 | "express-validator": "^6.12.2", 22 | "jsonwebtoken": "^8.5.1", 23 | "moment": "^2.29.1", 24 | "mongoose": "^5.13.9", 25 | "mongoose-unique-validator": "^2.0.3", 26 | "multer": "^1.4.3", 27 | "nodemailer": "^6.6.5", 28 | "nodemailer-sendgrid-transport": "^0.2.0", 29 | "nodemon": "^2.0.13", 30 | "uuid": "^8.3.2" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /frontend/src/screens/Contributors.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState} from 'react'; 2 | import { useHttpClient } from "../hooks/http-hook"; 3 | import DisplayContributors from '../components/DisplayContributors'; 4 | import {BASE_API_URL} from '../api/api'; 5 | 6 | const Contributors = () => { 7 | 8 | const { sendRequest } = useHttpClient(); 9 | const [contributors, setContributors] = useState(); 10 | 11 | useEffect(() => { 12 | const fetchContributors = async () => { 13 | try { 14 | const responseData = await sendRequest( 15 | BASE_API_URL+'/contributors' 16 | ); 17 | setContributors(responseData); 18 | } catch (err) {} 19 | }; 20 | fetchContributors(); 21 | }, [sendRequest]); 22 | 23 | return ( 24 | 25 | {contributors && } 26 | 27 | ); 28 | }; 29 | 30 | export default Contributors; -------------------------------------------------------------------------------- /models/user.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | const uniqueValidator = require('mongoose-unique-validator'); 3 | 4 | const Schema = mongoose.Schema; 5 | 6 | const userSchema = new Schema({ 7 | fullname: { type: String, required: true }, 8 | email: { type: String, required: true, unique: [true, "Email must be unique"] }, 9 | password: { type: String, required: true, minlength: [3, 'Password should have atleast 3 characters'] }, 10 | mobile: {type: Number, required: true }, 11 | gender: {type: String, required: true }, 12 | type: {type: String, required: true }, 13 | address: { type: String, required: true }, 14 | city: {type: String, required: true }, 15 | state: {type: String, required: true }, 16 | Url: {type: String, required: true }, 17 | datetime: { type: String, required: true}, 18 | resetToken: {type: String}, 19 | expireToken : { type: Date}}, 20 | {timestamps:true} 21 | ); 22 | 23 | userSchema.plugin(uniqueValidator); 24 | 25 | module.exports = mongoose.model('User', userSchema); 26 | -------------------------------------------------------------------------------- /models/food.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | const User = require('./user'); 3 | const Schema = mongoose.Schema; 4 | 5 | const foodSchema = new Schema({ 6 | userId: {type: mongoose.Types.ObjectId, ref: 'User' }, 7 | recId: {type: String, required: true}, 8 | funcname: { type: String, required: true }, 9 | name: { type: String, required: true }, 10 | mobile: {type: Number, required: true }, 11 | description: { type: String, required: true }, 12 | quantity: { type: String, required: true }, 13 | quality: {type: Number, required: true }, 14 | foodtype: {type: String, required: true }, 15 | cookedtime: { type: String, required: true}, 16 | expirytime: { type: Date, required: true}, 17 | status: {type: Boolean, required: true }, 18 | received: {type: Boolean, required: true}, 19 | address: { type: String, required: true }, 20 | city: {type: String, required: true }, 21 | state: {type: String, required: true }, 22 | lat: {type: Number, rewuired: true}, 23 | lng: {type: Number, rewuired: true}, 24 | Url: {type: String, required: true }, 25 | datetime: { type: String, required: true}, 26 | resetToken: {type: String}, 27 | expireToken : { type: Date} 28 | }); 29 | 30 | module.exports = mongoose.model('Food', foodSchema); -------------------------------------------------------------------------------- /frontend/src/screens/ViewProfile.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable react-hooks/exhaustive-deps */ 2 | import React, { useEffect, useState, useContext } from 'react'; 3 | import { AuthContext } from "../context/auth-context"; 4 | import { useHttpClient } from "../hooks/http-hook"; 5 | import ViewUser from '../components/ViewUser'; 6 | import {BASE_API_URL} from '../api/api'; 7 | 8 | const ViewProfile = () => { 9 | 10 | const auth = useContext(AuthContext); 11 | const { sendRequest } = useHttpClient(); 12 | const [loadedUser, setloadedUser] = useState(); 13 | 14 | useEffect(() => { 15 | const fetchUsers = async () => { 16 | try { 17 | const responseData = await sendRequest( 18 | BASE_API_URL+'/viewprofile', 19 | 'POST', 20 | JSON.stringify({ 21 | }), 22 | { 23 | 'Content-Type': 'application/json', 24 | Authorization: 'Bearer ' + auth.token 25 | } 26 | ); 27 | setloadedUser(responseData); 28 | } catch (err) { } 29 | }; 30 | fetchUsers(); 31 | }, [sendRequest]); 32 | 33 | return ( 34 | 35 | {loadedUser && } 36 | 37 | ); 38 | }; 39 | 40 | export default ViewProfile; -------------------------------------------------------------------------------- /frontend/src/screens/UserDonFood.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable react-hooks/exhaustive-deps */ 2 | import React, { useEffect, useState, useContext } from 'react'; 3 | import { AuthContext } from "../context/auth-context"; 4 | import { useHttpClient } from "../hooks/http-hook"; 5 | import DisplayUserDonFood from '../components/DisplayUserDonFood'; 6 | import {BASE_API_URL} from '../api/api'; 7 | 8 | const UserDonFood = () => { 9 | 10 | const auth = useContext(AuthContext); 11 | const { sendRequest } = useHttpClient(); 12 | const [loadedFood, setLoadedFood] = useState(); 13 | 14 | useEffect(() => { 15 | const fetchFoods = async () => { 16 | try { 17 | const responseData = await sendRequest( 18 | BASE_API_URL+'/viewdonatedfood', 19 | 'POST', 20 | JSON.stringify({ 21 | }), 22 | { 23 | 'Content-Type': 'application/json', 24 | Authorization: 'Bearer ' + auth.token 25 | } 26 | ); 27 | setLoadedFood(responseData); 28 | } catch (err) { } 29 | }; 30 | fetchFoods(); 31 | }, [sendRequest]); 32 | 33 | return ( 34 | 35 | {loadedFood && } 36 | 37 | ); 38 | }; 39 | 40 | export default UserDonFood; 41 | -------------------------------------------------------------------------------- /frontend/src/screens/UserRecFood.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable react-hooks/exhaustive-deps */ 2 | import React, { useEffect, useState, useContext } from 'react'; 3 | import { AuthContext } from "../context/auth-context"; 4 | import { useHttpClient } from "../hooks/http-hook"; 5 | import DisplayUserRecFood from '../components/DisplayUserRecFood'; 6 | import {BASE_API_URL} from '../api/api'; 7 | 8 | const UserRecFood = () => { 9 | 10 | const auth = useContext(AuthContext); 11 | const { sendRequest } = useHttpClient(); 12 | const [loadedFood, setLoadedFood] = useState(); 13 | 14 | useEffect(() => { 15 | const fetchFoods = async () => { 16 | try { 17 | const responseData = await sendRequest( 18 | BASE_API_URL+'/viewreceivedfood', 19 | 'POST', 20 | JSON.stringify({ 21 | }), 22 | { 23 | 'Content-Type': 'application/json', 24 | Authorization: 'Bearer ' + auth.token 25 | } 26 | ); 27 | setLoadedFood(responseData); 28 | } catch (err) { } 29 | }; 30 | fetchFoods(); 31 | }, [sendRequest]); 32 | 33 | return ( 34 | 35 | {loadedFood && } 36 | 37 | ); 38 | }; 39 | 40 | export default UserRecFood; 41 | -------------------------------------------------------------------------------- /frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "we-dont-waste-food", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.14.1", 7 | "@testing-library/react": "^11.2.7", 8 | "@testing-library/user-event": "^12.8.3", 9 | "axios": "^0.21.4", 10 | "bootstrap": "^4.6.0", 11 | "dotenv": "^8.6.0", 12 | "google-maps-react": "^2.0.6", 13 | "mdbreact": "^5.1.0", 14 | "moment": "^2.29.1", 15 | "react": "^17.0.2", 16 | "react-bootstrap": "^1.6.4", 17 | "react-dom": "^17.0.2", 18 | "react-dotenv": "^0.1.3", 19 | "react-geocode": "^0.2.3", 20 | "react-google-autocomplete": "^1.3.0", 21 | "react-google-maps": "^9.4.5", 22 | "react-moment": "^1.1.1", 23 | "react-places-autocomplete": "^7.3.0", 24 | "react-router-dom": "^5.3.0", 25 | "react-scripts": "4.0.2", 26 | "web-vitals": "^1.1.2" 27 | }, 28 | "scripts": { 29 | "start": "react-scripts start", 30 | "build": "react-scripts build", 31 | "test": "react-scripts test", 32 | "eject": "react-scripts eject" 33 | }, 34 | "eslintConfig": { 35 | "extends": [ 36 | "react-app", 37 | "react-app/jest" 38 | ] 39 | }, 40 | "browserslist": { 41 | "production": [ 42 | ">0.2%", 43 | "not dead", 44 | "not op_mini all" 45 | ], 46 | "development": [ 47 | "last 1 chrome version", 48 | "last 1 firefox version", 49 | "last 1 safari version" 50 | ] 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /frontend/src/screens/DetailUserDonFood.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable react-hooks/exhaustive-deps */ 2 | import React, { useEffect, useState, useContext} from 'react'; 3 | import { useParams} from 'react-router-dom'; 4 | import { AuthContext } from "../context/auth-context"; 5 | import { useHttpClient } from "../hooks/http-hook"; 6 | import DisplayDetailUserDonFood from '../components/DisplayDetailUserDonFood'; 7 | import {BASE_API_URL} from '../api/api'; 8 | 9 | const DetailUserDonFood = () => { 10 | 11 | const auth = useContext(AuthContext); 12 | const foodId = useParams().foodId; 13 | const { sendRequest } = useHttpClient(); 14 | const [loadedFood, setLoadedFood] = useState(); 15 | 16 | useEffect(() => { 17 | const fetchFoods = async () => { 18 | try { 19 | const responseData = await sendRequest( 20 | BASE_API_URL+'/openviewdonatefood', 21 | 'POST', 22 | JSON.stringify({ 23 | foodId 24 | }), 25 | { 26 | 'Content-Type': 'application/json', 27 | Authorization: 'Bearer ' + auth.token 28 | } 29 | ); 30 | setLoadedFood(responseData); 31 | } catch (err) { } 32 | }; 33 | fetchFoods(); 34 | }, [sendRequest]); 35 | 36 | return ( 37 | 38 | {loadedFood && } 39 | 40 | ); 41 | }; 42 | 43 | export default DetailUserDonFood; 44 | -------------------------------------------------------------------------------- /frontend/src/screens/DetailUserRecFood.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable react-hooks/exhaustive-deps */ 2 | import React, { useEffect, useState, useContext} from 'react'; 3 | import { useParams} from 'react-router-dom'; 4 | import { AuthContext } from "../context/auth-context"; 5 | import { useHttpClient } from "../hooks/http-hook"; 6 | import DisplayDetailUserRecFood from '../components/DisplayDetailUserRecFood'; 7 | import {BASE_API_URL} from '../api/api'; 8 | 9 | const DetailUserRecFood = () => { 10 | 11 | const auth = useContext(AuthContext); 12 | const foodId = useParams().foodId; 13 | const { sendRequest } = useHttpClient(); 14 | const [loadedFood, setLoadedFood] = useState(); 15 | 16 | useEffect(() => { 17 | const fetchFoods = async () => { 18 | try { 19 | const responseData = await sendRequest( 20 | BASE_API_URL+'/openviewreceivedfood', 21 | 'POST', 22 | JSON.stringify({ 23 | foodId 24 | }), 25 | { 26 | 'Content-Type': 'application/json', 27 | Authorization: 'Bearer ' + auth.token 28 | } 29 | ); 30 | setLoadedFood(responseData); 31 | } catch (err) { } 32 | }; 33 | fetchFoods(); 34 | }, [sendRequest]); 35 | 36 | return ( 37 | 38 | {loadedFood && } 39 | 40 | ); 41 | }; 42 | 43 | export default DetailUserRecFood; 44 | -------------------------------------------------------------------------------- /frontend/src/screens/ReqViewFood.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable react-hooks/exhaustive-deps */ 2 | import React, { useEffect, useState, useContext } from 'react'; 3 | import { AuthContext } from "../context/auth-context"; 4 | import { useParams } from 'react-router-dom'; 5 | import { useHttpClient } from "../hooks/http-hook"; 6 | import ViewFood from '../components/ViewFood'; 7 | import RecViewFood from '../components/RecViewFood'; 8 | import {BASE_API_URL} from '../api/api'; 9 | 10 | const ReqViewFood = () => { 11 | 12 | const auth = useContext(AuthContext); 13 | const foodId = useParams().foodId; 14 | const { sendRequest } = useHttpClient(); 15 | 16 | const [loadedFood, setloadedFood] = useState(); 17 | 18 | useEffect(() => { 19 | const fetchUsers = async () => { 20 | try { 21 | const responseData = await sendRequest( 22 | BASE_API_URL+'/viewfood', 23 | 'POST', 24 | JSON.stringify({ 25 | foodId 26 | }), 27 | { 28 | 'Content-Type': 'application/json', 29 | Authorization: 'Bearer ' + auth.token 30 | } 31 | ); 32 | setloadedFood(responseData); 33 | } catch (err) { } 34 | }; 35 | fetchUsers(); 36 | }, [sendRequest]); 37 | return ( 38 | 39 | {loadedFood && } 40 | {loadedFood && } 41 | 42 | ); 43 | }; 44 | 45 | export default ReqViewFood; -------------------------------------------------------------------------------- /frontend/src/hooks/auth-hook.js: -------------------------------------------------------------------------------- 1 | import { useState, useCallback, useEffect } from 'react'; 2 | 3 | let logoutTimer; 4 | 5 | export const useAuth = () => { 6 | const [token, setToken] = useState(false); 7 | const [tokenExpirationDate, setTokenExpirationDate] = useState(); 8 | const [userId, setUserId] = useState(false); 9 | 10 | const login = useCallback((uid, token, expirationDate) => { 11 | setToken(token); 12 | setUserId(uid); 13 | const tokenExpirationDate = 14 | expirationDate || new Date(new Date().getTime() + 1000 * 60 * 60); 15 | setTokenExpirationDate(tokenExpirationDate); 16 | localStorage.setItem( 17 | 'userData', 18 | JSON.stringify({ 19 | userId: uid, 20 | token: token, 21 | expiration: tokenExpirationDate.toISOString() 22 | }) 23 | ); 24 | }, []); 25 | 26 | const logout = useCallback(() => { 27 | setToken(null); 28 | setTokenExpirationDate(null); 29 | setUserId(null); 30 | localStorage.removeItem('userData'); 31 | }, []); 32 | 33 | useEffect(() => { 34 | if (token && tokenExpirationDate) { 35 | const remainingTime = tokenExpirationDate.getTime() - new Date().getTime(); 36 | logoutTimer = setTimeout(logout, remainingTime); 37 | } else { 38 | clearTimeout(logoutTimer); 39 | } 40 | }, [token, logout, tokenExpirationDate]); 41 | 42 | useEffect(() => { 43 | const storedData = JSON.parse(localStorage.getItem('userData')); 44 | if ( 45 | storedData && 46 | storedData.token && 47 | new Date(storedData.expiration) > new Date() 48 | ) { 49 | login(storedData.userId, storedData.token, new Date(storedData.expiration)); 50 | } 51 | }, [login]); 52 | 53 | return { token, login, logout, userId}; 54 | }; -------------------------------------------------------------------------------- /routes/user-routes.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const { check } = require('express-validator'); 3 | const usersController = require('../controllers/user-controllers'); 4 | const foodController = require('../controllers/food-controller'); 5 | const Authenticate = require('../middleware/check-auth'); 6 | const router = express.Router(); 7 | 8 | router.post( 9 | '/signup', 10 | [ 11 | check('fullname') 12 | .not() 13 | .isEmpty(), 14 | check('email') 15 | .normalizeEmail() 16 | .isEmail(), 17 | check('password').isLength({ min: 3 }) 18 | ], 19 | usersController.signup 20 | ); 21 | 22 | router.post('/login', usersController.login); 23 | router.post('/reset-password', usersController.resetPassword); 24 | router.post('/new-password', usersController.newPassword); 25 | router.post('/viewprofile', Authenticate, usersController.viewProfile); 26 | router.post('/editprofile', Authenticate, usersController.editProfile); 27 | 28 | router.post('/donate', Authenticate, foodController.addfood); 29 | router.get('/request', foodController.getFood); 30 | router.delete('/deletefood', Authenticate, foodController.deletefood); 31 | router.post('/viewfood', Authenticate, foodController.viewfood); 32 | router.post('/acceptfood', Authenticate, foodController.acceptfood); 33 | router.post('/viewdonatedfood', Authenticate, foodController.viewdonatedfood); 34 | router.post('/viewreceivedfood', Authenticate, foodController.viewreceivedfood); 35 | router.post('/openviewdonatefood', Authenticate, foodController.openviewdonatefood); 36 | router.post('/openviewreceivedfood', Authenticate, foodController.openviewreceivedfood); 37 | router.post('/receivedfood', Authenticate, foodController.receivedfood); 38 | router.post('/cancelledfood', Authenticate, foodController.cancelledfood); 39 | router.get('/contributors', foodController.contributors); 40 | 41 | module.exports = router; 42 | -------------------------------------------------------------------------------- /frontend/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | We Don't Waste Food 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const bodyParser = require('body-parser'); 3 | const mongoose = require('mongoose'); 4 | const cors = require('cors'); 5 | 6 | const HttpError = require('./models/http-error'); 7 | const usersRoutes = require('./routes/user-routes'); 8 | 9 | require('dotenv').config(); 10 | 11 | const app = express(); 12 | app.use(express.json()) 13 | 14 | app.use((req, res, next) => { 15 | res.setHeader('Access-Control-Allow-Origin', '*'); 16 | res.setHeader( 17 | 'Access-Control-Allow-Headers', 18 | 'Origin, X-Requested-With, Content-Type, Accept, Authorization' 19 | ); 20 | res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PATCH, DELETE'); 21 | next(); 22 | }); 23 | 24 | app.use('/api/users', usersRoutes); 25 | 26 | const allowedOrigins = [ 27 | 'http://localhost:3000', 28 | 'http://localhost:5000', 29 | 'http://we-dont-waste-food.herokuapp.com', 30 | 'https://we-dont-waste-food.herokuapp.com', 31 | 'https://api.cloudinary.com/v1_1/wdwfsdp/image/upload' 32 | ] 33 | // app.use( 34 | // cors({ 35 | // origin: function (origin, callback) { 36 | // if (!origin) return callback(null, true) 37 | // if (allowedOrigins.indexOf(origin) === -1) { 38 | // var msg = 39 | // 'The CORS policy for this site does not ' + 40 | // 'allow access from the specified Origin.' 41 | // return callback(new Error(msg), false) 42 | // } 43 | // return callback(null, true) 44 | // }, 45 | // }) 46 | // ) 47 | 48 | if(process.env.NODE_ENV == "production"){ 49 | app.use(express.static("frontend/build")); 50 | const path = require("path"); 51 | app.get("*", (req, res) => { 52 | res.sendFile(path.resolve(__dirname, 'frontend', 'build', 'index.html')); 53 | }) 54 | } 55 | 56 | mongoose 57 | .connect( 58 | process.env.MONGO_URI, {"useNewUrlParser": true, "useUnifiedTopology": true, 'useCreateIndex': true} 59 | ) 60 | .then(() => { 61 | console.log("Database connected"); 62 | }) 63 | .catch(err => { 64 | console.log(err); 65 | } 66 | ); 67 | 68 | const PORT = process.env.PORT || 5000; 69 | app.listen(PORT); -------------------------------------------------------------------------------- /frontend/src/components/Header.js: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react'; 2 | import { AuthContext } from '../context/auth-context'; 3 | import { Dropdown, Navbar, Nav, Button } from 'react-bootstrap'; 4 | 5 | function Header() { 6 | const auth = useContext(AuthContext); 7 | return ( 8 | 9 | 10 | We Don't Waste Food 11 | 12 | 13 | 20 | 37 | 38 | 39 | ) 40 | } 41 | 42 | export default Header; -------------------------------------------------------------------------------- /frontend/src/components/Food.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Button, Card } from 'react-bootstrap'; 3 | import Timer from '../screens/Timer'; 4 | require('dotenv').config(); 5 | 6 | const Food = props => { 7 | if (props.items.length === 0) { 8 | return ( 9 |
10 |
11 | 12 | 13 | 14 | Want to Donate Food? 15 | 16 | YOUR SUPPORT MATTERS CONTRIBUTE TO HELP US PROVIDE ESSENTIAL FOOD SUPPORT TO THOSE IN NEED 17 | 18 |
19 | 20 |
21 |
22 |
23 |
24 |
25 | ); 26 | } 27 | return ( 28 |
29 |
30 | {props.items.map(food => ( 31 |
32 | 33 |
34 | Sample 35 |
36 |
37 |
38 |
39 |
{food.name}
40 |

{food.address}

41 |
42 | 43 |
44 |
45 |
46 | ) 47 | )} 48 |
49 |
50 |
51 | ); 52 | }; 53 | 54 | export default Food; 55 | -------------------------------------------------------------------------------- /frontend/src/screens/Timer.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable react-hooks/exhaustive-deps */ 2 | import React, { useRef, useState, useEffect } from 'react'; 3 | import { useHistory } from "react-router-dom"; 4 | import moment from 'moment'; 5 | 6 | const Timer = props => { 7 | 8 | const history = useHistory(); 9 | 10 | var today = moment(props.items).format('MMMM DD, YYYY hh:mm:ss'); 11 | 12 | const [timerDays, setTimerDays] = useState('00'); 13 | const [timerHours, setTimerHours] = useState('00'); 14 | const [timerMinutes, setTimerMinutes] = useState('00'); 15 | const [timerSeconds, setTimerSeconds] = useState('00'); 16 | 17 | let interval = useRef(); 18 | const startTimer = () => { 19 | const countdowndate = new Date(today).getTime(); 20 | 21 | interval = setInterval(() => { 22 | var current = moment().format('MMMM DD, YYYY hh:mm:ss'); 23 | const now = new Date(current).getTime(); 24 | const distance = countdowndate - now; 25 | 26 | var days = Math.floor(distance / (1000 * 60 * 60 * 24)); 27 | var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); 28 | var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)); 29 | var seconds = Math.floor((distance % (1000 * 60)) / 1000); 30 | 31 | days = (days).toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false}); 32 | hours = (hours).toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false}); 33 | minutes = (minutes).toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false}); 34 | seconds = (seconds).toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false}); 35 | 36 | if (distance < 0) { 37 | history.push('/reqforfood'); 38 | clearInterval(interval.current); 39 | } 40 | else { 41 | setTimerDays(days); 42 | setTimerHours(hours); 43 | setTimerMinutes(minutes); 44 | setTimerSeconds(seconds); 45 | } 46 | }, 1000); 47 | }; 48 | 49 | useEffect(() => { 50 | startTimer(); 51 | return () => { 52 | clearInterval(interval.current); 53 | } 54 | }, []); 55 | 56 | return ( 57 |
58 |

Expires in : {timerDays}:{timerHours}:{timerMinutes}:{timerSeconds}

59 |
60 | ); 61 | }; 62 | export default Timer; -------------------------------------------------------------------------------- /frontend/src/components/ViewUser.js: -------------------------------------------------------------------------------- 1 | const ViewUser = props => { 2 | return ( 3 |
4 |
5 |
6 |
7 |
8 | avatar 9 |
10 |

{props.items.name}

11 | 12 | 13 | 14 |
15 |
16 |
17 |
18 |
19 |
20 |
Email
21 |

{props.items.email}

22 |
23 |
Contact Number
24 |

+91 {props.items.mobile}

25 |
26 |
Gender
27 |

{props.items.gender}

28 |
29 |
Type
30 |

{props.items.type}

31 |
32 |
Address
33 |

{props.items.address}

34 |
35 |
City, State
36 |

{props.items.city}, {props.items.state}

37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | ) 48 | } 49 | 50 | export default ViewUser; -------------------------------------------------------------------------------- /frontend/src/screens/ResetPassword.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import { useHistory } from "react-router-dom"; 3 | import { useHttpClient } from '../hooks/http-hook'; 4 | import {BASE_API_URL} from '../api/api'; 5 | 6 | function ResetPassword() { 7 | const { sendRequest } = useHttpClient(); 8 | 9 | const history = useHistory(); 10 | const [email, setemail] = useState(""); 11 | 12 | const postdata = async (e) => { 13 | e.preventDefault(); 14 | try { 15 | const responseData = await sendRequest( 16 | BASE_API_URL+'/reset-password', 17 | 'POST', 18 | JSON.stringify({ 19 | email, 20 | }), 21 | { 22 | 'Content-Type': 'application/json', 23 | } 24 | ); 25 | if (responseData.message === "check your email") { 26 | alert("Check your mail id to reset password"); 27 | history.push('/'); 28 | } 29 | else{ 30 | document.getElementById("msg").innerHTML = "
No User found
"; 31 | return; 32 | } 33 | } 34 | catch (err) { 35 | } 36 | }; 37 | 38 | return ( 39 |
40 | {/* Required meta tags */} 41 | 42 | 43 | {/* Bootstrap CSS */} 44 | 45 | We Don't Waste Food 46 |
47 |
48 |
49 |
50 |
51 |

Reset Password

52 |
53 | 54 | setemail(e.target.value)} /> 56 |
57 |
58 |
59 | 60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | ) 71 | } 72 | 73 | export default ResetPassword; 74 | 75 | -------------------------------------------------------------------------------- /frontend/src/components/DisplayUserRecFood.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Spinner, Button, Card } from 'react-bootstrap'; 3 | require('dotenv').config(); 4 | 5 | const DisplayUserRecFood = props => { 6 | 7 | if (props.items.foods.length === 0) { 8 | return ( 9 |
10 |
11 | 12 | 13 | 14 | Want to Receive Food? 15 | 16 | YOUR SUPPORT MATTERS CONTRIBUTE TO HELP US PROVIDE ESSENTIAL FOOD SUPPORT TO THOSE IN NEED 17 | 18 |
19 | 20 |
21 |
22 |
23 |
24 | 25 |
26 | ); 27 | } 28 | 29 | return ( 30 |
31 |
32 | {props.items.foods.map(food => ( 33 |
34 | 35 |
36 | Sample 37 |
38 |
39 |
40 |
41 |
{food.name}
42 | {!food.received && } 52 | {food.received && } 62 |
63 |
64 | ) 65 | )} 66 |
67 |
68 |
69 |
70 | ); 71 | }; 72 | 73 | export default DisplayUserRecFood; -------------------------------------------------------------------------------- /frontend/README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Create React App 2 | 3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 4 | 5 | ## Available Scripts 6 | 7 | In the project directory, you can run: 8 | 9 | ### `npm start` 10 | 11 | Runs the app in the development mode.\ 12 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 13 | 14 | The page will reload if you make edits.\ 15 | You will also see any lint errors in the console. 16 | 17 | ### `npm test` 18 | 19 | Launches the test runner in the interactive watch mode.\ 20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 21 | 22 | ### `npm run build` 23 | 24 | Builds the app for production to the `build` folder.\ 25 | It correctly bundles React in production mode and optimizes the build for the best performance. 26 | 27 | The build is minified and the filenames include the hashes.\ 28 | Your app is ready to be deployed! 29 | 30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 31 | 32 | ### `npm run eject` 33 | 34 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 35 | 36 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 37 | 38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 39 | 40 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 41 | 42 | ## Learn More 43 | 44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 45 | 46 | To learn React, check out the [React documentation](https://reactjs.org/). 47 | 48 | ### Code Splitting 49 | 50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting) 51 | 52 | ### Analyzing the Bundle Size 53 | 54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size) 55 | 56 | ### Making a Progressive Web App 57 | 58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app) 59 | 60 | ### Advanced Configuration 61 | 62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration) 63 | 64 | ### Deployment 65 | 66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment) 67 | 68 | ### `npm run build` fails to minify 69 | 70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) 71 | -------------------------------------------------------------------------------- /frontend/src/components/DisplayUserDonFood.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Spinner, Button, Card } from 'react-bootstrap'; 3 | require('dotenv').config(); 4 | 5 | const DisplayUserDonFood = props => { 6 | 7 | if (props.items.foods.length === 0) { 8 | return ( 9 |
10 |
11 | 12 | 13 | 14 | Want to Donate Food? 15 | 16 | YOUR SUPPORT MATTERS CONTRIBUTE TO HELP US PROVIDE ESSENTIAL FOOD SUPPORT TO THOSE IN NEED 17 | 18 |
19 | 20 |
21 |
22 |
23 |
24 |
25 |
26 | ); 27 | } 28 | 29 | return ( 30 |
31 |
32 | {props.items.foods.map(food => ( 33 |
34 | 35 |
36 | Sample 37 |
38 |
39 |
40 |
41 |
{food.name}
42 | {food.status && } 52 | {!food.status && food.received && } 55 | {!food.status && !food.received && } 65 |
66 |
67 | ) 68 | )} 69 |
70 |
71 |
72 | ); 73 | }; 74 | 75 | export default DisplayUserDonFood; 76 | -------------------------------------------------------------------------------- /frontend/src/screens/NewPassword.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useContext } from "react"; 2 | import { AuthContext } from '../context/auth-context'; 3 | import {BASE_API_URL} from '../api/api'; 4 | import { useHistory, useParams } from "react-router-dom"; 5 | import { useHttpClient } from '../hooks/http-hook'; 6 | 7 | function NewPassword() { 8 | 9 | const auth = useContext(AuthContext); 10 | const { sendRequest } = useHttpClient(); 11 | const { token } = useParams(); 12 | 13 | const history = useHistory(); 14 | const [password, setpassword] = useState(""); 15 | const [confpassword, setconfpassword] = useState(""); 16 | 17 | const postdata = async (e) => { 18 | e.preventDefault(); 19 | if (password !== confpassword) { 20 | document.getElementById("msg").innerHTML = "
Password hasn't matched
"; 21 | return; 22 | } 23 | try { 24 | const responseData = await sendRequest( 25 | BASE_API_URL+'/new-password', 26 | 'POST', 27 | JSON.stringify({ 28 | password, 29 | token 30 | }), 31 | { 32 | 'Content-Type': 'application/json', 33 | } 34 | ); 35 | if (responseData) { 36 | auth.login( 37 | responseData.userId, 38 | responseData.token 39 | ); 40 | history.push('/login'); 41 | } 42 | } 43 | catch (err) { 44 | } 45 | }; 46 | 47 | return ( 48 |
49 | {/* Required meta tags */} 50 | 51 | 52 | {/* Bootstrap CSS */} 53 | 54 | We Don't Waste Food 55 |
56 |
57 |
58 |
59 |
60 |

Enter New Password

61 |
62 | 63 | setpassword(e.target.value)} /> 65 |
66 |
67 | 68 | setconfpassword(e.target.value)} /> 70 |
71 |
72 |
73 | 74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 | ) 84 | } 85 | 86 | export default NewPassword; 87 | 88 | -------------------------------------------------------------------------------- /frontend/src/components/DisplayContributors.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable jsx-a11y/img-redundant-alt */ 2 | import React from 'react'; 3 | import rank1 from '../images/1.jpg' 4 | import rank2 from '../images/2.jpg' 5 | import rank3 from '../images/3.jpg' 6 | import donation from '../images/donation.png' 7 | import food from '../images/food.png' 8 | 9 | const DisplayContributors = props => { 10 | 11 | return ( 12 |
13 |
14 |

imageTop Donors Contributorsimage

15 |
16 |
17 |
18 |
19 |
20 | image 21 |
{props.items.Don[1].don.fullname}
22 |

image

23 |
24 |
25 |
26 | image 27 |
{props.items.Don[0].don.fullname}
28 |

image

29 |
30 |
31 |
32 | image 33 |
{props.items.Don[2].don.fullname}
34 |

image

35 |
36 |
37 |
38 | 39 |

40 |
41 |

imageTop Recipient Contributorsimage

42 |
43 |
44 |
45 |
46 |
47 | image 48 |
{props.items.Rec[1].rec.fullname}
49 |

image

50 |
51 |
52 |
53 | image 54 |
{props.items.Rec[0].rec.fullname}
55 |

image

56 |
57 |
58 |
59 | image 60 |
{props.items.Rec[2].rec.fullname}
61 |

image

62 |
63 |
64 |
65 |
66 | ); 67 | }; 68 | 69 | export default DisplayContributors; 70 | -------------------------------------------------------------------------------- /frontend/src/components/ViewFood.js: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | import { useParams } from 'react-router-dom'; 3 | import { useHistory } from "react-router-dom"; 4 | import { useHttpClient } from '../hooks/http-hook'; 5 | import { AuthContext } from '../context/auth-context'; 6 | import Moment from 'react-moment'; 7 | import {BASE_API_URL} from '../api/api'; 8 | 9 | const ViewFood = props => { 10 | 11 | const auth = useContext(AuthContext); 12 | const { sendRequest } = useHttpClient(); 13 | const recId = useParams().userId; 14 | const foodId = useParams().foodId; 15 | const history = useHistory(); 16 | 17 | function checkId() { 18 | if (auth.userId !== recId) return false; 19 | return true; 20 | } 21 | 22 | const deletefood = async (e) => { 23 | e.preventDefault(); 24 | try { 25 | const responseData = await sendRequest( 26 | BASE_API_URL+'/deletefood', 27 | 'DELETE', 28 | JSON.stringify({ 29 | foodId 30 | }), 31 | { 32 | 'Content-Type': 'application/json', 33 | Authorization: 'Bearer ' + auth.token 34 | } 35 | ); 36 | if(responseData){ 37 | history.push('/reqforfood'); 38 | } 39 | } 40 | catch (err) { 41 | } 42 | }; 43 | 44 | return ( 45 |
46 |
47 |
48 |
49 |
50 | avatar 51 |
52 |

{props.items.name}

53 | 54 |
55 |
56 |
57 |
58 |
59 |
60 |

Food Name : {props.items.name}

61 |

Function Name : {props.items.funcname}

62 |

Food Type : {props.items.foodtype}

63 |

Food Description : {props.items.description}

64 |

Donator Contact No : {props.items.mobile}

65 |

Food Quality : {props.items.quality}, Food Quantity : {props.items.quantity}

66 |

Food Cooked Time : 67 | 68 | {props.items.cookedtime} 69 | , Food Expiry Time : 70 | 71 | {props.items.expirytime} 72 |

73 |

Food Address : {props.items.address}, {props.items.city}, {props.items.state}

74 | {checkId() && } 75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 | ) 87 | } 88 | 89 | export default ViewFood; -------------------------------------------------------------------------------- /frontend/src/screens/Home.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { Carousel } from 'react-bootstrap'; 4 | import image1 from '../images/image1.png'; 5 | import image4 from '../images/image4.png'; 6 | import image33 from '../images/image33.jpg'; 7 | import image3 from '../images/image3.png'; 8 | 9 | function Home() { 10 | return ( 11 |
12 | 13 | 14 | Second slide 19 | 20 |

BECOME A HUNGER HERO

21 |

22 | We are serving cooked meals to people in need daily through our NGO partners across India 23 |

24 |
25 |
26 | 27 | First slide 32 | 33 |

FEED EVERY CHILD

34 |

35 | Reliable food and nutrition for underserved 36 | children across India. 37 |

38 |
39 |
40 |
41 | 42 |
43 |
44 |
45 |

46 | 47 | Lead a movement towards{' '} 48 | 49 | zero hunger 50 |

51 |

52 | We design interventions to ensure reliable meals for 53 | children in underserved communities where food can 54 | act as an incentive to education and skill 55 | development. We support Slum Schools, Skill 56 | Development centres, Creches, Community Development 57 | Centres and Child Shelter Homes. 58 |

59 |
60 |
61 | 66 |
67 |
68 |
69 |
70 |
71 |

72 | Become an 73 | agent of change 74 |

75 |

76 | A network of highly passionate citizens who care 77 | deeply about the potential the future generation 78 | holds. We help mobilize food from various sources to 79 | those in need through solutions that can ensure the 80 | lack of reliable meals is never an obstacle for a 81 | future with more education, better health and better 82 | economic status. 83 |

84 |
85 |
86 | 87 |
88 |
89 |
90 |
91 | ) 92 | } 93 | export default Home; 94 | -------------------------------------------------------------------------------- /frontend/src/screens/Login.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useContext } from "react"; 2 | import { AuthContext } from '../context/auth-context'; 3 | import { useHistory } from "react-router-dom"; 4 | import { useHttpClient } from '../hooks/http-hook'; 5 | import {BASE_API_URL} from '../api/api'; 6 | 7 | function Login() { 8 | 9 | const auth = useContext(AuthContext); 10 | const { sendRequest } = useHttpClient(); 11 | 12 | const history = useHistory(); 13 | const [email, setemail] = useState(""); 14 | const [password, setpassword] = useState(""); 15 | 16 | const postdata = async (e) => { 17 | e.preventDefault(); 18 | try { 19 | const responseData = await sendRequest( 20 | BASE_API_URL+'/login', 21 | 'POST', 22 | JSON.stringify({ 23 | email, 24 | password 25 | }), 26 | { 27 | 'Content-Type': 'application/json', 28 | } 29 | ); 30 | if (responseData.userId) { 31 | auth.login( 32 | responseData.userId, 33 | responseData.token 34 | ); 35 | history.push('/'); 36 | } 37 | else{ 38 | document.getElementById("msg").innerHTML = "
Invalid Email or Password
"; 39 | return; 40 | } 41 | } 42 | catch (err) { 43 | } 44 | }; 45 | 46 | return ( 47 |
48 | {/* Required meta tags */} 49 | 50 | 51 | {/* Bootstrap CSS */} 52 | 53 | We Don't Waste Food 54 |
55 |
56 |
57 |
58 |
59 |

Login

60 |
61 | 62 | setemail(e.target.value)} required/> 64 |
65 |
66 | 67 | setpassword(e.target.value)} required/> 69 |
70 |
71 |
72 | 73 |
74 |
75 |
76 | Forgot Password? 77 |
78 |
79 |
80 | 83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 | ) 92 | } 93 | 94 | export default Login; -------------------------------------------------------------------------------- /frontend/src/components/MapFoodComp.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { withGoogleMap, GoogleMap, withScriptjs, InfoWindow, Marker } from "react-google-maps"; 3 | import Geocode from "react-geocode"; 4 | 5 | require('dotenv').config(); 6 | Geocode.setApiKey(process.env.REACT_APP_MAP_API); 7 | Geocode.enableDebug(); 8 | 9 | class MapFoodComp extends Component{ 10 | 11 | constructor( props ){ 12 | super( props ); 13 | this.state = { 14 | address: '', 15 | city: '', 16 | area: '', 17 | state: '', 18 | mapPosition: { 19 | lat: this.props.center.lat, 20 | lng: this.props.center.lng 21 | }, 22 | markerPosition: { 23 | lat: this.props.center.lat, 24 | lng: this.props.center.lng 25 | } 26 | } 27 | } 28 | 29 | componentDidMount() { 30 | Geocode.fromLatLng( this.state.mapPosition.lat , this.state.mapPosition.lng ).then( 31 | response => { 32 | const address = response.results[0].formatted_address, 33 | addressArray = response.results[0].address_components, 34 | city = this.getCity( addressArray ), 35 | area = this.getArea( addressArray ), 36 | state = this.getState( addressArray ); 37 | 38 | this.setState( { 39 | address: ( address ) ? address : '', 40 | area: ( area ) ? area : '', 41 | city: ( city ) ? city : '', 42 | state: ( state ) ? state : '', 43 | } ) 44 | }, 45 | error => { 46 | } 47 | ); 48 | } 49 | 50 | shouldComponentUpdate( nextProps, nextState ){ 51 | if ( 52 | this.state.markerPosition.lat !== this.props.center.lat || 53 | this.state.address !== nextState.address || 54 | this.state.city !== nextState.city || 55 | this.state.area !== nextState.area || 56 | this.state.state !== nextState.state 57 | ) { 58 | return true 59 | } else if ( this.props.center.lat === nextProps.center.lat ){ 60 | return false 61 | } 62 | } 63 | 64 | getCity = ( addressArray ) => { 65 | let city = ''; 66 | for( let i = 0; i < addressArray.length; i++ ) { 67 | if ( addressArray[ i ].types[0] && 'administrative_area_level_2' === addressArray[ i ].types[0] ) { 68 | city = addressArray[ i ].long_name; 69 | return city; 70 | } 71 | } 72 | }; 73 | 74 | getArea = ( addressArray ) => { 75 | let area = ''; 76 | for( let i = 0; i < addressArray.length; i++ ) { 77 | if ( addressArray[ i ].types[0] ) { 78 | for ( let j = 0; j < addressArray[ i ].types.length; j++ ) { 79 | if ( 'sublocality_level_1' === addressArray[ i ].types[j] || 'locality' === addressArray[ i ].types[j] ) { 80 | area = addressArray[ i ].long_name; 81 | return area; 82 | } 83 | } 84 | } 85 | } 86 | }; 87 | 88 | getState = ( addressArray ) => { 89 | let state = ''; 90 | for( let i = 0; i < addressArray.length; i++ ) { 91 | for( let i = 0; i < addressArray.length; i++ ) { 92 | if ( addressArray[ i ].types[0] && 'administrative_area_level_1' === addressArray[ i ].types[0] ) { 93 | state = addressArray[ i ].long_name; 94 | return state; 95 | } 96 | } 97 | } 98 | }; 99 | 100 | onInfoWindowClose = ( event ) => { 101 | 102 | }; 103 | 104 | render(){ 105 | const AsyncMap = withScriptjs( 106 | withGoogleMap( 107 | props => ( 108 | 112 | {/* InfoWindow on top of marker */} 113 | 117 |
118 | { this.state.address } 119 |
120 |
121 | {/*Marker*/} 122 | 127 | 128 | {/* For Auto complete Search Box */} 129 |
130 | ) 131 | ) 132 | ); 133 | let map; 134 | if( this.props.center.lat !== undefined ) { 135 | map =
136 |
137 |
138 | 142 | } 143 | containerElement={ 144 |
145 | } 146 | mapElement={ 147 |
148 | } 149 | /> 150 |
151 | } else { 152 | map =
153 | } 154 | return( map ) 155 | } 156 | } 157 | export default MapFoodComp; 158 | -------------------------------------------------------------------------------- /frontend/src/App.js: -------------------------------------------------------------------------------- 1 | import './App.css' 2 | import '@fortawesome/fontawesome-free/css/all.min.css'; 3 | import 'bootstrap-css-only/css/bootstrap.min.css'; 4 | import 'mdbreact/dist/css/mdb.css'; 5 | import 'bootstrap/dist/css/bootstrap.min.css'; 6 | 7 | import { useAuth } from './hooks/auth-hook'; 8 | import { AuthContext } from './context/auth-context'; 9 | import { BrowserRouter as Router, Switch, Route} from 'react-router-dom'; 10 | 11 | import Header from './components/Header'; 12 | import Footer from './components/Footer'; 13 | import Home from './screens/Home' 14 | import Donate from './screens/Donate' 15 | import ReqForFood from './screens/ReqForFood' 16 | import Contributors from './screens/Contributors' 17 | import Contact from './screens/Contact' 18 | import ViewProfile from './screens/ViewProfile' 19 | import Signup from './screens/Signup'; 20 | import Login from './screens/Login'; 21 | import ResetPassword from './screens/ResetPassword'; 22 | import NewPassword from './screens/NewPassword'; 23 | import EditProfile from './screens/EditProfile'; 24 | import MapNew from './components/MapNew'; 25 | import ReqViewFood from './screens/ReqViewFood'; 26 | import UserRecFood from './screens/UserRecFood'; 27 | import DetailUserRecFood from './screens/DetailUserRecFood'; 28 | import UserDonFood from './screens/UserDonFood'; 29 | import DetailUserDonFood from './screens/DetailUserDonFood'; 30 | import Timer from './screens/Timer'; 31 | 32 | function App() { 33 | const { token, login, logout, userId } = useAuth(); 34 | let routes; 35 | if (userId) { 36 | routes = ( 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | ); 85 | } 86 | else { 87 | routes = ( 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | ); 118 | } 119 | 120 | return ( 121 | <> 122 | 131 |
132 | 133 | {routes} 134 | 135 | 136 |