Skip to content
Snippets Groups Projects
Commit b588bb22 authored by Ludvig Damberg's avatar Ludvig Damberg
Browse files

pages

implement the first pages
parent cd9c56ff
No related branches found
No related tags found
No related merge requests found
......@@ -18,6 +18,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^4.8.0",
"react-router-dom": "^6.10.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
}
......@@ -3512,6 +3513,14 @@
"url": "https://opencollective.com/popperjs"
}
},
"node_modules/@remix-run/router": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.5.0.tgz",
"integrity": "sha512-bkUDCp8o1MvFO+qxkODcbhSqRa6P2GXgrGZVpt0dCXNW2HCSCqYI0ZoAqEOSAjRWmmlKcYgFvN4B4S+zo/f8kg==",
"engines": {
"node": ">=14"
}
},
"node_modules/@rollup/plugin-babel": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
......@@ -14827,6 +14836,36 @@
"node": ">=0.10.0"
}
},
"node_modules/react-router": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.10.0.tgz",
"integrity": "sha512-Nrg0BWpQqrC3ZFFkyewrflCud9dio9ME3ojHCF/WLsprJVzkq3q3UeEhMCAW1dobjeGbWgjNn/PVF6m46ANxXQ==",
"dependencies": {
"@remix-run/router": "1.5.0"
},
"engines": {
"node": ">=14"
},
"peerDependencies": {
"react": ">=16.8"
}
},
"node_modules/react-router-dom": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.10.0.tgz",
"integrity": "sha512-E5dfxRPuXKJqzwSe/qGcqdwa18QiWC6f3H3cWXM24qj4N0/beCIf/CWTipop2xm7mR0RCS99NnaqPNjHtrAzCg==",
"dependencies": {
"@remix-run/router": "1.5.0",
"react-router": "6.10.0"
},
"engines": {
"node": ">=14"
},
"peerDependencies": {
"react": ">=16.8",
"react-dom": ">=16.8"
}
},
"node_modules/react-scripts": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz",
......@@ -20111,6 +20150,11 @@
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.7.tgz",
"integrity": "sha512-Cr4OjIkipTtcXKjAsm8agyleBuDHvxzeBoa1v543lbv1YaIwQjESsVcmjiWiPEbC1FIeHOG/Op9kdCmAmiS3Kw=="
},
"@remix-run/router": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.5.0.tgz",
"integrity": "sha512-bkUDCp8o1MvFO+qxkODcbhSqRa6P2GXgrGZVpt0dCXNW2HCSCqYI0ZoAqEOSAjRWmmlKcYgFvN4B4S+zo/f8kg=="
},
"@rollup/plugin-babel": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
......@@ -28196,6 +28240,23 @@
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
"integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A=="
},
"react-router": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.10.0.tgz",
"integrity": "sha512-Nrg0BWpQqrC3ZFFkyewrflCud9dio9ME3ojHCF/WLsprJVzkq3q3UeEhMCAW1dobjeGbWgjNn/PVF6m46ANxXQ==",
"requires": {
"@remix-run/router": "1.5.0"
}
},
"react-router-dom": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.10.0.tgz",
"integrity": "sha512-E5dfxRPuXKJqzwSe/qGcqdwa18QiWC6f3H3cWXM24qj4N0/beCIf/CWTipop2xm7mR0RCS99NnaqPNjHtrAzCg==",
"requires": {
"@remix-run/router": "1.5.0",
"react-router": "6.10.0"
}
},
"react-scripts": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz",
......@@ -13,6 +13,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^4.8.0",
"react-router-dom": "^6.10.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
......
frontend/public/content/cheers.jpg

2.13 MiB

