diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index dfe0770424b2a19faf507a501ebfc23be8f54e7b..0000000000000000000000000000000000000000 --- a/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -# Auto detect text files and perform LF normalization -* text=auto diff --git a/backend/models/UploadModel.js b/backend/models/UploadModel.js deleted file mode 100644 index 60a146482a8de56a217820a69fa53911045d613a..0000000000000000000000000000000000000000 --- a/backend/models/UploadModel.js +++ /dev/null @@ -1,44 +0,0 @@ -const mongoose = require('mongoose') -const userModel = require('./user') - -const postSchema = new mongoose.Schema({ - name: { - type: String, - required: true - }, - recipe: { - type: [String], - required: false - }, - description: { - type: String, - required: true - }, - author:{ - type: mongoose.Schema.Types.ObjectId, - ref:"user" - }, - profile_picture: { - type: String, - required: true - }, - profile_name: { - type: String, - required: true - }, - upvotes: { - type: [String], - required: false - }, - photo: { - type: String, - required: true - } - - -}) - -const postModel = mongoose.model("Post", postSchema) - -module.exports = postModel - diff --git a/backend/public/uploads/f941bdfb-caef-47cd-bb2c-52b7fb14e763_.jpg b/backend/public/uploads/f941bdfb-caef-47cd-bb2c-52b7fb14e763_.jpg deleted file mode 100644 index d62454433216ead19366d7a5e46c7d8cd8601be4..0000000000000000000000000000000000000000 Binary files a/backend/public/uploads/f941bdfb-caef-47cd-bb2c-52b7fb14e763_.jpg and /dev/null differ diff --git a/backend/routes/routes.js b/backend/routes/routes.js index 5508d1439405216d0d1ff659721d116d118e2f13..3d3facbf87cac76abf9ebb58dd39ac46a3bb454a 100644 --- a/backend/routes/routes.js +++ b/backend/routes/routes.js @@ -1,7 +1,7 @@ const express = require('express') const { Router } = require('express') const userModel = require('../models/user') -const postModel = require('../models/UploadModel') +const postModel = require('../models/post') const uploadMiddleware = require('../middlewares/MulterMiddleware') const multer = require('multer') const generateToken = require('../utils/generateToken') @@ -10,6 +10,7 @@ const router = Router() const auth = require('../middlewares/auth') const jwt = require('jsonwebtoken'); const fs = require('fs') +const commentModel = require('../models/comment') require('dotenv').config() @@ -98,8 +99,6 @@ router.post("/post", uploadMiddleware.single("photo"), (req, res) => { //Get posts router.get('/posts', async (req, res) => { - - const loads = req.headers.loads console.log(loads) @@ -210,6 +209,8 @@ router.put('/upvote', async (req, res) => { const post = await postModel.findById(req.body.post_id) + console.log(post) + if (!post) { return res.json("Not a valid post") } @@ -217,16 +218,17 @@ router.put('/upvote', async (req, res) => { if (post.upvotes.includes(req.body.upvote)) { - const carIndex = post.upvotes.indexOf(req.body.upvote) - post.upvotes.splice(req.body.upvote, 1) + const index = post.upvotes.indexOf(req.body.upvote) + post.upvotes.splice(index, 1) await post.save() return res.json("upvote deleted") + }else{ + post.upvotes.push(req.body.upvote) + await post.save() + res.send(post) } - post.upvotes.push(req.body.upvote) - await post.save() - - res.send(post) + }) @@ -241,6 +243,46 @@ router.get("/api/posts/search", (req, res) => { }); }); +router.post("/comment", (req, res) => { + + console.log(req.body) + + const comment = new commentModel( + { + profile_name: req.body.profile_name, + profile_picture: req.body.profile_picture, + comment: req.body.comment, + }) + comment.save() + .then(console.log("comment saved successfully")) + res.send(comment) + +}) + +router.put('/savecomment', async (req, res) => { + + console.log(req.body) + + const post = await postModel.findById(req.body.post_id) + + console.log(post) + + if (!post) { + return res.json("Not a valid post") + }else{ + + const comment = req.body.comment_id + + console.log(comment) + + //post.comments.push(comment) + + //await post.save() + } + + + +}) module.exports = router \ No newline at end of file diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 08c7cc2894108723718dde40e011516343ac8044..4770f06cd01684ee5e3bc9eacc2ef8131d13fe03 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -14,6 +14,7 @@ "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", + "animejs": "^3.2.1", "axios": "^1.3.4", "jwt-decode": "^3.1.2", "react": "^18.2.0", @@ -5231,6 +5232,11 @@ "ajv": "^6.9.1" } }, + "node_modules/animejs": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/animejs/-/animejs-3.2.1.tgz", + "integrity": "sha512-sWno3ugFryK5nhiDm/2BKeFCpZv7vzerWUcUPyAZLDhMek3+S/p418ldZJbJXo5ZUOpfm2kP2XRO4NJcULMy9A==" + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -21460,6 +21466,11 @@ "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "requires": {} }, + "animejs": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/animejs/-/animejs-3.2.1.tgz", + "integrity": "sha512-sWno3ugFryK5nhiDm/2BKeFCpZv7vzerWUcUPyAZLDhMek3+S/p418ldZJbJXo5ZUOpfm2kP2XRO4NJcULMy9A==" + }, "ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", diff --git a/frontend/package.json b/frontend/package.json index c2afb67786d82232cfc74eb4dc0fd85161cdece7..121579bda0842fe9413e6e76598718436206a785 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -9,6 +9,7 @@ "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", + "animejs": "^3.2.1", "axios": "^1.3.4", "jwt-decode": "^3.1.2", "react": "^18.2.0", diff --git a/frontend/src/App.js b/frontend/src/App.js index 73e94d05e3e48412dd87fb83ef8aa58a5b6b0caf..c8737f56de9e6253c386ebfbe89d57c5fcc8ad65 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -1,14 +1,36 @@ import Landing from './components/Landing' import Header from './components/Header' +import styles from './styles/styles.module.css' +import { fadeInVertical, fadeInHorizontal, fadeInAndScale } from './functions/animations'; +import React, {useRef, useEffect } from 'react' function App() { + const fadein = useRef(null); + + useEffect(() => { + const element = fadein.current; + if (element) { + fadeInVertical(element); + } + }, []); return ( - <> - <Header/> - <Landing/> - </> + <> + + <div className={styles.background}> + <div className={styles.content}> + <div className={styles.header}> + <Header /> + </div> + <div className={styles.lander}> + <h1 ref={fadein} className={styles.logo}>LIQOURBUDDY</h1> + </div> + + + </div> + </div> + </> ); } diff --git a/frontend/src/components/Landing.js b/frontend/src/components/Landing.js index b22f64994bb84cac685dcd9fa8c19125d75e7539..b07e0b0663c8149dc728947603d0c0cf46a15455 100644 --- a/frontend/src/components/Landing.js +++ b/frontend/src/components/Landing.js @@ -1,55 +1,37 @@ -import React from 'react' +import React, {useRef, useEffect } from 'react' import styles from '../styles/styles.module.css' +import { fadeInVertical, fadeInHorizontal, fadeInAndScale } from '../functions/animations'; + + const Landing = () => { - return ( - <> - <div className={styles.Header}> - <div className={styles.text_container}> - <h1>Welcome to Liqour Buddy!</h1> - <p>A project by Ludvig Damberg and Ludvig Hillert for Linköping University. </p> - <p>Scroll down to see a checklist for our project and test the current features! Keep in mind that this is a project - under developement, some features might not work or have any response. ðŸ¹ðŸ» - </p> - </div> - <div className={styles.image_container}> - <img alt='' src='../../content/landing.jpg'/> - </div> - </div> - <div className={styles.Header2}> - <div className={styles.card}> - <h1>Functionality ðŸº</h1> - <ul className={styles.list}> - <li className={styles.item}>Creating Posts </li> - <li className={styles.item}>Account Sign Up </li> - <li className={styles.item}>Logging In </li> - <li className={styles.item}>Authentication Checking </li> - <li className={styles.item}>Post filtering and priority</li> - </ul> - </div> - <div className={styles.card}> - <h1>PagesðŸº</h1> - <ul className={styles.list}> - <li className={styles.item}>Home </li> - <li className={styles.item}>Profile </li> - <li className={styles.item}>Discover </li> - <li className={styles.item}>Log In and Sign Up </li> - <li className={styles.item}>Crate Post </li> - </ul> - </div> - <div className={styles.card}> - <h1>User ExperienceðŸº</h1> - <ul className={styles.list}> - <li className={styles.item}>Scrolling Triggers </li> - <li className={styles.item}>Hover Interactions </li> - <li className={styles.item}>Instructional Interface </li> - <li className={styles.item}>Easy Usage </li> - <li className={styles.item}>Consistent Theme </li> - - </ul> - </div> - </div> - </> - ) + + const fadein = useRef(null); + + useEffect(() => { + const element = fadein.current; + if (element) { + fadeInVertical(element); + } + }, []); + + + return ( + <> + <div className={styles.Header}> + <div className={styles.text_container}> + <h1>Welcome to Liqour Buddy!</h1> + <p>A project by Ludvig Damberg and Ludvig Hillert for Linköping University. </p> + <p>Scroll down to see a checklist for our project and test the current features! Keep in mind that this is a project + under developement, some features might not work or have any response. ðŸ¹ðŸ» + </p> + </div> + <div className={styles.image_container}> + <img alt='' src='../../content/landing.jpg' /> + </div> + </div> + + </> + ) } export default Landing \ No newline at end of file diff --git a/frontend/src/components/Post.js b/frontend/src/components/Post.js index 4c909f25d0c49dbb0304c8048e7cf02c72376be2..bd82469a5ca31a518282903696edf8f7b590e4d9 100644 --- a/frontend/src/components/Post.js +++ b/frontend/src/components/Post.js @@ -5,7 +5,6 @@ import { AiOutlineCamera } from 'react-icons/ai' import styles from '../styles/feed.module.css' import { useNavigate } from 'react-router-dom' import jwt_decode from 'jwt-decode'; -import { isLoggedIn } from '../functions/Functions' import buttons from '../styles/buttons.module.css' const Post = () => { @@ -19,6 +18,7 @@ const Post = () => { const [isLoggedIn, setIsLoggedIn] = useState(false); const navigate = useNavigate(); const [profileData, setProfileData] = useState() + const [loading,setLoading] = useState(true) const checkLoggedIn = async () => { @@ -43,7 +43,6 @@ const Post = () => { const get_profile = () => { - const token = localStorage.getItem('token'); axios.get('http://localhost:5000/profile', { @@ -53,9 +52,9 @@ const Post = () => { }) .then(res => { setProfileData(res.data) + }) - - + setLoading(false) } useEffect(() => { @@ -96,6 +95,7 @@ const Post = () => { console.log(profileName) + formData.append('name', name) formData.append('recipe', recipe) formData.append('description', description) @@ -115,39 +115,87 @@ const Post = () => { } + + if(loading === true){ + + console.log("Loading...") + }else if(loading === false){ + console.log(profileData) +return ( + <div> + <div className={styles.post_container}> + <div className={styles.post_header}> + <h1>Make your drink!</h1> + </div> + + <div className={styles.grid_container}> + <div className={styles.input_fields}> + <input className={styles.post_input1} onChange={(e) => setName(e.target.value)} placeholder='Title of your drink' type='text' /> - return ( - <div className={styles.post_container}> - <div className={styles.post_header}> - <h1>Make your drink!</h1> - </div> + <input className={styles.post_input1} onChange={(e) => setIngredient(e.target.value)} placeholder='Ingredient' type='text' /> + <button className={buttons.button2} onClick={add_ingredient}>add ingredient</button> + <div className={styles.tag_container}> + <ul>{recipe.map((item, index) => ( + <li key={index} >{item}</li> + ))}</ul> + </div> + <textarea className={styles.post_input2} value={description} onChange={(e) => setDescription(e.target.value)} placeholder='How to make it...' type='text' cols='40' rows="5" /> + + + <label className={buttons.button2} id="button">add image + <input hidden type="file" id="button" onChange={(e) => handlePictureChange(e)} /> + + </label> - <div className={styles.input_fields}> - <input className={styles.post_input1} onChange={(e) => setName(e.target.value)} placeholder='Title of your drink' type='text' /> + </div> - <input className={styles.post_input1} onChange={(e) => setIngredient(e.target.value)} placeholder='Ingredient' type='text' /> - <button className={buttons.button2} onClick={add_ingredient}>add ingredient</button> - <div className={styles.tag_container}> - <ul>{recipe.map((item, index) => ( - <li key={index} >{item}</li> - ))}</ul> + <div> + <div className={styles.posts_header}> + + + </div> + <div className={styles.posts_container} > + + <div className={styles.grid_container}> + <div className={styles.post_img_container}> + <img className={styles.img} src={picturePreview} /> + </div> + <div> + <h2>{name}</h2> + <div > + <h3>Recipe:</h3> + <div className={styles.tag_container}> + <ul> + {recipe.map((ingredient, index) => ( + <li key={index}> + {ingredient} + </li> + + ))} + </ul> + + </div> + </div> + </div> + <div> + <div className={styles.description}><h3>Description:</h3>{description} </div> + </div> + </div> + + + </div> + </div> </div> - <textarea className={styles.post_input2} value={description} onChange={(e) => setDescription(e.target.value)} placeholder='How to make it...' type='text' cols='40' rows="5" /> - - - <label className={buttons.button2} id="button">add image - <input hidden type="file" id="button" onChange={(e) => handlePictureChange(e)}/> - </label> - - - </div> - <button className={buttons.button2} onClick={createPost}>Upload</button> + <button className={buttons.button2} onClick={createPost}>Upload</button> + </div> + </div > - </div> ) + } + } diff --git a/frontend/src/components/Posts.js b/frontend/src/components/Posts.js index 8aa66c84bd9054ef40b0eeb0fd33f1bd3428d9dd..033f2f5e7e3241cc1ad90468c3462e3800f08861 100644 --- a/frontend/src/components/Posts.js +++ b/frontend/src/components/Posts.js @@ -5,6 +5,8 @@ import axios from 'axios' import Loading from './Loading' import jwt_decode from 'jwt-decode'; import buttons from '../styles/buttons.module.css' + + const Posts = () => { const [posts, setPosts] = useState([]) @@ -13,8 +15,26 @@ const Posts = () => { const [loads, setLoads] = useState(1) const [search, setSearch] = useState("") const [searchChange, setSearchChange] = useState() + const [profileData, setProfileData] = useState() + const [comment, setComment] = useState("") + const [comment_id, setComment_id] = useState() + + const get_profile = () => { + + + const token = localStorage.getItem('token'); + axios.get('http://localhost:5000/profile', { + headers: { + Authorization: `Bearer ${token}` + } + }) + .then(res => { + setProfileData(res.data) + }) + setLoading(false) + } const loadPosts = () => { @@ -31,9 +51,11 @@ const Posts = () => { useEffect(() => { loadPosts() - + get_profile() }, []) + + const handleChange = (e) => { @@ -58,6 +80,37 @@ const Posts = () => { } + const handleComment = (id) => { + + console.log(profileData) + + console.log(id) + + axios.post("http://localhost:5000/comment", { profile_name: profileData.username, profile_picture: profileData.photo, comment: comment }) + .then((res) => { + console.log(res.data) + setComment_id(res.data._id) + }).catch(err => console.log(err)) + + + + save_comment(id) + } + + const save_comment = (id) => { + + + + + console.log(comment_id) + + axios.put("http://localhost:5000/savecomment", {post_id: id, comment_id: comment_id }) + .then((res) => { + console.log(res.data) + + }).catch(err => console.log(err)) + + } if (loading) { return ( @@ -77,43 +130,51 @@ const Posts = () => { onChange={(e) => handleChange(e)} /> <button className={buttons.button2} onClick={loadPosts}>Search</button> - <div>{posts.map((post) => { + <div>{posts.map((post, index) => { return ( - <> + <div key={post._id}> <div className={styles.posts_header}> - <img className={styles.img} src={`http://localhost:5000/uploads/${post.profile_picture}`} /> + <img className={styles.posts_header_img} src={`http://localhost:5000/uploads/${post.profile_picture}`} /> <p>{post.profile_name}</p> - + <button className={styles.upvote} onClick={() => handleUpvote(post._id)}>Upvotes: {post.upvotes.length}</button> - + </div> <div className={styles.posts_container} key={post._id}> - <div className={styles.post_img_container}> - <img className={styles.img} src={`http://localhost:5000/uploads/${post.photo}`} /> - </div> - <div> - <h2>{post.name}</h2> - <div > - <h3>Recipe:</h3> - <div className={styles.tag_container}> - <ul> - {post.recipe[0].split(',').map((ingredient, index) => ( - <li key={index}> - {ingredient} - </li> - - ))} - </ul> + + <div className={styles.grid_container}> + <div className={styles.post_img_container}> + <img className={styles.img} src={`http://localhost:5000/uploads/${post.photo}`} /> + </div> + <div> + <h2>{post.name}</h2> + <div > + <h3>Recipe:</h3> + <div className={styles.tag_container}> + <ul> + {post.recipe[0].split(',').map((ingredient, index) => ( + <li key={index}> + {ingredient} + </li> + + ))} + </ul> + + </div> </div> </div> - - <div className={styles.description}><p>Description: {post.description}</p> </div> - + <div> + <div className={styles.description}><h3>Description:</h3>{post.description} </div> + </div> </div> - + </div> - </> + <div> + <input type='text' className={styles.input} onChange={(e) => setComment(e.target.value)} /> + <button onClick={() => handleComment(post._id)} className={buttons.button2} >Comment</button> + </div> + </div> ) })}</div> <button onClick={loadPosts} className={buttons.button2} >Load 2 more</button> diff --git a/frontend/src/functions/Functions.js b/frontend/src/functions/Functions.js deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/frontend/src/index.css b/frontend/src/index.css index f3b518b600e45d092353ca115fcfedd1bd3c8722..b49e8e2924d05f94b91f18a526a6e9d532ad4584 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -20,7 +20,7 @@ body { h1{ - font-family: 'Inter', sans-serif; + font-family: 'Outfit', sans-serif; font-weight: bold; } p{ diff --git a/frontend/src/pages/Feed.js b/frontend/src/pages/Feed.js index b9ded43003d5a99f9560b63bc5b491b3f2315e8c..c5758a387397c43737ef662e8e383a4d84c9e391 100644 --- a/frontend/src/pages/Feed.js +++ b/frontend/src/pages/Feed.js @@ -6,26 +6,76 @@ import Post from '../components/Post' import buttons from '../styles/buttons.module.css' import { FaArrowLeft } from 'react-icons/fa'; import { Link } from 'react-router-dom' - +import axios from 'axios' const Feed = () => { + const [profileData, setProfileData] = useState() + const [loading, setLoading] = useState(true) + const [openPost, setOpenPost] = useState(false) + const fetchProfile = async () => { - return ( - <div> - <div className={styles.header}> - <div className={buttons.arrow}><Link to='/'><FaArrowLeft /></Link></div> - </div> - <Post /> - <div className={styles.container} > - <Posts /> - </div> - </div> + const token = localStorage.getItem('token'); + console.log(token) + + axios.get('http://localhost:5000/profile', { + headers: { + Authorization: `Bearer ${token}` + } + }).then((res) => { + setProfileData(res.data); + setLoading(false) + }).catch(err => console.log(err)) + + + } + + useEffect(() => { + + fetchProfile() + + }, []) - ) + const handleOpenPost = () => { + if (openPost == true) { + setOpenPost(false) + } else { + setOpenPost(true) + } + } + + if (loading == false) { + + return ( + + <div> + <div className={styles.header}> + + <div className={styles.header_photo}> <img className={styles.posts_header_img} src={`http://localhost:5000/uploads/${profileData.photo}`} /></div> + <div className={styles.header_text}> <h2 >Feed</h2></div> + <div className={styles.header_button}><button onClick={handleOpenPost} className={buttons.button3}>add post + + </button></div> + </div> + <div className={buttons.arrow}><Link to='/'><FaArrowLeft /></Link></div> + <div> {openPost ? ( + <Post/> + ) : ( + <></> + )}</div> + + + <div className={styles.container} > + <Posts /> + </div> + </div> + + ) + } else { + return (<div>loading</div>) + } } export default Feed \ No newline at end of file diff --git a/frontend/src/styles/buttons.module.css b/frontend/src/styles/buttons.module.css index d7918793e08e7c1793e5c2b6f39d9c2213906237..ef6066ba0285f648f447113b2703c2dd1cc2ebb0 100644 --- a/frontend/src/styles/buttons.module.css +++ b/frontend/src/styles/buttons.module.css @@ -105,4 +105,40 @@ .button2:active { box-shadow: none; + } + .button3 { + font-family: 'Outfit', sans-serif; + appearance: none; + background-color: #38dd6f; + border: none; + border-radius: 5px; + font-weight: 600; + color: #ffffff; + cursor: pointer; + font-size: 18px; + line-height: normal; + height: 40px; + width: 100px; + outline: none; + text-align: center; + transition: all 300ms cubic-bezier(.23, 1, 0.32, 1); + user-select: none; + -webkit-user-select: none; + touch-action: manipulation; + will-change: transform; + } + + + + .button3:hover { + color: #000000; + background-color: #ffffff; + border: none; + box-shadow: rgba(0, 0, 0, 0.25) 0 8px 15px; + transform: scale(1.05); + } + + .button3:active { + box-shadow: none; + } \ No newline at end of file diff --git a/frontend/src/styles/feed.module.css b/frontend/src/styles/feed.module.css index cbc46522c1ca09c8caebcf6f34e2bd6354c94578..517cb6a0e6099ffd8b3fbd980e73d488ae53e773 100644 --- a/frontend/src/styles/feed.module.css +++ b/frontend/src/styles/feed.module.css @@ -41,10 +41,10 @@ textarea { .description { width: 300px; border: none; - background-color: rgb(49, 49, 49); - border-radius: 4px; - color: rgb(255, 255, 255); - margin: 10px; + margin-top:54px; + font-family: 'Outfit', sans-serif; + color: rgb(0, 0, 0); + } .image_container { @@ -71,20 +71,43 @@ textarea { } .header{ - height: 20vh; + height: 8vh; + margin-bottom: 5px; + background-color:#71caf3; + box-shadow: 0 1px 15px 0 rgba(0, 0, 0, 0.2); + align-items: center; + width: 100vw; + color: white; + display: grid; + grid-template-columns: repeat(3, 1fr); +} +.header_photo{ + display: flex; + margin-top: auto; + margin-bottom: auto; +} +.header_text{ +margin: auto; } +.header_button{ + display: flex; + justify-content: end; + margin-right: 25px; + + } .container { background: rgb(255, 255, 255); - border-radius: 2px; + border-radius: 15px; + border: 0.5px solid rgb(185, 185, 185); box-shadow: 0 8px 13px 0 rgba(41, 41, 43, 0.705); width: 90%; margin: auto; padding: 20px; backdrop-filter: blur(10px); justify-content: center; - display: flex; text-align: center; - + display: flex; + margin-top: 150px; } .searchbar { @@ -104,7 +127,9 @@ textarea { height: 65vh; align-self: center; justify-self: center; - margin: auto; + margin-left: auto; + margin-right: auto; + margin-top: 200px; width:93%; display: flex; flex-direction: column; @@ -114,7 +139,8 @@ textarea { .post_header{ - margin: 25px; + margin-top: 100px; + margin: 10px; display: flex; width: 100%; color: white; @@ -181,7 +207,6 @@ textarea { margin-left: auto; margin-right: 20px; font-family: 'Outfit', sans-serif; - } @@ -189,19 +214,32 @@ textarea { min-height: 35vh; width: 900px; display: flex; - background: linear-gradient(135deg, rgb(48, 51, 51), rgb(36, 44, 44), 0); - backdrop-filter: blur(10px); - -webkit-backdrop-filter: blur(10px); + + background-color: white; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; box-shadow: 0 1px 15px 0 rgba(0, 0, 0, 0.2); text-align: left; } +.grid_container { + display: grid; + grid-template-columns: repeat(3, 1fr); + grid-template-rows: 300px; + grid-gap: 10px; +} + +.grid_container2 { + display: grid; + grid-template-columns: repeat(2, 1fr); + grid-template-rows: 300px; + grid-gap: 10px; +} + .preview_img_container { - width: 60px; + width: 300px; /* set width of image container */ - height: 60px; + height: 300px; border-radius: 50%; /* make image container circular */ overflow: hidden; @@ -273,6 +311,7 @@ textarea { margin-right: 10px; margin-bottom: 10px; display: inline-block; + flex-direction: column; } .wrapper { @@ -296,12 +335,11 @@ textarea { } -.posts_header img { +.posts_header_img { width: 45px; height: 45px; border-radius: 50%; object-fit: cover; - margin: 5px; border: solid 1px white; margin-left: 10px; } \ No newline at end of file diff --git a/frontend/src/styles/styles.module.css b/frontend/src/styles/styles.module.css index 19077064383bf4b63b4a374256297db7add7e39e..b61b22dd666583dbbf4ffc7d4ae494800bc5a74d 100644 --- a/frontend/src/styles/styles.module.css +++ b/frontend/src/styles/styles.module.css @@ -11,224 +11,46 @@ textarea{ text-align: start; margin-left:10px; } -.Header{ - height: 90vh; - display: flex; - justify-content: center; - align-items: center; - background-color: #ffffff; - color: rgb(0, 0, 0); - flex-wrap: wrap; /* Add flex-wrap property to allow text to wrap */ -} -.Header p{ - margin: 0; - width: 90%; - font-size: 110%; -} -.Header h1{ - margin: 0; - color: #000000; - font-size: 350%; -} - -.pick_file { - font-size: 35px; - margin:10px; +.background { + background-image: url('../../public/content/landing1.jpg'); + background-size: cover; + background-position: center center; + background-repeat: no-repeat; + height: 100vh; +} + +.content { + background-color: rgba(29, 29, 29, 0.178); + backdrop-filter: blur(5px); + height: 100vh; - display: inline; - justify-content: center; - align-items: center; - - -} - -.image_container { - width: 500px; /* set width of image container */ - height: 500px; /* set height of image container */ - border-radius: 50%; /* make image container circular */ - overflow: hidden; - display: flex; /* Add display flex to center image vertically */ - align-items: center; /* Center image vertically */ - justify-content: center; /* Center image horizontally */ - - } - -.image_container img { -height: 100%; -width: 100%; -object-fit: cover; - - -} - -.text_container{ - display: flex; - flex-direction: column; - justify-content: center; - text-align: left; - width: 40%; - } - -.Header2{ - height: 70vh; - display: flex; - justify-content: center; - background: #ffffff; - flex-wrap: wrap; /* Add flex-wrap property to allow text to wrap */ - +.header{ + height: 10vh; } -.card { - margin: 30px; - width: 400px; - height: 450px; - margin: auto; - color: rgb(0, 0, 0); - border-radius: 5px; - border: solid 3px black; - box-shadow: 0 8px 13px 0 rgba(41, 41, 43, 0.548); - text-align: center; - background: #ffffff; - } - .card h1{ - font-size: 250%; - color: #000000; - } - .list{ - list-style: none; - padding: 0; - margin: 0; - background: #ffffff; - font-size: 120%; - -} -.item{ - margin-top: 30px; - margin-bottom: 15px; - -} - -.post_container{ - min-height: 35vh; - margin: auto; - width: 600px; - text-align: center; - display: flex; - flex-direction: row; - flex-wrap: wrap; - background: linear-gradient(135deg,rgb(48, 51, 51),rgb(36, 44, 44),0 ); - backdrop-filter: blur(10px); - -webkit-backdrop-filter: blur(10px); - border-radius: 10px; - box-shadow: 0 1px 15px 0 rgba(0, 0, 0, 0.2); - box-align: center; -} -.post_container h1{ - margin: auto; - margin-top: 10px; -} -.post_input1{ - border: none; - background-color: rgb(26, 100, 100); - width: 500px; - height: 30px; - color: aliceblue; - outline: none; - margin-left: 50px; - margin-bottom: 10px; - margin-top: 15px; - border-radius:4px; -} -.post_input2{ - border: none; - background-color: rgb(26, 100, 100); - width: 500px; - height: 100px; - color: rgb(0, 0, 0); - outline: none; - margin-left: 50px; - margin-bottom: 10px; - margin-right: 20px; - border-radius:4px; -} -.post_container button{ - background: rgb(150, 172, 110); - color: rgb(0, 0, 0); - font-weight: bold; - font-size: 18px; - border: none; - width: 200px; - height: 80px; - margin-left: 35%; - margin-bottom: 25px; - border-radius: 5px; - - - -} -.upvote{ - background-color: rgb(25, 100, 100); - height: 30px; - width:30px; - box-align: center; - - font-size: 18px; - border-radius: 5px; - border: none; - color: white; - -} -.upvote button{ - background: rgb(150, 172, 110); - color: white; - margin: auto; -} -.posts_container{ - min-height: 35vh; - margin: auto; - margin-top: 30px; - - width: 900px; +.lander{ text-align: center; + align-items: center; + justify-content: center; + height: 90vh; display: flex; - flex-direction: row; - flex-wrap: wrap; - background: linear-gradient(135deg,rgb(48, 51, 51),rgb(36, 44, 44),0 ); - backdrop-filter: blur(10px); - -webkit-backdrop-filter: blur(10px); - border-radius: 10px; - box-shadow: 0 1px 15px 0 rgba(0, 0, 0, 0.2); -} -.post_img_container{ - width: 300px; /* set width of image container */ - height: 300px; /* set height of image container */ - border-radius: 50%; /* make image container circular */ - overflow: hidden; - display: flex; /* Add display flex to center image vertically */ - align-items: center; /* Center image vertically */ - justify-content: center; /* Center image horizontally */ - margin-left: 5%; - margin-right: 10%; - margin-top:5%; - margin-bottom:5%; -} -.post_img_container img{ - - height: 100%; - width: 100%; - object-fit: cover; } - -.addpicture{ - text-align: center; - margin-right: 30px; - margin-left:31%; - margin-bottom: 30px; - height:50px; - width:500px; - display:flex; -} -::placeholder { - color:aliceblue; - text-align: start; +.logo { + background: linear-gradient(-45deg, #1c0194, #038b37, #e89a3e, #e83e3e); + background-size: 300%; + font-weight: 900; + font-size: 450%; + letter-spacing: -2px; + text-transform: uppercase; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + animation: animated_text 10s ease-in-out infinite; + -moz-animation: animated_text 10s ease-in-out infinite; + -webkit-animation: animated_text 10s ease-in-out infinite; +} + +@keyframes animated_text { + 0% { background-position: 0px 50%; } + 50% { background-position: 100% 50%; } + 100% { background-position: 0px 50%; } } \ No newline at end of file