├── .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 |

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 |
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 |
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 |

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 |

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 | //
39 | //
40 | // - Age: {age}
41 | // - Location: {location}
42 | // - Bio: {comment}
43 | // - Programming Language: {proglang}
44 | //
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 |

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 |
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 |
--------------------------------------------------------------------------------