import axios from 'axios'
import React, {useState, useEffect} from 'react'
import './styles.css'
import styles from './styles/styles.module.css'
import Landing from './components/Landing'
import Post from './components/Post'
import SignUp from './components/SignUp'
import Login from './components/Login'
import Header from './components/Header'
function App() {
const [posts,setPosts] = useState([])
......@@ -26,18 +23,20 @@ const loadPosts = () => {
loadPosts()
},[])
return (
<>
<Header/>
<Landing/>
<Post/>
<div className=''>
<div>
<h1>POSTS</h1>
<div className=''>{posts.map((post) => {
<div>{posts.map((post) => {
return(
<div className='posts-container' key={post._id}>
<img className='img' src={`http://localhost:5000/uploads/${post.photo}`}/>
<div className={styles.posts_container} key={post._id}>
<img className={styles.img} src={`http://localhost:5000/uploads/${post.photo}`}/>
<div>
<h1>{post.name}</h1>
<p>{post.description}</p>
......@@ -47,8 +46,7 @@ const loadPosts = () => {
)
})}</div>
</div>
<SignUp/>
<Login/>
</>
);
}
......
import React from 'react'
import {Link} from 'react-router-dom'
import styles from '../styles/header.module.css'
const Header = () => {
return (
<div className={styles.header}>
<Link to='/register'>
<div className={styles.button}>Register</div>
</Link>
<Link to='/login'>
<div className={styles.button}>Login</div>
</Link>
</div>
)
}
export default Header
\ No newline at end of file
import React from 'react'
import '../styles.css'
import styles from '../styles/styles.module.css'
const Landing = () => {
return (
<>
<div className='Header'>
<div className='text-container'>
<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='image-container'>
<div className={styles.image_container}>
<img alt='' src='../../content/landing.jpg'/>
</div>
</div>
<div className='Header2'>
<div className='card'>
<div className={styles.Header2}>
<div className={styles.card}>
<h1>Functionality 🍺</h1>
<ul className='list'>
<li className='item'>Creating Posts </li>
<li className='item'>Account Sign Up </li>
<li className='item'>Logging In </li>
<li className='item'>Authentication Checking </li>
<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>
</ul>
</div>
<div className='card'>
<div className={styles.card}>
<h1>Pages🍺</h1>
<ul className='list'>
<li className='item'>Home </li>
<li className='item'>About </li>
<li className='item'>Discover </li>
<li className='item'>Log In and Sign Up </li>
<li className='item'>Crate Post </li>
<ul className={styles.list}>
<li className={styles.item}>Home </li>
<li className={styles.item}>About </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='card'>
<div className={styles.card}>
<h1>User Experience🍺</h1>
<ul className='list'>
<li className='item'>Scrolling Triggers </li>
<li className='item'>Hover Interactions </li>
<li className='item'>Instructional Interface </li>
<li className='item'>Easy Usage </li>
<li className='item'>Consistent Theme </li>
<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>
......
import React from 'react'
import {useState} from 'react'
import {useState, useRef, useEffect} from 'react'
import axios from 'axios'
const Login = () => {
const userRef = useRef();
const errRef = useRef();
const[password,setPassword] = useState("")
const[email,setEmail] = useState("")
const [errMsg, setErrMsg] = useState('');
const [success, setSuccess] = useState(false);
// useEffect(()=>{
// userRef.current.focus();
// }, [])
useEffect(() => {
setErrMsg('');
}, [email, password])
const Login = () => {
const handleLogin = () => {
console.log({email,password})
setSuccess(true);
axios.post("http://localhost:5000/login", {email, password})
.then((res) => {
......@@ -21,12 +36,42 @@ const Login = () => {
}
return (
<>
{success ? (
<section>
<h1>You are logged in!</h1>
<br />
</section>
) : (
<div>
<input type='text' placeholder='Email' onChange={(e) => setEmail(e.target.value)}/>
<input type='text' placeholder='Password' onChange={(e) => setPassword(e.target.value)}/>
<button onClick={Login}>Sign up</button>
<p ref={errRef} className = {errMsg ? "errmsg" : "offscreen"}
aria-live = "assertive">{errMsg}</p>
<h1>Sign In</h1>
<label htmlFor = "Email">Email: </label>
<input
type='text'
id='Email'
ref ={userRef}
autocomplete = "off"
onChange={(e) => setEmail(e.target.value)}
value = {email}
required/>
<label htmlFor = "password">Password: </label>
<input
type='text'
id="password"
ref ={userRef}
onChange={(e) => setPassword(e.target.value)}
value = {password}
required/>
<button onClick={handleLogin}>Sign in</button>
</div>
)}
</>
)
}
......
import React from 'react'
import {useState} from 'react'
import {useState, useRef, useEffect} from 'react'
import axios from 'axios'
const USER_REGEX = /^[a-zA-Z][a-zA-Z0-9-_]{3,23}$/;
const SignUp = () => {
const userRef = useRef();
const errRef = useRef();
const[username,setUsername] = useState("")
const[password,setPassword] = useState("")
const[email,setEmail] = useState("")
const Signup = () => {
const [validName, setValidName] = useState(false);
const [errMsg, setErrMsg] = useState('');
const [success, setSuccess] = useState(false);
useEffect(() => {
setErrMsg('');
}, [username, password])
useEffect(() => {
const result = USER_REGEX.test(username);
setValidName(result);
}, [username])
const handleSignup = () => {
setSuccess(true);
console.log({email,username,password})
......@@ -27,13 +51,50 @@ const SignUp = () => {
}
return (
<>
{success ? (
<section>
<h1>Success!</h1>
<p>
<a href="#">Sign In</a>
</p>
</section>
) : (
<div>
<input type='text' placeholder='Email' onChange={(e) => setEmail(e.target.value)}/>
<input type='text' placeholder='Username' onChange={(e) => setUsername(e.target.value)}/>
<input type='text' placeholder='Password' onChange={(e) => setPassword(e.target.value)}/>
<button onClick={Signup}>Sign up</button>
<h1>Register</h1>
<label htmlFor="email">Email:</label>
<input type='text'
placeholder='Email'
ref={userRef}
autoComplete="off"
onChange={(e) => setEmail(e.target.value)}
/>
<label htmlFor="username">Username:</label>
<input type='text'
placeholder='Username'
ref={userRef}
autoComplete="off"
onChange={(e) => setUsername(e.target.value)}
required
/>
<label htmlFor="password">Password:</label>
<input type='password'
placeholder='Password'
onChange={(e) => setPassword(e.target.value)}
value={password}/>
<button disabled={!validName ? true : false}
onClick={handleSignup}>
Sign up
</button>
</div>
)}
</>
)
}
......
......@@ -2,12 +2,31 @@ import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import Register from './pages/Register';
import Login from './pages/Login';
import { RouterProvider, createBrowserRouter, Route } from 'react-router-dom';
const router =createBrowserRouter([
{
path: '/',
element: <App/>
},
{
path: '/login',
element: <Login/>
},
{
path: '/register',
element: <Register/>
},
])
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<App />
<RouterProvider router={router}/>
);
// If you want to start measuring performance in your app, pass a function
......
import React from 'react'
import styles from '../styles/login.module.css'
const Login = () => {
return (
<div className={styles.parent}>
<div className={styles.left}>
<h1>LOGIN TO START SHARING THE FUN!</h1>
</div>
<div className={styles.right}>
<div className={styles.image_container}>
<img src='../content/cheers.jpg'/>
</div>
</div>
</div>
)
}
export default Login
\ No newline at end of file
import React from 'react'
const Register = () => {
return (
<>
</>
)
}
export default Register
\ No newline at end of file
.header{
height: 10vh;
margin: 0;
padding: 10px;
display: flex;
justify-content: end;
}
.button {
appearance: none;
background-color: rgb(255, 240, 153);
border: 0.125em solid #383838;
border-radius: 0.9375em;
box-sizing: border-box;
color: #383838;
cursor: pointer;
display: inline-block;
font-size: 16px;
font-weight: 600;
line-height: normal;
margin: 0;
min-height: 3.75em;
min-width: 0;
outline: none;
padding: 1em 2.3em;
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;
margin: 5px;
}
.button:disabled {
pointer-events: none;
}
.button:hover {
color: #fff;
background-color: #1A1A1A;
box-shadow: rgba(0, 0, 0, 0.25) 0 8px 15px;
transform: translateY(-2px);
}
.button:active {
box-shadow: none;
transform: translateY(0);
}
\ No newline at end of file
.parent{
display: flex;
height: 100vh;
}
.left{
width: 40%;
background: rgb(49, 117, 121);
}
.left h1{
margin: 0;
color: rgb(255, 240, 153);
}
.right{
width: 60%;
height: 100vh;
background: black;
}
.image_container {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
}
.image_container img{
max-width: 150%;
max-height: 150%;
object-fit: cover;
}
\ No newline at end of file
......@@ -7,7 +7,7 @@ input{
font-family: 'Poppins', sans-serif;
}
.Header{
height: 100vh;
height: 90vh;
display: flex;
justify-content: center;
align-items: center;
......@@ -25,7 +25,7 @@ input{
color: rgb(255, 240, 153);
font-size: 350%;
}
.pick-file {
.pick_file {
color: rgb(67, 1, 128);
font-size: 35px;
margin:0;
......@@ -36,7 +36,7 @@ input{
}
.image-container {
.image_container {
width: 500px; /* set width of image container */
height: 500px; /* set height of image container */
border-radius: 50%; /* make image container circular */
......@@ -47,14 +47,14 @@ input{
}
.image-container img {
.image_container img {
height: 100%;
width: 100%;
object-fit: cover;
}
.text-container{
.text_container{
display: flex;
flex-direction: column;
justify-content: center;
......@@ -96,7 +96,7 @@ object-fit: cover;
margin-bottom: 15px;
}
.post-container{
.post_container{
min-height: 35vh;
margin: auto;
width: 50vw;
......@@ -111,7 +111,7 @@ object-fit: cover;
box-shadow: 0 8px 23px 0 rgba(0, 0, 0, 0.2);
}
.post-input1{
.post_input1{
border: none;
background-color: rgb(11, 58, 58);
width: 300px;
......@@ -122,7 +122,7 @@ object-fit: cover;
margin-top: 15px;
}
.post-input2{
.post_input2{
border: none;
background-color: rgb(11, 58, 58);
width: 1000px;
......@@ -132,7 +132,7 @@ object-fit: cover;
margin: 10px;
}
.post-container button{
.post_container button{
background: rgb(150, 172, 110);
color: white;
font-weight: bold;
......@@ -144,7 +144,7 @@ object-fit: cover;
font-family: 'Poppins', sans-serif;
border-radius: 5px;
}
.posts-container{
.posts_container{
min-height: 35vh;
margin: auto;
margin-top: 30px;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment