├── .DS_Store ├── client ├── .DS_Store ├── assets │ ├── Star-nosed-mole.png │ └── app-background.jpg ├── stylesheets │ ├── style.css │ ├── Matches.css │ ├── FeedItem.css │ ├── MatchesItem.css │ ├── Feed.css │ ├── Profile.css │ ├── NavBar.css │ ├── MatchPopUp.css │ ├── SignUp.css │ └── Login.css ├── index.js ├── index.html ├── components │ ├── MatchPopUp.js │ ├── FeedItem.js │ ├── UpdateProfile.js │ ├── NavBar.js │ └── MatchesItem.js ├── Matches.js ├── Profile.js ├── App.js ├── Login.js ├── SignUp.js └── Feed.js ├── README.md ├── server ├── userModel.js ├── api.js ├── server.js └── controller.js ├── LICENSE ├── webpack.config.js ├── package.json └── .gitignore /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DangerNoodles36/CodersOnly/HEAD/.DS_Store -------------------------------------------------------------------------------- /client/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DangerNoodles36/CodersOnly/HEAD/client/.DS_Store -------------------------------------------------------------------------------- /client/assets/Star-nosed-mole.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DangerNoodles36/CodersOnly/HEAD/client/assets/Star-nosed-mole.png -------------------------------------------------------------------------------- /client/assets/app-background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DangerNoodles36/CodersOnly/HEAD/client/assets/app-background.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Scratch-Project 2 | 3 | Star Mole credit: 4 | https://www.redbubble.com/i/sticker/Star-Nosed-Mole-by-GardenDragon/11822172.EJUG5 5 | -------------------------------------------------------------------------------- /client/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | /* .profile { 2 | border: solid black; 3 | } 4 | 5 | .profile-page { 6 | border: solid red; 7 | } 8 | 9 | .profile-image { 10 | border: solid blue; 11 | text-align:center; 12 | } 13 | 14 | .profile-bio { 15 | border: solid blue; 16 | text-align:center; 17 | } */ 18 | -------------------------------------------------------------------------------- /client/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import App from './App.js'; 4 | import { BrowserRouter } from 'react-router-dom'; 5 | 6 | const root = ReactDOM.createRoot(document.querySelector('#root')); 7 | root.render( 8 | 9 | 10 | 11 | ); 12 | -------------------------------------------------------------------------------- /client/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /client/stylesheets/Matches.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #c4fff9; 3 | } 4 | 5 | .MainMatchesContainer { 6 | margin: 50px; 7 | background-color: #c4fff9; 8 | display: grid; 9 | grid-template-columns: repeat(3, 1fr); 10 | justify-items: center; 11 | align-items: center; 12 | gap: 50px; 13 | } 14 | 15 | .MyMatches { 16 | font-family: 'DejaVu Sans Mono', sans-serif; 17 | margin-left: 50px; 18 | } 19 | -------------------------------------------------------------------------------- /client/components/MatchPopUp.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import '../stylesheets/MatchPopUp.css'; 3 | 4 | const MatchPopUp = (props) => { 5 | return ( 6 | 15 | ); 16 | }; 17 | 18 | export default MatchPopUp; 19 | -------------------------------------------------------------------------------- /server/userModel.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | const Schema = mongoose.Schema; 3 | 4 | const userSchema = mongoose.Schema({ 5 | username: { type: String, required: true }, 6 | password: { type: String, required: true }, 7 | age: { type: Number, required: true }, 8 | location: { type: String, required: true }, 9 | proglang: { type: String, required: true }, 10 | matches: {}, 11 | comment: { type: String, default: ' ' }, 12 | url: { type: String }, 13 | }); 14 | 15 | const User = mongoose.model('user', userSchema); 16 | 17 | module.exports = User; 18 | -------------------------------------------------------------------------------- /client/stylesheets/FeedItem.css: -------------------------------------------------------------------------------- 1 | .feedImage { 2 | height: 400px; 3 | width: 100%; 4 | object-fit: cover; 5 | } 6 | 7 | .feedContainer { 8 | margin-top: 50px; 9 | width: 500px; 10 | display: flex; 11 | flex-direction: column; 12 | align-items: center; 13 | background-color: whitesmoke; 14 | border-radius: 10px; 15 | box-shadow: rgba(0, 0, 0, 0.2) 0px 12px 28px 0px, 16 | rgba(0, 0, 0, 0.1) 0px 2px 4px 0px, 17 | rgba(255, 255, 255, 0.05) 0px 0px 0px 1px inset; 18 | } 19 | 20 | .feedContainer p { 21 | font-family: 'DejaVu Sans Mono', sans-serif; 22 | } 23 | 24 | .username { 25 | border-radius: 10px 10px 0 0; 26 | width: 100%; 27 | background-color: #9ceaef; 28 | } 29 | 30 | .username h3 { 31 | text-align: center; 32 | } 33 | -------------------------------------------------------------------------------- /client/stylesheets/MatchesItem.css: -------------------------------------------------------------------------------- 1 | .matchesImage { 2 | height: 400px; 3 | width: 100%; 4 | object-fit: cover; 5 | } 6 | 7 | .matchesContainer { 8 | display: flex; 9 | flex-direction: column; 10 | align-items: center; 11 | margin-top: 50px; 12 | width: 500px; 13 | background-color: whitesmoke; 14 | border-radius: 10px; 15 | box-shadow: rgba(0, 0, 0, 0.2) 0px 12px 28px 0px, 16 | rgba(0, 0, 0, 0.1) 0px 2px 4px 0px, 17 | rgba(255, 255, 255, 0.05) 0px 0px 0px 1px inset; 18 | } 19 | 20 | .matchesContainer p { 21 | font-family: 'DejaVu Sans Mono', sans-serif; 22 | align-items: center; 23 | } 24 | 25 | .username { 26 | border-radius: 10px 10px 0 0; 27 | width: 100%; 28 | background-color: #9ceaef; 29 | } 30 | 31 | .username h3 { 32 | text-align: center; 33 | } 34 | -------------------------------------------------------------------------------- /client/stylesheets/Feed.css: -------------------------------------------------------------------------------- 1 | .feedDiv button { 2 | font-family: 'DejaVu Sans Mono', sans-serif; 3 | } 4 | 5 | .feedDiv { 6 | display: flex; 7 | flex-direction: column; 8 | justify-content: center; 9 | align-items: center; 10 | background-color: #c4fff9; 11 | background-size: cover; 12 | padding-bottom: 60px; 13 | } 14 | 15 | .feedBtns { 16 | display: flex; 17 | gap: 10px; 18 | } 19 | 20 | .feedBtns button { 21 | width: 100px; 22 | height: 30px; 23 | border: none; 24 | outline: none; 25 | background: #2f2f2f; 26 | color: #fff; 27 | font-size: 18px; 28 | border-radius: 10px; 29 | text-align: center; 30 | box-shadow: 0 6px 20px -5px rgba(0, 0, 0, 0.4); 31 | position: relative; 32 | overflow: hidden; 33 | cursor: pointer; 34 | margin-top: 20px; 35 | box-shadow: rgba(0, 0, 0, 0.19) 0px 10px 20px, rgba(0, 0, 0, 0.23) 0px 6px 6px; 36 | } 37 | -------------------------------------------------------------------------------- /client/components/FeedItem.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import '../stylesheets/FeedItem.css'; 3 | 4 | const FeedItem = (props) => { 5 | //the way each user profile will look in the feed 6 | if (!props.user) { 7 | return

