├── 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 | You need to enable JavaScript to run this app.
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 |
14 | Home
15 | {auth.isLoggedIn && (Donate )}
16 | {auth.isLoggedIn && (Request For Food )}
17 | Contributors
18 | Contact Us
19 |
20 |
21 | {!auth.isLoggedIn && (Login )}
22 | {!auth.isLoggedIn && (SignUp )}
23 | {auth.isLoggedIn &&
24 |
25 | Profile
26 |
27 |
28 | View Profile
29 | Donated Food
30 | Received Food
31 |
32 | }
33 | {auth.isLoggedIn && (
34 | Logout
35 | )}
36 |
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 |
21 |
22 |
23 |
24 |
25 | );
26 | }
27 | return (
28 |
29 |
30 | {props.items.map(food => (
31 |
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 |
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 |
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 |
21 |
22 |
23 |
24 |
25 |
26 | );
27 | }
28 |
29 | return (
30 |
31 |
32 | {props.items.foods.map(food => (
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
{food.name}
42 | {!food.received &&
43 | Requested{' '}
44 |
51 | }
52 | {food.received &&
53 | Collected{' '}
54 |
61 | }
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 |
21 |
22 |
23 |
24 |
25 |
26 | );
27 | }
28 |
29 | return (
30 |
31 |
32 | {props.items.foods.map(food => (
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
{food.name}
42 | {food.status &&
43 | NOT YET Requested{' '}
44 |
51 | }
52 | {!food.status && food.received &&
53 | Collected{' '}
54 | }
55 | {!food.status && !food.received &&
56 | Requested{' '}
57 |
64 | }
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 |
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 |
Top Donors Contributors
15 |
16 |
17 |
18 |
19 |
20 |
21 |
{props.items.Don[1].don.fullname}
22 |
23 |
24 |
25 |
26 |
27 |
{props.items.Don[0].don.fullname}
28 |
29 |
30 |
31 |
32 |
33 |
{props.items.Don[2].don.fullname}
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
Top Recipient Contributors
42 |
43 |
44 |
45 |
46 |
47 |
48 |
{props.items.Rec[1].rec.fullname}
49 |
50 |
51 |
52 |
53 |
54 |
{props.items.Rec[0].rec.fullname}
55 |
56 |
57 |
58 |
59 |
60 |
{props.items.Rec[2].rec.fullname}
61 |
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 |
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() && Delete Food }
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 |
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 |
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 |
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 |
137 | >
138 | );
139 | }
140 | export default App;
--------------------------------------------------------------------------------
/frontend/src/screens/Contact.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | function Contact() {
4 | return (
5 |
6 | {/* Required meta tags */}
7 |
8 |
12 | {/* Bootstrap CSS */}
13 |
19 |
We Don't Waste Food
20 | {/* navbar */}
21 |
22 |
Contact Us
23 |
109 |
110 |
111 | )
112 | }
113 |
114 | export default Contact;
--------------------------------------------------------------------------------
/frontend/src/components/DisplayDetailUserRecFood.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable jsx-a11y/img-redundant-alt */
2 | import React from 'react';
3 | import { Spinner } from 'react-bootstrap';
4 | import Moment from 'react-moment';
5 |
6 | const DisplayDetailUserRecFood = props => {
7 |
8 | return (
9 |
10 | {/* food information */}
11 |
12 |
13 |
14 |
15 |
16 |
17 |
{props.items.food.name}
18 |
19 |
20 |
21 |
22 |
23 |
24 |
Food Name : {props.items.food.name}
25 |
Function Name : {props.items.food.funcname}
26 |
Food Type : {props.items.food.foodtype}
27 |
Food Description : {props.items.food.description}
28 |
Donator Contact No : {props.items.food.mobile}
29 |
Food Quality : {props.items.food.quality}, Food Quantity : {props.items.food.quantity}
30 |
Food Cooked Time :
31 |
32 | {props.items.food.cookedtime}
33 | , Food Expiry Time :
34 |
35 | {props.items.food.expirytime}
36 |
37 |
Food Address : {props.items.food.address}, {props.items.food.city}, {props.items.food.state}
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | {props.items.food.received ?
51 |
52 | {' '}
57 | Congratulations You have performed one more good deed. Keep up the good work.
58 | {' '}
63 |
64 | :
65 |
66 |
67 |
68 | {' '}
73 | You are expected to reach there before
74 |
75 | {props.items.recdetail.exptime}
76 |
77 | {' '}to collect the food or else your Request will be Rejected{' '}
78 | {' '}
83 |
84 | }
85 |
86 |
87 |
88 | {/* Donator information */}
89 |
90 |
91 |
92 |
Donor Information
93 |
94 |
FullName : {props.items.donator.fullname}
95 |
Email : {props.items.donator.email}
96 |
Contact No : {props.items.donator.mobile}
97 |
Gender : {props.items.donator.gender}
98 |
Type : {props.items.donator.type}
99 |
Address : {props.items.donator.city}, {props.items.donator.state}
100 |
101 |
102 |
103 |
Recipient Information
104 |
105 |
FullName : {props.items.receiver.fullname}
106 |
Email : {props.items.receiver.email}
107 |
Contact No : {props.items.receiver.mobile}
108 |
Gender : {props.items.receiver.gender}
109 |
Type : {props.items.receiver.type}
110 |
Address : {props.items.receiver.city}, {props.items.receiver.state}
111 |
112 |
113 |
114 |
115 | );
116 | };
117 |
118 | export default DisplayDetailUserRecFood;
119 |
--------------------------------------------------------------------------------
/frontend/src/screens/EditProfile.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-unused-vars */
2 | import React, { useState, useContext } from "react";
3 | import { AuthContext } from "../context/auth-context";
4 | import { useHttpClient } from "../hooks/http-hook";
5 | import { useHistory } from "react-router-dom";
6 | import {BASE_API_URL} from '../api/api';
7 | require('dotenv').config();
8 |
9 | const EditProfile = () => {
10 |
11 | const auth = useContext(AuthContext);
12 | const { sendRequest } = useHttpClient();
13 |
14 | const history = useHistory();
15 | const [fullname, setfullname] = useState("");
16 | const [email, setemail] = useState("");
17 | const [mobile, setmobile] = useState("");
18 | const [type, settype] = useState("NGO");
19 | const [gender, setgender] = useState("Male");
20 | const [address, setaddress] = useState("");
21 | const [city, setcity] = useState("");
22 | const [state, setstate] = useState("");
23 | const [image, setimage] = useState("")
24 | const [Url, setUrl] = useState("")
25 |
26 | const handleChangeGender = (e) => {
27 | setgender(e.target.value);
28 | };
29 | const handleChangeType = (e) => {
30 | settype(e.target.value);
31 | };
32 |
33 | async function postDetails() {
34 | const data = new FormData()
35 | data.append("file", image)
36 | data.append("upload_preset", process.env.REACT_APP_IMG_UPLOAD)
37 | data.append("cloud_name", process.env.REACT_APP_IMG_CLOUD)
38 | const res_a = await fetch(process.env.REACT_APP_IMG_URL , {
39 | method: "post",
40 | body: data
41 | })
42 | .catch((error) => {
43 | console.log(error);
44 | });
45 | const data_a = await res_a.json();
46 | return data_a;
47 | }
48 |
49 | const postdata = async (e) => {
50 | e.preventDefault();
51 | let a = postDetails();
52 | a.then((data) => {
53 | setUrl(data.url);
54 | responseData(data.url);
55 | }
56 | )
57 | };
58 |
59 | async function responseData(Url1) {
60 | const responseNew = await sendRequest(
61 | BASE_API_URL+'/editprofile',
62 | 'POST',
63 | JSON.stringify({
64 | fullname,
65 | email,
66 | mobile,
67 | type,
68 | gender,
69 | address,
70 | city,
71 | state,
72 | Url: Url1
73 | }),
74 | {
75 | 'Content-Type': 'application/json',
76 | Authorization: 'Bearer ' + auth.token
77 | }
78 | );
79 |
80 | try {
81 | if (!responseNew) {
82 | document.getElementById("msg").innerHTML = "" + responseNew + " ";
83 | return;
84 | }
85 | if (responseNew) {
86 | history.push('/viewprofile');
87 | }
88 | }
89 | catch (err) {
90 | }
91 | }
92 |
93 | return (
94 |
172 | )
173 | }
174 |
175 | export default EditProfile;
--------------------------------------------------------------------------------
/frontend/src/components/Map.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 | import Autocomplete from 'react-google-autocomplete';
5 | require('dotenv').config();
6 |
7 | Geocode.setApiKey(process.env.MAP_API);
8 | Geocode.enableDebug();
9 |
10 | class Map extends Component {
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 | this.setState({
38 | address: (address) ? address : '',
39 | area: (area) ? area : '',
40 | city: (city) ? city : '',
41 | state: (state) ? state : '',
42 | })
43 | },
44 | error => {
45 | }
46 | );
47 | };
48 |
49 | shouldComponentUpdate(nextProps, nextState) {
50 | if (
51 | this.state.markerPosition.lat !== this.props.center.lat ||
52 | this.state.address !== nextState.address ||
53 | this.state.city !== nextState.city ||
54 | this.state.area !== nextState.area ||
55 | this.state.state !== nextState.state
56 | ) {
57 | return true
58 | } else if (this.props.center.lat === nextProps.center.lat) {
59 | return false
60 | }
61 | }
62 |
63 | getCity = (addressArray) => {
64 | let city = '';
65 | for (let i = 0; i < addressArray.length; i++) {
66 | if (addressArray[i].types[0] && 'administrative_area_level_2' === addressArray[i].types[0]) {
67 | city = addressArray[i].long_name;
68 | return city;
69 | }
70 | }
71 | };
72 |
73 | getArea = (addressArray) => {
74 | let area = '';
75 | for (let i = 0; i < addressArray.length; i++) {
76 | if (addressArray[i].types[0]) {
77 | for (let j = 0; j < addressArray[i].types.length; j++) {
78 | if ('sublocality_level_1' === addressArray[i].types[j] || 'locality' === addressArray[i].types[j]) {
79 | area = addressArray[i].long_name;
80 | return area;
81 | }
82 | }
83 | }
84 | }
85 | };
86 |
87 | getState = (addressArray) => {
88 | let state = '';
89 | for (let i = 0; i < addressArray.length; i++) {
90 | for (let i = 0; i < addressArray.length; i++) {
91 | if (addressArray[i].types[0] && 'administrative_area_level_1' === addressArray[i].types[0]) {
92 | state = addressArray[i].long_name;
93 | return state;
94 | }
95 | }
96 | }
97 | };
98 |
99 | onChange = (event) => {
100 | this.setState({ [event.target.name]: event.target.value });
101 | };
102 |
103 | onInfoWindowClose = (event) => {
104 |
105 | };
106 |
107 | onMarkerDragEnd = (event) => {
108 | let newLat = event.latLng.lat(),
109 | newLng = event.latLng.lng();
110 |
111 | Geocode.fromLatLng(newLat, newLng).then(
112 | response => {
113 | const address = response.results[0].formatted_address,
114 | addressArray = response.results[0].address_components,
115 | city = this.getCity(addressArray),
116 | area = this.getArea(addressArray),
117 | state = this.getState(addressArray);
118 | this.setState({
119 | address: (address) ? address : '',
120 | area: (area) ? area : '',
121 | city: (city) ? city : '',
122 | state: (state) ? state : '',
123 | markerPosition: {
124 | lat: newLat,
125 | lng: newLng
126 | },
127 | mapPosition: {
128 | lat: newLat,
129 | lng: newLng
130 | },
131 | })
132 | },
133 | error => {
134 | }
135 | );
136 | this.props.mapValueFunc(this.address);
137 | };
138 |
139 | onPlaceSelected = (place) => {
140 | const address = place.formatted_address,
141 | addressArray = place.address_components,
142 | city = this.getCity(addressArray),
143 | area = this.getArea(addressArray),
144 | state = this.getState(addressArray),
145 | latValue = place.geometry.location.lat(),
146 | lngValue = place.geometry.location.lng();
147 | this.setState({
148 | address: (address) ? address : '',
149 | area: (area) ? area : '',
150 | city: (city) ? city : '',
151 | state: (state) ? state : '',
152 | markerPosition: {
153 | lat: latValue,
154 | lng: lngValue
155 | },
156 | mapPosition: {
157 | lat: latValue,
158 | lng: lngValue
159 | },
160 | })
161 | };
162 |
163 | render() {
164 | const AsyncMap = withScriptjs(
165 | withGoogleMap(
166 | props => (
167 |
171 | {/* InfoWindow on top of marker */}
172 |
176 |
177 | {this.state.address}
178 |
179 |
180 | {/*Marker*/}
181 |
187 |
188 | {/* For Auto complete Search Box */}
189 |
200 |
201 | )
202 | )
203 | );
204 | let map;
205 | if (this.props.center.lat !== undefined) {
206 | map =
207 |
226 |
227 |
231 | }
232 | containerElement={
233 |
234 | }
235 | mapElement={
236 |
237 | }
238 | />
239 |
240 | } else {
241 | map =
242 | }
243 | return (map)
244 | }
245 | }
246 | export default Map;
--------------------------------------------------------------------------------
/frontend/src/components/RecViewFood.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-unused-vars */
2 | import React, { useState, useContext } from "react";
3 | import { AuthContext } from '../context/auth-context';
4 | import { useHistory } from "react-router-dom";
5 | import { useHttpClient } from '../hooks/http-hook';
6 | import { Button, Modal } from 'react-bootstrap';
7 | import moment from 'moment';
8 | import MapFood from './MapFood';
9 | import {BASE_API_URL} from '../api/api';
10 |
11 | const RecViewFood = props => {
12 |
13 | const auth = useContext(AuthContext);
14 | const { sendRequest } = useHttpClient();
15 |
16 | let message = "";
17 | const [showmessage, setshowmessage] = useState("");
18 | const [show, setShow] = useState(false);
19 | const handleClose = () => setShow(false);
20 |
21 | const history = useHistory();
22 | const [name, setname] = useState("");
23 | const [email, setemail] = useState("");
24 | const [mobile, setmobile] = useState("");
25 | const [address, setaddress] = useState("");
26 | const [city, setcity] = useState("");
27 | const [state, setstate] = useState("");
28 | const [exptime, setexptime] = useState("");
29 |
30 | let donId;
31 | function checkId() {
32 | donId = props.items.userId;
33 | if (donId !== auth.userId) return true;
34 | return false;
35 | }
36 |
37 |
38 | const postdata = async (e) => {
39 | e.preventDefault();
40 | message = "";
41 |
42 | var currentdate = new Date();
43 | var datetime = currentdate.getFullYear() + "-"
44 | + (currentdate.getMonth() < 10 ? "0" : "") + (currentdate.getMonth() + 1) + "-"
45 | + (currentdate.getDate() < 10 ? "0" : "") + currentdate.getDate() + "T"
46 | + (currentdate.getHours() < 10 ? "0" : "") + currentdate.getHours() + ":"
47 | + (currentdate.getMinutes() < 10 ? "0" : "") + currentdate.getMinutes();
48 | const dateIsSame = moment(datetime).isAfter(moment(exptime));
49 | const dateIsBefore = moment(props.items.cookedtime).isBefore(moment(exptime));
50 | const dateIsAfter = moment(props.items.expirytime).isAfter(moment(exptime));
51 | if (!dateIsBefore) message = message + "Your Expected Time to reach is earlier than Cooked time";
52 | if (!dateIsAfter) message = message + "Your Expected Time to reach exceeds Expiry time";
53 | if (dateIsSame && dateIsBefore) message = message + "Your Expected Time to reach is earlier than Current time";
54 | setshowmessage(message);
55 | if (message.length !== 0) {
56 | setShow(true);
57 | }
58 | else{
59 | try {
60 | const responseData = await sendRequest(
61 | BASE_API_URL+'/acceptfood',
62 | 'POST',
63 | JSON.stringify({
64 | donId,
65 | foodId: props.items.foodId,
66 | name,
67 | email,
68 | mobile,
69 | address,
70 | exptime
71 | }),
72 | {
73 | 'Content-Type': 'application/json',
74 | Authorization: 'Bearer ' + auth.token
75 | }
76 | );
77 | history.push('/reqforfood');
78 | }
79 | catch (err) {
80 | }
81 | }
82 | };
83 |
84 | return (
85 |
86 | {checkId() &&
87 |
88 |
89 |
90 |
91 |
92 |
152 |
153 |
}
154 |
155 | )
156 | }
157 |
158 | export default RecViewFood;
--------------------------------------------------------------------------------
/frontend/src/components/MapComp.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 | import Autocomplete from 'react-google-autocomplete';
5 | require('dotenv').config();
6 |
7 | Geocode.setApiKey(process.env.REACT_APP_MAP_API);
8 | Geocode.enableDebug();
9 |
10 | class MapComp extends Component {
11 |
12 | constructor(props) {
13 | super(props);
14 | this.state = {
15 | address: 'Green Block, Navratna Apt, CTM Cross Rd, Hatkeshwar',
16 | city: 'Ahmedabad',
17 | area: 'Hatkeshwar',
18 | state: 'Gujarat',
19 | mapPosition: {
20 | lat: this.props.center.lat,
21 | lng: this.props.center.lng
22 | },
23 | markerPosition: {
24 | lat: this.props.center.lat,
25 | lng: this.props.center.lng
26 | },
27 | mapValueFunc: this.props.mapValueFunc
28 | }
29 | }
30 |
31 | componentDidMount() {
32 | Geocode.fromLatLng(this.state.mapPosition.lat, this.state.mapPosition.lng).then(
33 | response => {
34 | const address = response.results[0].formatted_address,
35 | addressArray = response.results[0].address_components,
36 | city = this.getCity(addressArray),
37 | area = this.getArea(addressArray),
38 | state = this.getState(addressArray);
39 | this.state.mapValueFunc(this.state);
40 |
41 | this.setState({
42 | address: (address) ? address : '',
43 | area: (area) ? area : '',
44 | city: (city) ? city : '',
45 | state: (state) ? state : '',
46 | })
47 | this.state.mapValueFunc(this.state);
48 | },
49 | error => {
50 | }
51 | );
52 | this.state.mapValueFunc(this.state);
53 | }
54 |
55 | shouldComponentUpdate(nextProps, nextState) {
56 | if (
57 | this.state.markerPosition.lat !== this.props.center.lat ||
58 | this.state.address !== nextState.address ||
59 | this.state.city !== nextState.city ||
60 | this.state.area !== nextState.area ||
61 | this.state.state !== nextState.state
62 | ) {
63 | return true
64 | } else if (this.props.center.lat === nextProps.center.lat) {
65 | return false
66 | }
67 | }
68 |
69 | getCity = (addressArray) => {
70 | let city = '';
71 | for (let i = 0; i < addressArray.length; i++) {
72 | if (addressArray[i].types[0] && 'administrative_area_level_2' === addressArray[i].types[0]) {
73 | city = addressArray[i].long_name;
74 | return city;
75 | }
76 | }
77 | };
78 |
79 | getArea = (addressArray) => {
80 | let area = '';
81 | for (let i = 0; i < addressArray.length; i++) {
82 | if (addressArray[i].types[0]) {
83 | for (let j = 0; j < addressArray[i].types.length; j++) {
84 | if ('sublocality_level_1' === addressArray[i].types[j] || 'locality' === addressArray[i].types[j]) {
85 | area = addressArray[i].long_name;
86 | return area;
87 | }
88 | }
89 | }
90 | }
91 | };
92 |
93 | getState = (addressArray) => {
94 | let state = '';
95 | for (let i = 0; i < addressArray.length; i++) {
96 | for (let i = 0; i < addressArray.length; i++) {
97 | if (addressArray[i].types[0] && 'administrative_area_level_1' === addressArray[i].types[0]) {
98 | state = addressArray[i].long_name;
99 | return state;
100 | }
101 | }
102 | }
103 | };
104 |
105 | onChange = (event) => {
106 | this.setState({ [event.target.name]: event.target.value });
107 | };
108 |
109 | onInfoWindowClose = (event) => {
110 |
111 | };
112 |
113 | onMarkerDragEnd = (event) => {
114 | let newLat = event.latLng.lat(),
115 | newLng = event.latLng.lng();
116 |
117 | Geocode.fromLatLng(newLat, newLng).then(
118 | response => {
119 | const address = response.results[0].formatted_address,
120 | addressArray = response.results[0].address_components,
121 | city = this.getCity(addressArray),
122 | area = this.getArea(addressArray),
123 | state = this.getState(addressArray);
124 | this.setState({
125 | address: (address) ? address : '',
126 | area: (area) ? area : '',
127 | city: (city) ? city : '',
128 | state: (state) ? state : '',
129 | markerPosition: {
130 | lat: newLat,
131 | lng: newLng
132 | },
133 | mapPosition: {
134 | lat: newLat,
135 | lng: newLng
136 | },
137 | })
138 | this.state.mapValueFunc(this.state);
139 | },
140 | error => {
141 | }
142 | );
143 | };
144 |
145 | onPlaceSelected = (place) => {
146 | const address = place.formatted_address,
147 | addressArray = place.address_components,
148 | city = this.getCity(addressArray),
149 | area = this.getArea(addressArray),
150 | state = this.getState(addressArray),
151 | latValue = place.geometry.location.lat(),
152 | lngValue = place.geometry.location.lng();
153 | this.setState({
154 | address: (address) ? address : '',
155 | area: (area) ? area : '',
156 | city: (city) ? city : '',
157 | state: (state) ? state : '',
158 | markerPosition: {
159 | lat: latValue,
160 | lng: lngValue
161 | },
162 | mapPosition: {
163 | lat: latValue,
164 | lng: lngValue
165 | },
166 | })
167 | this.state.mapValueFunc(this.state);
168 | };
169 |
170 |
171 | render() {
172 | const AsyncMap = withScriptjs(
173 | withGoogleMap(
174 | props => (
175 |
179 | {/* InfoWindow on top of marker */}
180 |
184 |
185 | {this.state.address}
186 |
187 |
188 | {/*Marker*/}
189 |
195 |
196 | {/* For Auto complete Search Box */}
197 |
208 |
209 | )
210 | )
211 | );
212 | let map;
213 | if (this.props.center.lat !== undefined) {
214 | map =
215 |
238 |
239 |
243 | }
244 | containerElement={
245 |
246 | }
247 | mapElement={
248 |
249 | }
250 | />
251 |
252 | } else {
253 | map =
254 | }
255 | return (map)
256 | }
257 | }
258 |
259 | export default MapComp;
260 |
--------------------------------------------------------------------------------
/frontend/src/screens/Signup.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-unused-vars */
2 | import React, { useState, useContext } from "react";
3 | import { AuthContext } from "../context/auth-context";
4 | import { useHistory } from "react-router-dom";
5 | import { useHttpClient } from "../hooks/http-hook";
6 | import {BASE_API_URL} from '../api/api';
7 | require('dotenv').config();
8 |
9 | function Signup() {
10 | const auth = useContext(AuthContext);
11 | const { sendRequest } = useHttpClient();
12 |
13 | const history = useHistory();
14 | const [fullname, setfullname] = useState("");
15 | const [email, setemail] = useState("");
16 | const [password, setpassword] = useState("");
17 | const [confpassword, setconfpassword] = useState("");
18 | const [mobile, setmobile] = useState("");
19 | const [type, settype] = useState("NGO");
20 | const [gender, setgender] = useState("Male");
21 | const [address, setaddress] = useState("");
22 | const [city, setcity] = useState("");
23 | const [state, setstate] = useState("");
24 | const [image, setimage] = useState("")
25 | const [Url, setUrl] = useState("")
26 |
27 | const handleChangeGender = (e) => {
28 | setgender(e.target.value);
29 | };
30 | const handleChangeType = (e) => {
31 | settype(e.target.value);
32 | };
33 |
34 | async function postDetails() {
35 | console.log(process.env.REACT_APP_IMG_URL);
36 | const data = new FormData()
37 | data.append("file", image)
38 | data.append("upload_preset", process.env.REACT_APP_IMG_UPLOAD)
39 | data.append("cloud_name", process.env.REACT_APP_IMG_CLOUD)
40 | const res_a = await fetch(process.env.REACT_APP_IMG_URL , {
41 | method: "post",
42 | body: data
43 | })
44 | .catch((error) => {
45 | console.log(error);
46 | });
47 | const data_a = await res_a.json();
48 | return data_a;
49 | }
50 |
51 | const postdata = async (e) => {
52 | e.preventDefault();
53 | if (password !== confpassword) {
54 | document.getElementById("msg").innerHTML = "Password hasn't matched ";
55 | return;
56 | }
57 | let a = postDetails();
58 | a.then((data) => {
59 | setUrl(data.url);
60 | responseData(data.url);
61 | }
62 | )
63 | };
64 |
65 | async function responseData(Url1) {
66 | const responseNew = await sendRequest(
67 | BASE_API_URL+'/signup',
68 | 'POST',
69 | JSON.stringify({
70 | fullname,
71 | email,
72 | password,
73 | mobile,
74 | type,
75 | gender,
76 | address,
77 | city,
78 | state,
79 | Url: Url1
80 | }),
81 | {
82 | 'Content-Type': 'application/json',
83 | }
84 | );
85 | try {
86 | if (!responseNew.userId) {
87 | document.getElementById("msg").innerHTML = "" + responseNew + " ";
88 | return;
89 | }
90 | auth.login(
91 | responseNew.userId,
92 | responseNew.token
93 | );
94 | history.push('/');
95 | }
96 | catch (err) {
97 | }
98 | }
99 |
100 | return (
101 |
102 | {/* Required meta tags */}
103 |
104 |
108 | {/* Bootstrap CSS */}
109 |
115 |
We Don't Waste Food
116 |
117 |
203 |
204 |
205 | );
206 | }
207 | export default Signup;
--------------------------------------------------------------------------------
/controllers/user-controllers.js:
--------------------------------------------------------------------------------
1 | const { validationResult } = require('express-validator');
2 | const bcrypt = require('bcryptjs');
3 | const jwt = require('jsonwebtoken');
4 | const nodemailer = require('nodemailer');
5 | const crypto = require('crypto');
6 | require('dotenv').config();
7 |
8 | const HttpError = require('../models/http-error');
9 | const User = require('../models/user');
10 | const sendgridTransport = require('nodemailer-sendgrid-transport');
11 | const transporter = nodemailer.createTransport(sendgridTransport({
12 | auth:{
13 | api_key: process.env.Mail_API
14 | }
15 | }))
16 |
17 | const signup = async (req, res, next) => {
18 | const error = validationResult(req);
19 | if (!error.isEmpty()) {
20 | return next(
21 | new HttpError('Invalid inputs passed, please check your data.', 422)
22 | );
23 | }
24 |
25 | const { fullname, email, password, mobile, gender, type, address, city, state, Url} = req.body;
26 | var currentdate = new Date();
27 | var datetime = currentdate.getDate() + "/"
28 | + (currentdate.getMonth()+1) + "/"
29 | + currentdate.getFullYear() + " @ "
30 | + currentdate.getHours() + ":"
31 | + currentdate.getMinutes() + ":"
32 | + currentdate.getSeconds();
33 |
34 | let existingUser;
35 | try {
36 | existingUser = await User.findOne({ email: email });
37 | } catch (err) {
38 | const error = new HttpError(
39 | 'Signing up failed, please try again later.',
40 | 500
41 | );
42 | return next(error);
43 | }
44 |
45 | if (existingUser) {
46 | const error = new HttpError(
47 | 'User exists already, please login instead.',
48 | 422
49 | );
50 | return next(error);
51 | }
52 |
53 | let hashedPassword;
54 | try {
55 | hashedPassword = await bcrypt.hash(password, 12);
56 | } catch (err) {
57 | const error = new HttpError(
58 | 'Could not create user, please try again.',
59 | 500
60 | );
61 | return next(error);
62 | }
63 |
64 | const createdUser = new User({
65 | fullname,
66 | email,
67 | password: hashedPassword,
68 | mobile,
69 | gender,
70 | type,
71 | address,
72 | city,
73 | state,
74 | Url,
75 | datetime
76 | });
77 |
78 | try {
79 | await createdUser.save();
80 | } catch (err) {
81 | const error = new HttpError(
82 | 'Signing up failed, please try again later.',
83 | 500
84 | );
85 | return next(error);
86 | }
87 |
88 | let token;
89 | try {
90 | token = jwt.sign(
91 | { userId: createdUser.id, email: createdUser.email },
92 | process.env.SECRET_KEY,
93 | { expiresIn: '1h' }
94 | );
95 | } catch (err) {
96 | const error = new HttpError(
97 | 'Signing up failed, please try again later.',
98 | 500
99 | );
100 | return next(error);
101 | }
102 | transporter.sendMail({
103 | to : createdUser.email,
104 | from: "we-dont-waste-food@king.buzz",
105 | subject:"Registration Successful",
106 | html:"welcome to we don't waste food "
107 | })
108 | res.status(201)
109 | .json({ userId: createdUser.id,
110 | email: createdUser.email,
111 | mobile: createdUser.mobile,
112 | gender: createdUser.gender,
113 | type: createdUser.type,
114 | address: createdUser.address,
115 | city: createdUser.city,
116 | state: createdUser.state,
117 | Url: createdUser.Url,
118 | datetime: datetime,
119 | token: token
120 | });
121 | };
122 |
123 | const login = async (req, res, next) => {
124 | const { email, password } = req.body;
125 | let existingUser;
126 | try {
127 | existingUser = await User.findOne({ email: email });
128 | } catch (err) {
129 | const error = new HttpError(
130 | 'Logging in failed, please try again later.',
131 | 500
132 | );
133 | return next(error);
134 | }
135 |
136 | if (!existingUser) {
137 | const error = new HttpError(
138 | 'Invalid credentials, could not log you in.',
139 | 403
140 | );
141 | return next(error);
142 | }
143 |
144 | let isValidPassword = false;
145 | try {
146 | isValidPassword = await bcrypt.compare(password, existingUser.password);
147 | } catch (err) {
148 | const error = new HttpError(
149 | 'Could not log you in, please check your credentials and try again.',
150 | 500
151 | );
152 | return next(error);
153 | }
154 |
155 | if (!isValidPassword) {
156 | const error = new HttpError(
157 | 'Invalid credentials, could not log you in.',
158 | 403
159 | );
160 | return next(error);
161 | }
162 |
163 | let token;
164 | try {
165 | token = jwt.sign(
166 | { userId: existingUser.id, email: existingUser.email },
167 | process.env.SECRET_KEY,
168 | { expiresIn: '1h' }
169 | );
170 | } catch (err) {
171 | const error = new HttpError(
172 | 'Logging in failed, please try again later.',
173 | 500
174 | );
175 | return next(error);
176 | }
177 | res.json({
178 | userId: existingUser.id,
179 | email: existingUser.email,
180 | token: token
181 | });
182 | };
183 |
184 | const resetPassword = (req,res,next) => {
185 | crypto.randomBytes(32,(err,buffer) => {
186 | if(err) {
187 | const error = new HttpError(
188 | 'token creation failed.',
189 | 500
190 | );
191 | return next(error);
192 | }
193 | const token1 = buffer.toString("hex");
194 | try {
195 | User.findOne({email: req.body.email})
196 | .then(user => {
197 | if(!user) {
198 | const error = new HttpError(
199 | 'no user found.',
200 | 422
201 | );
202 | return next(error);
203 | }
204 | user.resetToken = token1
205 | user.expireToken = Date.now() + 3600 * 1000
206 | try {
207 | user.save().then((result) => {
208 | transporter.sendMail({
209 | to:user.email,
210 | from:"we-dont-waste-food@king.buzz",
211 | subject:"Password Reset",
212 | html: `
213 | You requested for password reset
214 | Click in this link to reset password
215 | `
216 | })
217 | res.json({message:"check your email"})
218 | })
219 | } catch (err) {
220 | const error = new HttpError(
221 | 'Signing up failed, please try again later.',
222 | 500
223 | );
224 | return next(error);
225 | }
226 |
227 | })
228 | }catch(err){};
229 | })
230 | };
231 |
232 | const newPassword = (req,res,next) => {
233 | const newPassword = req.body.password;
234 | const sentToken = req.body.token;
235 | User.findOne({resetToken:sentToken, expireToken:{$gt:Date.now()}})
236 | .then(user=>{
237 | if(!user){
238 | const error = new HttpError(
239 | 'Email Id is not registered.',
240 | 422
241 | );
242 | return next(error);
243 | }
244 | bcrypt.hash(newPassword,12).then(hashedpassword=>{
245 | user.password = hashedpassword
246 | user.resetToken = undefined
247 | user.expireToken = undefined
248 | user.save().then((saveduser)=>{
249 | res.json({message:"Password Updateded successfully"})
250 | })
251 | })
252 | }).catch(err=>{
253 | })
254 | };
255 |
256 | const viewProfile = async (req, res, next) => {
257 | let users;
258 | try {
259 | users = await User.findOne({_id:req.userData.userId});
260 | } catch (err) {
261 | const error = new HttpError(
262 | 'Fetching User failed, please try again later.',
263 | 500
264 | );
265 | return next(error);
266 | }
267 | res.json({
268 | name: users.fullname,
269 | email: users.email,
270 | mobile: users.mobile,
271 | gender: users.gender,
272 | type: users.type,
273 | address: users.address,
274 | city: users.city,
275 | state: users.state,
276 | Url: users.Url
277 | });
278 | };
279 |
280 | const editProfile = async (req, res, next) => {
281 | let users;
282 | const { fullname, email, mobile, gender, type, address, city, state, Url} = req.body;
283 | try {
284 | users = await User.findOne({_id: req.userData.userId});
285 | users.fullname = fullname,
286 | users.email = email,
287 | users.mobile = mobile,
288 | users.gender = gender,
289 | users.type = type,
290 | users.address = address,
291 | users.city = city,
292 | users.state = state,
293 | users.Url = Url
294 | users.save().then((saveduser)=>{
295 | })
296 |
297 | } catch (err) {
298 | const error = new HttpError(
299 | 'Edit User Profile failed, please try again later.',
300 | 500
301 | );
302 | return next(error);
303 | }
304 | res.json({
305 | fullname: users.fullname,
306 | email: users.email,
307 | mobile: users.mobile,
308 | gender: users.gender,
309 | type: users.type,
310 | address: users.address,
311 | city: users.city,
312 | state: users.state,
313 | Url: users.Url
314 | });
315 | };
316 |
317 | exports.signup = signup;
318 | exports.login = login;
319 | exports.resetPassword = resetPassword;
320 | exports.newPassword = newPassword;
321 | exports.viewProfile = viewProfile;
322 | exports.editProfile = editProfile;
323 |
--------------------------------------------------------------------------------
/frontend/src/components/DisplayDetailUserDonFood.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable jsx-a11y/img-redundant-alt */
2 | /* eslint-disable no-unused-vars */
3 | import React, {useState, useContext} from 'react';
4 | import { Spinner, Button, Modal } from 'react-bootstrap';
5 | import { useHistory } from "react-router-dom";
6 | import { useHttpClient } from '../hooks/http-hook';
7 | import Moment from 'react-moment';
8 | import { AuthContext } from "../context/auth-context";
9 | import {BASE_API_URL} from '../api/api';
10 |
11 | const DisplayDetailUserDonFood = props => {
12 | const auth = useContext(AuthContext);
13 | const [show, setShow] = useState(false);
14 | const [rejmessage, setrejmessage] = useState("");
15 | const handleClose = () => setShow(false);
16 | const handleShow = () => setShow(true);
17 |
18 | const { sendRequest } = useHttpClient();
19 | const history = useHistory();
20 | let foodId;
21 | if (props.items.food.status === false) foodId = props.items.recdetail.foodId;
22 | else props.items.receiver = true;
23 | let print = false;
24 | if (props.items.receiver === true) print = true;
25 |
26 | function reject() {
27 | try {
28 | const responseData = sendRequest(
29 | BASE_API_URL+'/cancelledfood',
30 | 'POST',
31 | JSON.stringify({
32 | foodId,
33 | rejmessage
34 | }),
35 | {
36 | 'Content-Type': 'application/json',
37 | Authorization: 'Bearer ' + auth.token
38 | }
39 | );
40 | history.push('/reqforfood');
41 | }
42 | catch (err) {
43 | }
44 | }
45 |
46 | function accept() {
47 | try {
48 | const responseData = sendRequest(
49 | BASE_API_URL+'/receivedfood',
50 | 'POST',
51 | JSON.stringify({
52 | foodId
53 | }),
54 | {
55 | 'Content-Type': 'application/json',
56 | Authorization: 'Bearer ' + auth.token
57 | }
58 | );
59 | history.push('/userdonfood');
60 | }
61 | catch (err) {
62 | }
63 | }
64 |
65 | return (
66 |
67 | {/* food information */}
68 |
69 |
70 |
71 |
72 |
73 |
74 |
{props.items.food.name}
75 |
76 |
77 |
78 |
79 |
80 |
81 |
Food Name : {props.items.food.name}
82 |
Function Name : {props.items.food.funcname}
83 |
Food Type : {props.items.food.foodtype}
84 |
Food Description : {props.items.food.description}
85 |
Donator Contact No : {props.items.food.mobile}
86 |
Food Quality : {props.items.food.quality}, Food Quantity : {props.items.food.quantity}
87 |
Food Cooked Time :
88 |
89 | {props.items.food.cookedtime}
90 | , Food Expiry Time :
91 |
92 | {props.items.food.expirytime}
93 |
94 |
Food Address : {props.items.food.address}, {props.items.food.city}, {props.items.food.state}
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 | {print ?
108 |
109 |
110 |
111 | {' '}
116 | No one has yet requested for this food
117 | {' '}
122 |
123 |
124 |
:
125 |
126 | {props.items.food.received ?
127 |
128 |
129 | {' '}
134 | Congratulations Recipient {props.items.receiver.fullname} has successfully Collected your food
135 | {' '}
140 |
141 | :
142 |
143 |
144 |
145 | {props.items.receiver.fullname} has requested to receive this food. Kindly update status
146 |
147 |
Collected {' '}
148 |
Find another receiver
149 |
150 |
151 | Why food wasn't collected by receiver?
152 |
153 | setrejmessage(e.target.value)} required/>
155 |
156 |
157 | Close
158 |
159 |
160 | Send
161 |
162 |
163 |
164 |
165 | }
166 |
167 | }
168 |
169 |
170 |
171 | {/* Donator information */}
172 | {print ?
:
173 | {!props.items.food.status ?
174 |
175 |
176 |
Donor Information
177 |
178 |
FullName : {props.items.donator.fullname}
179 |
Email : {props.items.donator.email}
180 |
Contact No : {props.items.donator.mobile}
181 |
Gender : {props.items.donator.gender}
182 |
Type : {props.items.donator.type}
183 |
Address : {props.items.donator.city}, {props.items.donator.state}
184 |
185 | {/* extra div for designing */}
186 |
187 | {/* receiver information */}
188 |
189 |
Recipient Information
190 |
191 |
FullName : {props.items.receiver.fullname}
192 |
Email : {props.items.receiver.email}
193 |
Contact No : {props.items.receiver.mobile}
194 |
Gender : {props.items.receiver.gender}
195 |
Type : {props.items.receiver.type}
196 |
Address : {props.items.receiver.city}, {props.items.receiver.state}
197 |
198 |
199 |
:
200 | No one has yet requested for this food
201 | } }
202 |
203 | );
204 | };
205 |
206 | export default DisplayDetailUserDonFood;
207 |
--------------------------------------------------------------------------------
/frontend/src/screens/Donate.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-unused-vars */
2 | import React, { useState, useContext } from "react";
3 | import { AuthContext } from '../context/auth-context';
4 | import { useHistory } from "react-router-dom";
5 | import { useHttpClient } from '../hooks/http-hook';
6 | import { Button, Modal, Carousel } from 'react-bootstrap';
7 | import {BASE_API_URL} from '../api/api';
8 | import moment from 'moment';
9 | import image7 from '../images/image7.png';
10 | import image8 from '../images/image88.jpg';
11 | import MapNew from "../components/MapNew";
12 | require('dotenv').config();
13 |
14 | function Donate() {
15 |
16 | const auth = useContext(AuthContext);
17 | const { sendRequest } = useHttpClient();
18 |
19 | let message = "";
20 | const [showmessage, setshowmessage] = useState("");
21 | const [show, setShow] = useState(false);
22 | const handleClose = () => setShow(false);
23 |
24 | const history = useHistory();
25 | const [funcname, setfuncname] = useState("");
26 | const [name, setname] = useState("");
27 | const [mobile, setmobile] = useState("");
28 | const [description, setdescription] = useState("");
29 | const [quantity, setquantity] = useState("");
30 | const [quality, setquality] = useState("5");
31 | const [foodtype, setFoodType] = useState("Beverage");
32 | const [cookedtime, setcookedtime] = useState("");
33 | const [expirytime, setexpirytime] = useState("");
34 | const [image, setimage] = useState("");
35 | const [Url, setUrl] = useState("");
36 | const [map, setMap] = useState({});
37 |
38 | const handleChange = (e) => {
39 | setquality(e.target.value)
40 | }
41 |
42 | const handleChangeType = (e) => {
43 | setFoodType(e.target.value)
44 | }
45 |
46 | const mapChangeType = (e) => {
47 | setMap(e)
48 | }
49 |
50 | function setMapValue(data) {
51 | mapChangeType(data);
52 | }
53 |
54 | async function postDetails() {
55 |
56 | const data = new FormData();
57 | data.append("file", image);
58 | data.append("upload_preset", process.env.REACT_APP_IMG_UPLOAD);
59 | data.append("cloud_name", process.env.REACT_APP_IMG_CLOUD);
60 | const res_a = await fetch(process.env.REACT_APP_IMG_URL , {
61 | method: "post",
62 | body: data
63 | })
64 | .catch((error) => {
65 | console.log(error);
66 | });
67 | const data_a = await res_a.json();
68 | return data_a;
69 | }
70 |
71 | const postdata = async (e) => {
72 |
73 | e.preventDefault();
74 | message = "";
75 |
76 | var currentdate = new Date();
77 | var datetime = currentdate.getFullYear() + "-"
78 | + (currentdate.getMonth() < 10 ? "0" : "") + (currentdate.getMonth() + 1) + "-"
79 | + (currentdate.getDate() < 10 ? "0" : "") + currentdate.getDate() + "T"
80 | + (currentdate.getHours() < 10 ? "0" : "") + currentdate.getHours() + ":"
81 | + (currentdate.getMinutes() < 10 ? "0" : "") + currentdate.getMinutes();
82 |
83 | var dateIsBefore = moment(cookedtime).isBefore(moment(expirytime));
84 | var dateIsBeforeExpTime = moment(datetime).isBefore(moment(expirytime));
85 | var dateIsAfter = moment(datetime).isAfter(moment(cookedtime));
86 | if (!dateIsBefore) message = message + "Your Cooked Time is earlier than Expiry Time...";
87 | if (!dateIsBeforeExpTime) message = message + "You must enter Valid Expiry Time...";
88 | if (!dateIsAfter) message = message + "Your must enter Cooked Time less than Current Time...";
89 | console.log("Current "+datetime);
90 | console.log("CookedTime "+ cookedtime);
91 | console.log("ExpiryTime "+ expirytime);
92 |
93 | setshowmessage(message);
94 | if (message.length !== 0) {
95 | setShow(true);
96 | }
97 | else {
98 | let a = postDetails();
99 | a.then((data) => {
100 | setUrl(data.url);
101 | responseData(data.url);
102 | })
103 | }
104 | };
105 |
106 | async function responseData(Url1) {
107 | const responseNew = await sendRequest(
108 | BASE_API_URL+'/donate',
109 | 'POST',
110 | JSON.stringify({
111 | funcname,
112 | name,
113 | mobile,
114 | description,
115 | quantity,
116 | quality,
117 | foodtype,
118 | cookedtime,
119 | expirytime,
120 | address: map.address,
121 | city: map.city,
122 | state: map.state,
123 | lat: map.mapPosition.lat,
124 | lng: map.mapPosition.lng,
125 | Url: Url1
126 | }),
127 | {
128 | 'Content-Type': 'application/json',
129 | Authorization: 'Bearer ' + auth.token
130 | }
131 | );
132 |
133 | try {
134 | if (!responseNew.userId) {
135 | document.getElementById("msg").innerHTML = "" + responseNew + " ";
136 | return;
137 | }
138 | history.push('/reqforfood');
139 | }
140 | catch (err) {
141 | }
142 | }
143 |
144 | return (
145 |
146 | {/* Required meta tags */}
147 |
148 |
149 | {/* Bootstrap CSS */}
150 |
151 |
We Don't Waste Food
152 |
153 |
154 |
155 |
160 |
161 | OUR MISSION
162 |
163 | Make India Hunger Free
164 |
165 |
166 |
167 |
168 |
173 |
174 | YOUR SUPPORT MATTERS
175 |
176 | Contribute to help us provide essential food support to those in need
177 |
178 |
179 |
180 |
181 |
182 |
183 |
290 |
291 |
292 |
293 |
294 |
295 |
296 | )
297 | }
298 | export default Donate;
--------------------------------------------------------------------------------
/controllers/food-controller.js:
--------------------------------------------------------------------------------
1 | const { validationResult } = require('express-validator');
2 | const nodemailer = require('nodemailer');
3 | require('dotenv').config();
4 |
5 | const HttpError = require('../models/http-error');
6 | const Food = require('../models/food');
7 | const Receive = require('../models/receive');
8 | const User = require('../models/user');
9 | const sendgridTransport = require('nodemailer-sendgrid-transport');
10 | const transporter = nodemailer.createTransport(sendgridTransport({
11 | auth:{
12 | api_key: process.env.Mail_API
13 | }
14 | }))
15 |
16 | const addfood = async (req, res, next) => {
17 | const errors = validationResult(req);
18 | if (!errors.isEmpty()) {
19 | return next(
20 | new HttpError('Invalid inputs passed, please check your data.', 422)
21 | );
22 | }
23 |
24 | const { funcname, name, mobile, description, quantity, quality, foodtype, cookedtime, expirytime, address, city, state, lat, lng, Url } = req.body;
25 |
26 | var currentdate = new Date();
27 | var datetime = currentdate.getDate() + "/"
28 | + (currentdate.getMonth()+1) + "/"
29 | + currentdate.getFullYear() + " @ "
30 | + currentdate.getHours() + ":"
31 | + currentdate.getMinutes() + ":"
32 | + currentdate.getSeconds();
33 |
34 | let recId = false;
35 | let status = true;
36 | let received = false;
37 | const addedFood = new Food({
38 | userId:req.userData.userId,
39 | recId,
40 | funcname,
41 | name,
42 | mobile,
43 | description,
44 | quantity,
45 | quality,
46 | foodtype,
47 | cookedtime,
48 | expirytime,
49 | status,
50 | received,
51 | address,
52 | city,
53 | state,
54 | lat,
55 | lng,
56 | Url,
57 | datetime
58 | });
59 | try {
60 | await addedFood.save();
61 | } catch (err) {
62 | const error = new HttpError(
63 | 'Adding Food failed, please try again later.',
64 | 500
65 | );
66 | return next(error);
67 | }
68 | res
69 | .status(201)
70 | .json({ foodId: addedFood.id,
71 | userId: addedFood.userId,
72 | funcname: addedFood.funcname,
73 | name: addedFood.name,
74 | mobile: addedFood.mobile,
75 | description: addedFood.description,
76 | quantity: addedFood.quantity,
77 | quality: addedFood.quality,
78 | foodtype: addedFood.foodtype,
79 | cookedtime: addedFood.cookedtime,
80 | expirytime: addedFood.expirytime,
81 | address: addedFood.address,
82 | status: status,
83 | received: received,
84 | city: addedFood.city,
85 | state: addedFood.state,
86 | lat: addedFood.lat,
87 | lng: addedFood.lng,
88 | Url: addedFood.Url,
89 | datetime: datetime
90 | });
91 | };
92 |
93 | const getFood = async (req, res, next) => {
94 | let foods;
95 | try {
96 | var currentDate = new Date();
97 | foods = await Food.find({status:'true',received:'false', expirytime:{$gt:currentDate}}, '-datetime');
98 | } catch (err) {
99 | const error = new HttpError(
100 | 'Fetching food failed, please try again later.',
101 | 500
102 | );
103 | return next(error);
104 | }
105 | res.json({ foods: foods.map(food => food.toObject({getters: true })) });
106 | };
107 |
108 | const viewfood = async (req, res, next) => {
109 | let food;
110 | try {
111 | food = await Food.findOne({_id:req.body.foodId}, '-datetime');
112 | } catch (err) {
113 | const error = new HttpError(
114 | 'Fetching food failed, please try again later.',
115 | 500
116 | );
117 | return next(error);
118 | }
119 | let coor = { "lat":food.lat, "lng":food.lng};
120 | res.json({foodId: food.id,
121 | userId: food.userId,
122 | funcname: food.funcname,
123 | name: food.name,
124 | mobile: food.mobile,
125 | description: food.description,
126 | quantity: food.quantity,
127 | quality: food.quality,
128 | foodtype: food.foodtype,
129 | cookedtime: food.cookedtime,
130 | expirytime: food.expirytime,
131 | address: food.address,
132 | status: food.status,
133 | received: food.received,
134 | city: food.city,
135 | state: food.state,
136 | coor: coor,
137 | Url: food.Url
138 | });
139 | };
140 |
141 | const deletefood = async (req, res, next) => {
142 | try {
143 | let food = await Food.deleteOne({_id: req.body.foodId});
144 | res.send(food);
145 | } catch (err) {
146 | const error = new HttpError(
147 | 'Deleting food failed, please try again later.',
148 | 500
149 | );
150 | return next(error);
151 | }
152 | };
153 |
154 | const acceptfood = async (req, res, next) => {
155 | let food,donator,receiver;
156 | const { donId, foodId, name, email, mobile, address, exptime } = req.body;
157 | try {
158 | food = await Food.findOne({_id:foodId});
159 | donator = await User.findOne({_id:donId});
160 | receiver = await User.findOne({_id:req.userData.userId});
161 | food.status = false;
162 | food.recId = req.userData.userId;
163 | const receive = new Receive({
164 | donId,
165 | foodId,
166 | recId:req.userData.userId,
167 | name,
168 | email,
169 | mobile,
170 | address,
171 | exptime
172 | });
173 | try {
174 | await receive.save();
175 | await food.save();
176 | transporter.sendMail({
177 | to : donator.email,
178 | from: "we-dont-waste-food@king.buzz",
179 | subject:`${receiver.fullname} has Requested for ${food.name}`,
180 | html:`${receiver.fullname} has Requested for ${food.name}
181 |
182 |
Donator: ${donator.fullname}
183 |
Receiver: ${receiver.fullname}
184 |
Food: ${food.name}
185 |
Pickup time: ${receive.exptime}
186 |
`
187 | })
188 | transporter.sendMail({
189 | to : receiver.email,
190 | from: "we-dont-waste-food@king.buzz",
191 | subject:`You have successfully requested ${food.name} from ${donator.fullname}`,
192 | html:`You have successfully requested ${food.name} from ${donator.fullname}
193 |
194 |
Donator: ${donator.fullname}
195 |
Receiver: ${receiver.fullname}
196 |
Food: ${food.name}
197 |
Pickup time: ${receive.exptime}
198 |
`
199 | })
200 | } catch (err) {
201 | const error = new HttpError(
202 | 'receive 1failed, please try again later.',
203 | 500
204 | );
205 | return next(error);
206 | }
207 | } catch (err) {
208 | const error = new HttpError(
209 | 'receive 2failed, please try again later.',
210 | 500
211 | );
212 | return next(error);
213 | }
214 | res.json({
215 | donId: donId,
216 | foodId: foodId,
217 | recId: req.userData.userId,
218 | name: name,
219 | email: email,
220 | mobile: mobile,
221 | address: address,
222 | exptime: exptime
223 | });
224 | };
225 |
226 | const viewdonatedfood = async (req, res, next) => {
227 | let foods;
228 | try {
229 | foods = await Food.find({userId: req.userData.userId});
230 | } catch (err) {
231 | const error = new HttpError(
232 | 'Fetching food failed, please try again later.',
233 | 500
234 | );
235 | return next(error);
236 | }
237 | res.json({ foods: foods.map(food => food.toObject({getters: true })) });
238 | };
239 |
240 | const viewreceivedfood = async (req, res, next) => {
241 | let foods;
242 | try {
243 | foods = await Food.find({recId: req.userData.userId});
244 | } catch (err) {
245 | const error = new HttpError(
246 | 'Fetching food failed, please try again later.',
247 | 500
248 | );
249 | return next(error);
250 | }
251 | res.json({ foods: foods.map(food => food.toObject({getters: true })) });
252 | };
253 |
254 | const openviewdonatefood = async (req, res, next) => {
255 | let food,donator,receiver,recdetail;
256 | try {
257 | food = await Food.findOne({_id: req.body.foodId});
258 | donator = await User.findOne({_id: req.userData.userId});
259 | try {
260 | receiver = await User.findOne({_id: food.recId});
261 | recdetail = await Receive.findOne({foodId: req.body.foodId});
262 | } catch (err) {
263 | receiver = false;
264 | recdetail = false;
265 | }
266 | } catch (err) {
267 | const error = new HttpError(
268 | 'Fetching food failed, please try again later.',
269 | 500
270 | );
271 | return next(error);
272 | }
273 | let details = { "food":food, "donator":donator, "receiver":receiver, "recdetail":recdetail };
274 | res.send(details);
275 | };
276 |
277 | const openviewreceivedfood = async (req, res, next) => {
278 | let food,receiver,donator,recdetail;
279 | try {
280 | food = await Food.findOne({_id: req.body.foodId});
281 | receiver = await User.findOne({_id: req.userData.userId});
282 | donator = await User.findOne({_id: food.userId});
283 | recdetail = await Receive.findOne({foodId: req.body.foodId});
284 | } catch (err) {
285 | const error = new HttpError(
286 | 'Fetching food failed, please try again later.',
287 | 500
288 | );
289 | return next(error);
290 | }
291 | let details = { "food":food, "donator":donator, "receiver":receiver ,"recdetail":recdetail};
292 | res.send(details);
293 | };
294 |
295 | const receivedfood = async (req, res, next) => {
296 | try {
297 | let food = await Food.findOne({_id: req.body.foodId});
298 | let receiver = await User.findOne({_id: food.recId});
299 | let donator = await User.findOne({_id: food.userId});
300 | food.received = true;
301 | try {
302 | await food.save();
303 | transporter.sendMail({
304 | to : donator.email,
305 | from: "we-dont-waste-food@king.buzz",
306 | subject:`Congratulations, ${donator.fullname}`,
307 | html:`We got your confirmation that ${receiver.fullname} has collected ${food.name} succesfully.
308 |
309 |
Donator: ${donator.fullname}
310 |
Receiver: ${receiver.fullname}
311 |
Food: ${food.name}
312 |
`
313 | })
314 | transporter.sendMail({
315 | to : receiver.email,
316 | from: "we-dont-waste-food@king.buzz",
317 | subject:`Congratulation ${receiver.fullname}`,
318 | html:`${donator.fullname} has confirmed the pickup of ${food.name} succesfully.
319 |
320 |
Donator: ${donator.fullname}
321 |
Receiver: ${receiver.fullname}
322 |
Food: ${food.name}
323 |
`
324 | })
325 | } catch (err) {
326 | const error = new HttpError(
327 | 'received 1failed, please try again later.',
328 | 500
329 | );
330 | return next(error);
331 | }
332 | } catch (err) {
333 | const error = new HttpError(
334 | 'received 2failed, please try again later.',
335 | 500
336 | );
337 | return next(error);
338 | }
339 | };
340 |
341 | const cancelledfood = async (req, res, next) => {
342 | try {
343 | let food = await Food.findOne({_id: req.body.foodId});
344 | let receiver = await User.findOne({_id: food.recId});
345 | let donator = await User.findOne({_id: food.userId});
346 | let data = await Receive.deleteOne({foodId: req.body.foodId});
347 |
348 | try {
349 | transporter.sendMail({
350 | to : donator.email,
351 | from: "we-dont-waste-food@king.buzz",
352 | subject:`You have rejected the request of ${food.name} by ${receiver.fullname}`,
353 | html:`You have rejected the request of ${food.name} by ${receiver.fullname}
354 |
355 |
Donator: ${donator.fullname}
356 |
Receiver: ${receiver.fullname}
357 |
Food: ${food.name}
358 |
`
359 | })
360 | transporter.sendMail({
361 | to : receiver.email,
362 | from: "we-dont-waste-food@king.buzz",
363 | subject:`${donator.fullname} had rejected your request of ${food.name}`,
364 | html:`${donator.fullname} had rejeted your request of ${food.name}
365 |
Reason of Rejection: ${req.body.rejmessage}
366 |
367 |
Donator: ${donator.fullname}
368 |
Receiver: ${receiver.fullname}
369 |
Food: ${food.name}
370 |
`
371 | })
372 | food.recId = false;
373 | food.status = true;
374 | await food.save();
375 | await data.save();
376 |
377 | } catch (err) {
378 | const error = new HttpError(
379 | 'received 1failed, please try again later.',
380 | 500
381 | );
382 | return next(error);
383 | }
384 | } catch (err) {
385 | const error = new HttpError(
386 | 'received 2failed, please try again later.',
387 | 500
388 | );
389 | return next(error);
390 | }
391 | };
392 |
393 | const contributors = async (req,res,next) => {
394 | var Don = [];
395 | var Rec = [];
396 | try{
397 |
398 | let donator = await Receive.aggregate([
399 | {$group: {_id: "$donId", count: {$sum:1}}},
400 | {$sort: {count: -1}}
401 | ])
402 | for(var i = 0; i < donator.length, i<3; i++) {
403 | let don = await User.findById(donator[i]._id);
404 | let count = donator[i].count;
405 | Don[i] = {"don":don, "count":count}
406 | }
407 |
408 | let receiver = await Receive.aggregate([
409 | {$group: {_id: "$recId", count: {$sum:1}}},
410 | {$sort: {'count': -1}}
411 | ])
412 | for(var i = 0; i < receiver.length,i<3; i++) {
413 | let rec = await User.findById(receiver[i]._id);
414 | let count = receiver[i].count;
415 | Rec[i] = {"rec":rec, "count":count}
416 | }
417 | }catch(err){
418 | const error = new HttpError(
419 | 'failed, please try again later.',
420 | 500
421 | );
422 | }
423 | let contributors = {"Don":Don, "Rec":Rec}
424 | res.send(contributors);
425 | };
426 |
427 | exports.viewfood = viewfood;
428 | exports.addfood = addfood;
429 | exports.getFood = getFood;
430 | exports.deletefood = deletefood;
431 | exports.acceptfood = acceptfood;
432 | exports.viewdonatedfood = viewdonatedfood;
433 | exports.viewreceivedfood = viewreceivedfood;
434 | exports.receivedfood = receivedfood;
435 | exports.cancelledfood = cancelledfood;
436 | exports.openviewdonatefood = openviewdonatefood;
437 | exports.openviewreceivedfood = openviewreceivedfood;
438 | exports.contributors = contributors;
--------------------------------------------------------------------------------