No more users in your area

; 8 | } 9 | const { username, age, location, comment, proglang, url } = props.user; 10 | return ( 11 |
12 |
13 |

{username}

14 |
15 | profileImage 16 |

Age: {age}

17 |

Location: {location}

18 |

Bio: {comment}

19 |

Programming Language: {proglang}

20 |
21 | ); 22 | }; 23 | 24 | export default FeedItem; 25 | -------------------------------------------------------------------------------- /client/stylesheets/Profile.css: -------------------------------------------------------------------------------- 1 | .profilePage { 2 | display: flex; 3 | justify-content: center; 4 | align-items: center; 5 | } 6 | 7 | .profileImage { 8 | height: 400px; 9 | width: 100%; 10 | object-fit: cover; 11 | } 12 | 13 | .profileContainer { 14 | margin-top: 50px; 15 | width: 500px; 16 | display: flex; 17 | flex-direction: column; 18 | align-items: center; 19 | background-color: whitesmoke; 20 | border-radius: 10px; 21 | box-shadow: rgba(0, 0, 0, 0.2) 0px 12px 28px 0px, 22 | rgba(0, 0, 0, 0.1) 0px 2px 4px 0px, 23 | rgba(255, 255, 255, 0.05) 0px 0px 0px 1px inset; 24 | } 25 | 26 | .profileContainer p { 27 | font-family: 'DejaVu Sans Mono', sans-serif; 28 | } 29 | 30 | .username { 31 | border-radius: 10px 10px 0 0; 32 | width: 100%; 33 | background-color: #9ceaef; 34 | font-family: 'DejaVu Sans Mono', sans-serif; 35 | text-align: center; 36 | } 37 | -------------------------------------------------------------------------------- /client/components/UpdateProfile.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from "react"; 2 | 3 | //need to send patch request 4 | // stretch feature? 5 | const UpdateProfile = () => { 6 | return ( 7 |
8 |
9 | 10 |

11 | 12 |

13 | 14 |

15 | 16 |

17 |

18 |
19 |
20 | ) 21 | }; 22 | 23 | 24 | export default UpdateProfile; -------------------------------------------------------------------------------- /client/components/NavBar.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import '../stylesheets/NavBar.css'; 3 | import { Link } from 'react-router-dom'; 4 | import Mole from '../assets/Star-nosed-mole.png'; 5 | 6 | const Navbar = () => { 7 | //the way each user profile will look in the feed 8 | return ( 9 |
10 | 27 |
28 | ); 29 | }; 30 | 31 | export default Navbar; 32 | -------------------------------------------------------------------------------- /server/api.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const controller = require('./controller'); 4 | 5 | router.post('/verification', controller.verifyUser, (req, res) => { 6 | return res.status(201).json(res.locals.userExists); 7 | }); 8 | 9 | router.post('/', controller.createUser, (req, res) => { 10 | return res.status(201).json(res.locals.user); 11 | }); 12 | 13 | //get data from all users stored in database 14 | router.get('/friends', controller.getFriends, (req, res) => { 15 | return res.status(200).json(res.locals.friends); 16 | }); 17 | 18 | router.get('/:username', controller.getUser, (req, res) => { 19 | // console.log('res.locals.users ' + res.locals.user); 20 | return res.status(201).json(res.locals.user); 21 | }); 22 | 23 | router.patch( 24 | '/:username/:clickedUser/:decision', 25 | controller.updateUserMatches, 26 | (req, res) => { 27 | console.log(res.locals.match); 28 | return res.status(200).json(res.locals.match); 29 | } 30 | ); 31 | 32 | module.exports = router; 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 FoodieMeetsFoodie 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /client/Matches.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import { Link } from 'react-router-dom'; 3 | import MatchesItem from './components/MatchesItem'; 4 | import Navbar from './components/NavBar'; 5 | import './stylesheets/Matches.css'; 6 | const Matches = (props) => { 7 | const [userMatches, setUserMatches] = useState([]); 8 | 9 | useEffect(() => { 10 | fetch(`/api/${props.currUser}`) 11 | .then((data) => data.json()) 12 | .then((data) => { 13 | //props.allUser contains all user profiles, el is another users profile 14 | const matchesArr = props.allUsers.filter((el) => { 15 | if ( 16 | data.matches[el.username] === 'yes' && 17 | el.matches[props.currUser] === 'yes' 18 | ) 19 | return true; 20 | }); 21 | const matchesItemsArr = matchesArr.map((el) => { 22 | return ; 23 | }); 24 | 25 | setUserMatches(matchesItemsArr); 26 | }); 27 | }, []); 28 | 29 | return ( 30 |
31 | 32 |

My Matches

33 |
{userMatches}
34 |
35 | ); 36 | }; 37 | 38 | export default Matches; 39 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack'); 2 | const path = require('path'); 3 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 4 | 5 | const config = { 6 | entry: './client/index.js', 7 | output: { 8 | path: path.resolve(__dirname, 'dist'), 9 | filename: 'bundle.js', 10 | publicPath: '/', 11 | }, 12 | mode: process.env.NODE_ENV, 13 | devServer: { 14 | static: { 15 | directory: path.join(__dirname, './build'), 16 | publicPath: '/', 17 | }, 18 | // port: 3000, 19 | proxy: { 20 | '/api/**': 'http://localhost:3000', 21 | }, 22 | }, 23 | module: { 24 | rules: [ 25 | { 26 | test: /\.(js|jsx)$/, 27 | use: { 28 | loader: 'babel-loader', 29 | options: { 30 | presets: ['@babel/preset-env', '@babel/preset-react'], 31 | }, 32 | }, 33 | exclude: /node_modules/, 34 | }, 35 | { 36 | test: /\.css$/, 37 | use: ['style-loader', 'css-loader'], 38 | }, 39 | { 40 | test: /\.scss$/, 41 | use: ['style-loader', 'css-loader', 'sass-loader'], 42 | }, 43 | { 44 | test: /\.png|svg|jpg|gif$/, 45 | use: ['file-loader'], 46 | }, 47 | ], 48 | }, 49 | resolve: { extensions: ['*', '.js', '.jsx'] }, 50 | plugins: [new HtmlWebpackPlugin({ template: './client/index.html' })], 51 | }; 52 | 53 | module.exports = config; 54 | -------------------------------------------------------------------------------- /server/server.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const app = express(); 3 | const mongoose = require('mongoose'); 4 | const port = 3000; 5 | const apiRouter = require('./api.js'); 6 | 7 | mongoose.connect( 8 | 'mongodb+srv://jchen0903:ilovecodesmith@cluster0.wjuijhf.mongodb.net/FoodTinder?retryWrites=true&w=majority' 9 | ); 10 | 11 | //added this bc axios issues 12 | app.use((req, res, next) => { 13 | res.setHeader("Access-Control-Allow-Origin", "*"); 14 | res.setHeader("Access-Control-Allow-Credentials", "true"); 15 | res.setHeader("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT"); 16 | res.setHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers"); 17 | res.status(200); 18 | next(); 19 | }); 20 | 21 | app.use(express.urlencoded({ extended: true })); 22 | app.use(express.json()); 23 | 24 | app.use('/api', apiRouter); 25 | 26 | 27 | app.use((err, req, res, next) => { 28 | const defaultErr = { 29 | log: 'Express error handler caught unknown middleware error', 30 | status: 500, 31 | message: { err: 'An error occurred' }, 32 | }; 33 | const errorObj = Object.assign({}, defaultErr, err); 34 | console.log(errorObj.log); 35 | return res.status(errorObj.status).json(errorObj.message); 36 | }); 37 | 38 | app.listen(port, () => console.log(`Server started on port ${port}`)); 39 | 40 | module.exports = app; 41 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "scratch-project", 3 | "description": "", 4 | "version": "1.0.0", 5 | "main": "webpack.config.js", 6 | "scripts": { 7 | "start": "NODE_ENV=production node server/server.js", 8 | "build": "NODE_ENV=production webpack", 9 | "dev": "NODE_ENV=development webpack-dev-server --open & nodemon server/server.js" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/FoodieMeetsFoodie/Scratch-Project.git" 14 | }, 15 | "keywords": [], 16 | "author": "", 17 | "license": "ISC", 18 | "bugs": { 19 | "url": "https://github.com/FoodieMeetsFoodie/Scratch-Project/issues" 20 | }, 21 | "homepage": "https://github.com/FoodieMeetsFoodie/Scratch-Project#readme", 22 | "dependencies": { 23 | "@babel/preset-react": "^7.18.6", 24 | "axios": "^1.1.3", 25 | "concurrently": "^7.4.0", 26 | "dotenv": "^16.0.3", 27 | "eslint": "^8.26.0", 28 | "eslint-config": "^0.3.0", 29 | "express": "^4.18.2", 30 | "file-loader": "^6.2.0", 31 | "mongoose": "^6.6.7", 32 | "nodemon": "^2.0.20", 33 | "react": "^18.2.0", 34 | "react-dom": "^18.2.0", 35 | "react-router-dom": "^6.4.2", 36 | "webpack-dev-server": "^4.11.1" 37 | }, 38 | "devDependencies": { 39 | "@babel/core": "^7.19.6", 40 | "@babel/preset-env": "^7.19.4", 41 | "babel-loader": "^8.2.5", 42 | "css-loader": "^6.7.1", 43 | "html-webpack-plugin": "^5.5.0", 44 | "style-loader": "^3.3.1", 45 | "webpack": "^5.74.0", 46 | "webpack-cli": "^4.10.0" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /client/Profile.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import { Link } from 'react-router-dom'; 3 | import Navbar from './components/NavBar'; 4 | import './stylesheets/Profile.css'; 5 | 6 | //need to fetch our profile data from the database to fill in our profile 7 | const Profile = (props) => { 8 | //deconstructed props object 9 | const [profileData, setProfileData] = useState({ 10 | username: null, 11 | age: null, 12 | location: null, 13 | comment: null, 14 | proglang: null, 15 | }); 16 | 17 | useEffect(() => { 18 | fetch(`/api/${props.currUser}`) 19 | .then((data) => { 20 | return data.json(); 21 | }) 22 | .then((data) => { 23 | setProfileData(data); 24 | }); 25 | }, []); 26 | 27 | console.log(profileData); 28 | 29 | const { username, age, location, comment, proglang, url } = profileData; 30 | 31 | return ( 32 |
33 | 34 |
35 |
36 |
37 |

{username}

38 |
39 | profileImage 40 |

Age: {age}

41 |

Location: {location}

42 |

Bio: {comment}

43 |

Programming Language: {proglang}

44 |
45 |
46 |
47 | ); 48 | }; 49 | 50 | export default Profile; 51 | -------------------------------------------------------------------------------- /client/components/MatchesItem.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import '../stylesheets/MatchesItem.css'; 3 | 4 | const MatchesItem = (props) => { 5 | // The way each user profile will look in the feed 6 | if (!props.user) { 7 | return

You have no matches xD

; 8 | } 9 | const { username, age, location, comment, proglang, url } = props.user; 10 | return ( 11 |
12 |
13 |

{username}

14 |
15 | profileImage 16 |

Age: {age}

17 |

Location: {location}

18 |

Bio: {comment}

19 |

Programming Language: {proglang}

20 | 21 |
22 | ); 23 | }; 24 | 25 | export default MatchesItem; 26 | 27 | // const MatchesItem = (props) => { 28 | // //the way each user profile will look in the feed 29 | // if (!props.user) { 30 | // return

No matches yet. Check back later!

; 31 | // } 32 | // const { username, age, location, comment, proglang, url } = props.user; 33 | // return ( 34 | //
35 | //
36 | //

{username}

37 | //
38 | // 45 | //
46 | // ); 47 | // }; 48 | 49 | // export default MatchesItem;import React from 'react'; 50 | -------------------------------------------------------------------------------- /client/App.js: -------------------------------------------------------------------------------- 1 | import { Link, Route, Routes } from 'react-router-dom'; 2 | import React, { useState, useEffect } from 'react'; 3 | import Login from './Login.js'; 4 | import SignUp from './SignUp'; 5 | import Profile from './Profile'; 6 | import Feed from './Feed'; 7 | import UpdateProfile from './components/UpdateProfile'; 8 | import Matches from './Matches'; 9 | 10 | //imported stylesheet 11 | import './stylesheets/style.css'; 12 | 13 | //rendering profile here just for now before we add routers 14 | const App = () => { 15 | const [currUser, setCurrUser] = useState(false); 16 | const [allUsers, setAllUsers] = useState([]); 17 | 18 | useEffect(() => { 19 | fetch('/api/friends') 20 | .then((response) => response.json()) 21 | .then((data) => { 22 | setAllUsers(data); 23 | }); 24 | }, []); 25 | 26 | return ( 27 | 28 | } 31 | /> 32 | } 35 | /> 36 | } /> 37 | } 40 | /> 41 | 42 | ); 43 | }; 44 | 45 | //
46 | //
47 | // {/* 48 | // */} 49 | // 50 | //
51 | // {/* */} 52 | //
53 | 54 | export default App; 55 | 56 | // removed /signup & /login since / is capturing both 57 | // } /> 58 | // } /> 59 | 60 | // Removed homepage cause we want to feed anyways 61 | // /* } /> */ 62 | 63 | // Moving /UpdateProfile functionality to just /Profile 64 | // } /> 65 | -------------------------------------------------------------------------------- /client/stylesheets/NavBar.css: -------------------------------------------------------------------------------- 1 | @import url('http://fonts.cdnfonts.com/css/dejavu-sans-mono'); 2 | 3 | .navBar { 4 | position: sticky; 5 | display: flex; 6 | justify-content: space-between; 7 | align-items: center; 8 | background-color: #07beb8; 9 | height: 10%; 10 | box-shadow: none; 11 | border-bottom: 2px solid black; 12 | } 13 | .mascot { 14 | font-family: 'DejaVu Sans Mono', sans-serif; 15 | display: flex; 16 | align-items: center; 17 | justify-content: center; 18 | } 19 | 20 | .mascot h1 { 21 | font-size: 32px; 22 | } 23 | .navBar button { 24 | font-family: 'DejaVu Sans Mono', sans-serif; 25 | } 26 | 27 | .navBarImage { 28 | height: 85px; 29 | width: auto; 30 | } 31 | 32 | .navBtn { 33 | margin: 0 10px; 34 | } 35 | 36 | /* CSS */ 37 | .navBtn { 38 | background-color: #3dd1e7; 39 | border: 0 solid #e5e7eb; 40 | box-sizing: border-box; 41 | color: #000000; 42 | display: flex; 43 | font-family: ui-sans-serif, system-ui, -apple-system, system-ui, 'Segoe UI', 44 | Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 45 | 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; 46 | font-size: 14px; 47 | font-weight: 700; 48 | justify-content: center; 49 | line-height: 1.75rem; 50 | padding: 0.75rem 1.65rem; 51 | position: relative; 52 | text-align: center; 53 | text-decoration: none #000000 solid; 54 | text-decoration-thickness: auto; 55 | width: 250px; 56 | height: auto; 57 | max-width: 460px; 58 | position: relative; 59 | cursor: pointer; 60 | transform: rotate(-2deg); 61 | user-select: none; 62 | -webkit-user-select: none; 63 | touch-action: manipulation; 64 | } 65 | 66 | .navBtn:focus { 67 | outline: 0; 68 | } 69 | 70 | .navBtn:after { 71 | content: ''; 72 | position: absolute; 73 | border: 1px solid #000000; 74 | bottom: 4px; 75 | left: 4px; 76 | width: calc(100% - 1px); 77 | height: calc(100% - 1px); 78 | } 79 | 80 | .navBtn:hover:after { 81 | bottom: 2px; 82 | left: 2px; 83 | } 84 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | -------------------------------------------------------------------------------- /client/Login.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { Link, Navigate } from 'react-router-dom'; 3 | import './stylesheets/Login.css'; 4 | import SignUp from './SignUp.js'; 5 | import Mole from './assets/Star-nosed-mole.png'; 6 | 7 | const Login = (props) => { 8 | //is this state used? 9 | const [toggleSignUp, setToggleSignUp] = useState(false); 10 | 11 | const loginHandler = () => { 12 | const id = document.getElementById('loginUsername').value; 13 | const pw = document.getElementById('password').value; 14 | console.log('id ' + id); 15 | console.log('pw ' + pw); 16 | 17 | fetch('/api/verification', { 18 | method: 'POST', 19 | headers: { 20 | 'Content-Type': 'application/json', 21 | }, 22 | body: JSON.stringify({ username: id, password: pw }), 23 | }) 24 | .then((data) => { 25 | return data.json(); 26 | }) 27 | .then((data) => { 28 | if (data) { 29 | props.setCurrUser(id); 30 | } 31 | }); 32 | }; 33 | if (toggleSignUp) { 34 | return ; 35 | } 36 | return ( 37 |
38 |
39 |
40 | starmole 41 |

CodersOnly

42 |
43 | 50 | 57 |
58 | 61 | {props.currUser && } 62 | 68 |
69 |
70 |
71 | ); 72 | }; 73 | 74 | export default Login; 75 | 76 | { 77 | /* created route to feed...will need to make a conditional route so it will only route when verified user logs in*/ 78 | } 79 | /* 80 | 81 | {currUser !== '' && : } 82 | 83 | */ 84 | -------------------------------------------------------------------------------- /client/SignUp.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './stylesheets/SignUp.css'; 3 | import { Link } from 'react'; 4 | 5 | //fetch request ---->>>> 6 | const SignUp = (props) => { 7 | const createUserHandler = (e) => { 8 | e.preventDefault(); 9 | const userObj = {}; 10 | const inputs = document 11 | .querySelectorAll('.SignUpForm input') 12 | .forEach((el) => { 13 | userObj[el.name] = el.value; 14 | }); 15 | 16 | const langType = document.querySelector('.proglangDropDown').value; 17 | userObj.proglang = langType; 18 | userObj.matches = {}; 19 | userObj.matches[userObj.username] = 'no'; 20 | 21 | fetch('/api', { 22 | method: 'POST', 23 | headers: { 24 | 'Content-Type': 'application/json', 25 | }, 26 | body: JSON.stringify(userObj), 27 | }) 28 | .then((data) => { 29 | return data.json(); 30 | }) 31 | .then((data) => { 32 | console.log(data); 33 | props.setToggleSignUp(false); 34 | }); 35 | }; 36 | 37 | return ( 38 |
39 |
40 | 43 |
44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 72 | 73 | 74 | 75 |
76 | 77 |
78 |
79 | ); 80 | }; 81 | 82 | export default SignUp; 83 | 84 | // Old button router 85 | // {/* linking submit button back to login page */} 86 | // {/* this breaks for some reason when we uncomment the link component :( */} 87 | // {/* */} 88 | // 94 | // {/* */} 95 | -------------------------------------------------------------------------------- /client/stylesheets/MatchPopUp.css: -------------------------------------------------------------------------------- 1 | .MatchPopUp { 2 | position: absolute; 3 | transform: rotate(380deg); 4 | top: 150; 5 | left: 210; 6 | width: 300px; 7 | text-align: center; 8 | font-size: 32px; 9 | color: white; 10 | border-radius: 10px; 11 | box-shadow: rgba(0, 0, 0, 0.3) 0px 19px 38px, 12 | rgba(0, 0, 0, 0.22) 0px 15px 12px; 13 | background-color: rgb(7, 190, 184); 14 | font-family: 'DejaVu Sans Mono', sans-serif; 15 | } 16 | 17 | /* Animations for Buttons */ 18 | .matchPopUp, 19 | .matchPopUp:after { 20 | width: 150px; 21 | height: 76px; 22 | line-height: 78px; 23 | font-size: 32px; 24 | font-family: 'DejaVu Sans Mono', sans-serif; 25 | background: linear-gradient(45deg, transparent 5%, #202020 5%); 26 | border: 0; 27 | color: #fff; 28 | letter-spacing: 3px; 29 | box-shadow: 6px 0px 0px #c4fff9; 30 | outline: transparent; 31 | position: relative; 32 | user-select: none; 33 | -webkit-user-select: none; 34 | touch-action: manipulation; 35 | } 36 | 37 | /* button animation */ 38 | .matchPopUp:after { 39 | --slice-0: inset(50% 50% 50% 50%); 40 | --slice-1: inset(80% -6px 0 0); 41 | --slice-2: inset(50% -6px 30% 0); 42 | --slice-3: inset(10% -6px 85% 0); 43 | --slice-4: inset(40% -6px 43% 0); 44 | --slice-5: inset(80% -6px 5% 0); 45 | 46 | content: 'Star-nosed Moles'; 47 | display: block; 48 | position: absolute; 49 | top: 0; 50 | left: 0; 51 | right: 0; 52 | bottom: 0; 53 | background: linear-gradient( 54 | 45deg, 55 | transparent 3%, 56 | #00e6f6 3%, 57 | #00e6f6 5%, 58 | #ff013c 5% 59 | ); 60 | text-shadow: -3px -3px 0px #f8f005, 3px 3px 0px #00e6f6; 61 | clip-path: var(--slice-0); 62 | } 63 | 64 | .matchPopUp:hover:after { 65 | animation: 1s glitch; 66 | animation-timing-function: steps(2, end); 67 | } 68 | 69 | @keyframes glitch { 70 | 0% { 71 | clip-path: var(--slice-1); 72 | transform: translate(-20px, -10px); 73 | } 74 | 10% { 75 | clip-path: var(--slice-3); 76 | transform: translate(10px, 10px); 77 | } 78 | 20% { 79 | clip-path: var(--slice-1); 80 | transform: translate(-10px, 10px); 81 | } 82 | 30% { 83 | clip-path: var(--slice-3); 84 | transform: translate(0px, 5px); 85 | } 86 | 40% { 87 | clip-path: var(--slice-2); 88 | transform: translate(-5px, 0px); 89 | } 90 | 50% { 91 | clip-path: var(--slice-3); 92 | transform: translate(5px, 0px); 93 | } 94 | 60% { 95 | clip-path: var(--slice-4); 96 | transform: translate(5px, 10px); 97 | } 98 | 70% { 99 | clip-path: var(--slice-2); 100 | transform: translate(-10px, 10px); 101 | } 102 | 80% { 103 | clip-path: var(--slice-5); 104 | transform: translate(20px, -10px); 105 | } 106 | 90% { 107 | clip-path: var(--slice-1); 108 | transform: translate(-10px, 0px); 109 | } 110 | 100% { 111 | clip-path: var(--slice-1); 112 | transform: translate(0); 113 | } 114 | } 115 | 116 | @media (min-width: 768px) { 117 | .matchPopUp, 118 | .matchPopUp:after { 119 | width: 300px; 120 | height: 150px; 121 | line-height: 20px; 122 | } 123 | } 124 | 125 | /* 126 | height: 86px; 127 | line-height: 88px; 128 | */ 129 | -------------------------------------------------------------------------------- /client/stylesheets/SignUp.css: -------------------------------------------------------------------------------- 1 | .SignUpDiv { 2 | height: 100%; 3 | width: 100%; 4 | margin: 0, 0, 0, 0; 5 | display: flex; 6 | justify-content: center; 7 | background-image: url('https://images.pond5.com/computer-coding-background-footage-090890180_prevstill.jpeg'); 8 | background-size: cover; 9 | padding: 0px; 10 | margin: 0px; 11 | } 12 | 13 | .SignUp { 14 | display: flex; 15 | flex-direction: column; 16 | justify-content: center; 17 | align-items: center; 18 | gap: 10px; 19 | } 20 | 21 | .SignUpForm { 22 | display: flex; 23 | flex-direction: column; 24 | font-family: 'DejaVu Sans Mono', sans-serif; 25 | color: rgb(228, 220, 220); 26 | } 27 | 28 | .SignUp button { 29 | font-family: 'DejaVu Sans Mono', sans-serif; 30 | border-radius: 5px; 31 | } 32 | 33 | .SignUp input { 34 | border: none; 35 | background: transparent; 36 | font-family: 'DejaVu Sans Mono', sans-serif; 37 | color: white; 38 | } 39 | 40 | .proglangDropDown { 41 | border: none; 42 | opacity: 0.75; 43 | font-family: 'DejaVu Sans Mono', sans-serif; 44 | } 45 | 46 | /* CSS */ 47 | .SignUp button, 48 | .SignUp button:after { 49 | width: 150px; 50 | height: 76px; 51 | line-height: 78px; 52 | font-size: 14px; 53 | font-family: 'DejaVu Sans Mono', sans-serif; 54 | background: linear-gradient(45deg, transparent 5%, #07beb8 5%); 55 | border: 0; 56 | color: #fff; 57 | letter-spacing: 3px; 58 | box-shadow: 6px 0px 0px #c4fff9; 59 | outline: transparent; 60 | position: relative; 61 | user-select: none; 62 | -webkit-user-select: none; 63 | touch-action: manipulation; 64 | } 65 | 66 | .SignUp button:after { 67 | --slice-0: inset(50% 50% 50% 50%); 68 | --slice-1: inset(80% -6px 0 0); 69 | --slice-2: inset(50% -6px 30% 0); 70 | --slice-3: inset(10% -6px 85% 0); 71 | --slice-4: inset(40% -6px 43% 0); 72 | --slice-5: inset(80% -6px 5% 0); 73 | 74 | content: 'Star-nosed Moles'; 75 | display: block; 76 | position: absolute; 77 | top: 0; 78 | left: 0; 79 | right: 0; 80 | bottom: 0; 81 | background: linear-gradient( 82 | 45deg, 83 | transparent 3%, 84 | #00e6f6 3%, 85 | #00e6f6 5%, 86 | #ff013c 5% 87 | ); 88 | text-shadow: -3px -3px 0px #f8f005, 3px 3px 0px #00e6f6; 89 | clip-path: var(--slice-0); 90 | } 91 | 92 | .SignUp button:hover:after { 93 | animation: 1s glitch; 94 | animation-timing-function: steps(2, end); 95 | } 96 | 97 | @keyframes glitch { 98 | 0% { 99 | clip-path: var(--slice-1); 100 | transform: translate(-20px, -10px); 101 | } 102 | 10% { 103 | clip-path: var(--slice-3); 104 | transform: translate(10px, 10px); 105 | } 106 | 20% { 107 | clip-path: var(--slice-1); 108 | transform: translate(-10px, 10px); 109 | } 110 | 30% { 111 | clip-path: var(--slice-3); 112 | transform: translate(0px, 5px); 113 | } 114 | 40% { 115 | clip-path: var(--slice-2); 116 | transform: translate(-5px, 0px); 117 | } 118 | 50% { 119 | clip-path: var(--slice-3); 120 | transform: translate(5px, 0px); 121 | } 122 | 60% { 123 | clip-path: var(--slice-4); 124 | transform: translate(5px, 10px); 125 | } 126 | 70% { 127 | clip-path: var(--slice-2); 128 | transform: translate(-10px, 10px); 129 | } 130 | 80% { 131 | clip-path: var(--slice-5); 132 | transform: translate(20px, -10px); 133 | } 134 | 90% { 135 | clip-path: var(--slice-1); 136 | transform: translate(-10px, 0px); 137 | } 138 | 100% { 139 | clip-path: var(--slice-1); 140 | transform: translate(0); 141 | } 142 | } 143 | 144 | @media (min-width: 768px) { 145 | .SignUp button, 146 | .SignUp button:after { 147 | width: 165px; 148 | height: 45px; 149 | line-height: 20px; 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /client/Feed.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { useState, useEffect } from 'react'; 3 | import { Link } from 'react-router-dom'; 4 | import Navbar from './components/NavBar'; 5 | import FeedItem from './components/FeedItem'; 6 | import MatchPopUp from './components/MatchPopUp'; 7 | import './stylesheets/Feed.css'; 8 | 9 | const Feed = (props) => { 10 | const [currIndex, setCurrIndex] = useState(0); 11 | const [currUserFeed, setCurrUserFeed] = useState([]); 12 | const [toggleMatchPopUp, setToggleMatchPopUp] = useState(false); 13 | 14 | const yesHandler = () => { 15 | const clickedUser = document.querySelector('#userName').textContent; 16 | 17 | fetch(`/api/${props.currUser}/${clickedUser}/yes`, { 18 | method: 'PATCH', 19 | }) 20 | .then((data) => { 21 | return data.json(); 22 | }) 23 | .then((data) => { 24 | setToggleMatchPopUp(data); 25 | if (!data) { 26 | setCurrIndex((prevState) => prevState + 1); 27 | } 28 | }); 29 | }; 30 | 31 | const noHandler = (e) => { 32 | const clickedUser = document.querySelector('#userName').textContent; 33 | fetch(`/api/${props.currUser}/${clickedUser}/no`, { 34 | method: 'PATCH', 35 | }) 36 | .then((data) => { 37 | return data.json(); 38 | }) 39 | .then((data) => { 40 | setCurrIndex((prevState) => prevState + 1); 41 | // console.log(data); 42 | }); 43 | }; 44 | 45 | useEffect(() => { 46 | fetch(`/api/${props.currUser}`) 47 | .then((data) => { 48 | return data.json(); 49 | }) 50 | .then((data) => { 51 | const { matches } = data; 52 | const nonRejectedUsers = props.allUsers.filter((el) => { 53 | if (!matches[el.username]) return true; 54 | }); 55 | setCurrUserFeed(nonRejectedUsers); 56 | console.log(nonRejectedUsers); 57 | }); 58 | }, []); 59 | 60 | return ( 61 |
62 | 63 |
64 | {toggleMatchPopUp && ( 65 | 69 | )} 70 | 71 |
72 | 73 | 74 |
75 |
76 |
77 | ); 78 | }; 79 | 80 | export default Feed; 81 | 82 | // return ( 83 | //
84 | // 94 | //

Foodie Friends

95 | //
96 | // {/* sad attempt to render FeedItem */} 97 | // {/* 98 | // 99 | // */} 100 | // {/* friends.map((friend) => ( 101 | //
102 | // 103 | //
104 | // )); */} 105 | //
106 | //
107 | // ); 108 | 109 | //Comments 110 | //Fetch user profiles from the database to populate our feed 111 | //make sure to not include our own profile 112 | 113 | //L&P attempt: tried to fetch state here and then loop through it to pass our state to our FeedItem component 114 | // const [ friends, setFriends ] = useState(); 115 | 116 | // useEffect(() => { 117 | // fetch('/api/friends') 118 | // .then(response => response.json()) 119 | // .then(({data: friends}) => { 120 | // console.log('i am data', {data: friends}) 121 | // setFriends(friends) 122 | // }) 123 | // }, []); 124 | // fetch('/api/friends', { 125 | // method: 'GET', 126 | // headers: { 127 | // 'Content-Type': 'application/json', 128 | // }, 129 | // }).then((data) => { 130 | // console.log(data); 131 | // }); 132 | 133 | // const createFeed = (results) => { 134 | // console.log('this is friends', results) 135 | // // setFriends(results); 136 | // const item = []; 137 | // for (let i = 0; i < results.length; i++) { 138 | // item.push() 139 | // } 140 | // return item; 141 | -------------------------------------------------------------------------------- /client/stylesheets/Login.css: -------------------------------------------------------------------------------- 1 | @import url('http://fonts.cdnfonts.com/css/dejavu-sans-mono'); 2 | 3 | body { 4 | margin: 0; 5 | background-color: #07beb8; 6 | } 7 | 8 | .LoginTitle { 9 | display: flex; 10 | align-items: center; 11 | justify-content: center; 12 | margin-right: 55px; 13 | } 14 | 15 | .LoginBox { 16 | display: flex; 17 | flex-direction: column; 18 | justify-content: center; 19 | align-items: center; 20 | gap: 10px; 21 | } 22 | 23 | .LoginInDiv { 24 | height: 100%; 25 | width: 100%; 26 | margin: 0, 0, 0, 0; 27 | display: flex; 28 | justify-content: center; 29 | background-image: url('https://images.pond5.com/computer-coding-background-footage-090890180_prevstill.jpeg'); 30 | background-size: cover; 31 | padding: 0px; 32 | margin: 0px; 33 | } 34 | 35 | .title { 36 | color: rgb(228, 220, 220); 37 | /* color: white; */ 38 | font-size: 56px; 39 | font-family: 'DejaVu Sans Mono', sans-serif; 40 | } 41 | 42 | .id { 43 | font-family: 'DejaVu Sans Mono', sans-serif; 44 | background: transparent; 45 | border: none; 46 | color: white; 47 | } 48 | 49 | .password { 50 | font-family: 'DejaVu Sans Mono', sans-serif; 51 | background: transparent; 52 | border: none; 53 | color: white; 54 | } 55 | 56 | .LoginScreenButtons { 57 | display: flex; 58 | gap: 20px; 59 | } 60 | 61 | .loginButtons { 62 | display: flex; 63 | font-family: 'DejaVu Sans Mono', sans-serif; 64 | display: inline; 65 | margin: 0 auto; 66 | border-radius: 5px; 67 | } 68 | 69 | .loginImage { 70 | width: auto; 71 | height: 85px; 72 | } 73 | /* Animations for Buttons */ 74 | .loginButtons, 75 | .loginButtons:after { 76 | width: 150px; 77 | height: 76px; 78 | line-height: 78px; 79 | font-size: 14px; 80 | font-family: 'DejaVu Sans Mono', sans-serif; 81 | background: linear-gradient(45deg, transparent 5%, #07beb8 5%); 82 | border: 0; 83 | color: #fff; 84 | letter-spacing: 3px; 85 | box-shadow: 5px 0px 0px #c4fff9; 86 | outline: transparent; 87 | position: relative; 88 | user-select: none; 89 | -webkit-user-select: none; 90 | touch-action: manipulation; 91 | } 92 | 93 | .loginButtons:after { 94 | --slice-0: inset(50% 50% 50% 50%); 95 | --slice-1: inset(80% -6px 0 0); 96 | --slice-2: inset(50% -6px 30% 0); 97 | --slice-3: inset(10% -6px 85% 0); 98 | --slice-4: inset(40% -6px 43% 0); 99 | --slice-5: inset(80% -6px 5% 0); 100 | 101 | content: 'Star-nosed Moles'; 102 | display: block; 103 | position: absolute; 104 | top: 0; 105 | left: 0; 106 | right: 0; 107 | bottom: 0; 108 | background: linear-gradient( 109 | 45deg, 110 | transparent 3%, 111 | #00e6f6 3%, 112 | #00e6f6 5%, 113 | #ff013c 5% 114 | ); 115 | text-shadow: -3px -3px 0px #f8f005, 3px 3px 0px #00e6f6; 116 | clip-path: var(--slice-0); 117 | } 118 | 119 | .loginButtons:hover:after { 120 | animation: 1s glitch; 121 | animation-timing-function: steps(2, end); 122 | } 123 | 124 | @keyframes glitch { 125 | 0% { 126 | clip-path: var(--slice-1); 127 | transform: translate(-20px, -10px); 128 | } 129 | 10% { 130 | clip-path: var(--slice-3); 131 | transform: translate(10px, 10px); 132 | } 133 | 20% { 134 | clip-path: var(--slice-1); 135 | transform: translate(-10px, 10px); 136 | } 137 | 30% { 138 | clip-path: var(--slice-3); 139 | transform: translate(0px, 5px); 140 | } 141 | 40% { 142 | clip-path: var(--slice-2); 143 | transform: translate(-5px, 0px); 144 | } 145 | 50% { 146 | clip-path: var(--slice-3); 147 | transform: translate(5px, 0px); 148 | } 149 | 60% { 150 | clip-path: var(--slice-4); 151 | transform: translate(5px, 10px); 152 | } 153 | 70% { 154 | clip-path: var(--slice-2); 155 | transform: translate(-10px, 10px); 156 | } 157 | 80% { 158 | clip-path: var(--slice-5); 159 | transform: translate(20px, -10px); 160 | } 161 | 90% { 162 | clip-path: var(--slice-1); 163 | transform: translate(-10px, 0px); 164 | } 165 | 100% { 166 | clip-path: var(--slice-1); 167 | transform: translate(0); 168 | } 169 | } 170 | 171 | @media (min-width: 768px) { 172 | .loginButtons, 173 | .loginButtons:after { 174 | width: 100px; 175 | height: 45px; 176 | line-height: 20px; 177 | } 178 | } 179 | 180 | /* 181 | height: 86px; 182 | line-height: 88px; 183 | */ 184 | -------------------------------------------------------------------------------- /server/controller.js: -------------------------------------------------------------------------------- 1 | const User = require('./userModel'); 2 | 3 | const controller = {}; 4 | 5 | controller.createUser = async (req, res, next) => { 6 | try { 7 | const { 8 | username, 9 | password, 10 | age, 11 | location, 12 | proglang, 13 | comment, 14 | matches, 15 | url, 16 | } = req.body; 17 | if (typeof username !== 'string') 18 | throw new Error('username should be a string'); 19 | res.locals.user = await User.create({ 20 | username, 21 | password, 22 | age, 23 | location, 24 | proglang, 25 | comment, 26 | matches, 27 | url, 28 | }); 29 | return next(); 30 | } catch (err) { 31 | return next({ 32 | log: `controller.js: ERROR: ${err}`, 33 | status: 400, 34 | message: { 35 | err: 'An error occurred in controller.createUser. Check server logs for more details', 36 | }, 37 | }); 38 | } 39 | }; 40 | 41 | // change functionality to be for all instances of matches with value of not 'no' (or 'yes' and null) 42 | controller.getUser = async (req, res, next) => { 43 | try { 44 | console.log('ID ', req.params); 45 | const { username } = req.params; 46 | res.locals.user = await User.findOne({ username }).exec(); 47 | return next(); 48 | } catch (err) { 49 | return next({ 50 | log: `controller.js: ERROR: ${err}`, 51 | status: 400, 52 | message: { 53 | err: 'An error occurred in controller.getUser. Check server logs for more details', 54 | }, 55 | }); 56 | } 57 | }; 58 | 59 | // controller.updateUser = async (req, res, next) => { 60 | // try { 61 | // const { username } = req.params; 62 | // res.locals.user = await User.updateOne({username}, TODO: ADD UPDATE).exec(); 63 | // return next(); 64 | // } 65 | // catch (err) { 66 | // return next({ 67 | // log: `controller.js: ERROR: ${err}`, 68 | // status: 400, 69 | // message: { 70 | // err: 'An error occurred in controller.updateUser. Check server logs for more details', 71 | // }, 72 | // }); 73 | // } 74 | // }; 75 | 76 | controller.verifyUser = async (req, res, next) => { 77 | try { 78 | const { username, password } = req.body; 79 | const found = await User.findOne({ 80 | username: username, 81 | password: password, 82 | }); 83 | found ? (res.locals.userExists = true) : (res.locals.userExists = false); 84 | return next(); 85 | } catch (err) { 86 | return next({ 87 | log: `controller.js: ERROR: ${err}`, 88 | status: 400, 89 | message: { 90 | err: 'An error occurred in controller.verifyUser. Check server logs for more details', 91 | }, 92 | }); 93 | } 94 | }; 95 | 96 | //this controller is for fetching all the profiles from our db 97 | controller.getFriends = async (req, res, next) => { 98 | try { 99 | const data = await User.find(); 100 | res.locals.friends = data; 101 | return next(); 102 | } catch (err) { 103 | return next({ 104 | log: `controller.js: ERROR: ${err}`, 105 | status: 400, 106 | message: { 107 | err: 'An error occurred in controller.getFriends. Check server logs for more details', 108 | }, 109 | }); 110 | } 111 | }; 112 | 113 | // controller to update user's matches 114 | controller.updateUserMatches = async (req, res, next) => { 115 | try { 116 | const { username, clickedUser, decision } = req.params; 117 | const currUser = await User.findOne({ username }); 118 | currUser.matches[clickedUser] = decision; 119 | await User.updateOne({ username }, { matches: currUser.matches }).exec(); 120 | 121 | // check if decision is yes and if clickedUser's matches also includes currUser: yes 122 | const { matches } = await User.findOne({ username: clickedUser }); 123 | console.log(matches[username] === 'yes'); 124 | console.log(matches[username]); 125 | if (matches[username] === 'yes' && decision === 'yes') { 126 | res.locals.match = true; 127 | } else { 128 | res.locals.match = false; 129 | } 130 | 131 | return next(); 132 | } catch (err) { 133 | return next({ 134 | log: `controller.js: ERROR: ${err}`, 135 | status: 400, 136 | message: { 137 | err: 'An error occurred in controller.updateUserMatches. Check server logs for more details', 138 | }, 139 | }); 140 | } 141 | }; 142 | 143 | module.exports = controller; 144 | --------------------------------------------------------------------------------