diff --git a/public/beth.png b/public/beth.png new file mode 100644 index 0000000..8a15b98 Binary files /dev/null and b/public/beth.png differ diff --git a/public/hailey.png.jpg b/public/hailey.png.jpg new file mode 100644 index 0000000..42b7c73 Binary files /dev/null and b/public/hailey.png.jpg differ diff --git a/public/jeffpic.JPG b/public/jeffpic.JPG new file mode 100755 index 0000000..332aa7d Binary files /dev/null and b/public/jeffpic.JPG differ diff --git a/public/newlogo.png b/public/newlogo.png new file mode 100644 index 0000000..66fd875 Binary files /dev/null and b/public/newlogo.png differ diff --git a/public/phone.png b/public/phone.png new file mode 100644 index 0000000..7f47c1b Binary files /dev/null and b/public/phone.png differ diff --git a/public/trash.png b/public/trash.png new file mode 100644 index 0000000..43876e7 Binary files /dev/null and b/public/trash.png differ diff --git a/src/App.css b/src/App.css index 0b277d7..9aa8f96 100644 --- a/src/App.css +++ b/src/App.css @@ -1,5 +1,5 @@ .Logo { - display: block; + display: flex; margin-left: auto; margin-right: auto; width: 300px; diff --git a/src/App.jsx b/src/App.jsx index 2be50c1..b65daf7 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -6,57 +6,64 @@ import { BrowserRouter as Router, Route, Routes, Navigate } from 'react-router-d import PostList from './components/PostList.jsx'; import PostForm from './components/PostForm'; import AboutUs from './components/AboutUs'; +import LandingPage from './components/LandingPage'; +import FavoritesList from './components/FavoritesList'; import styles from './App.css'; // import logo from './logo.png'; import Navigation from './components/Navigation'; - export default function App() { const [currentUser, setCurrentUser] = useState({}); + const [posts, setPosts] = useState(null); return ( -
{currentUser.id ? : !()} -
+
+ + +
+
- ) : ( - - ) + currentUser.id ? : } /> - + currentUser.id ? ( + ) : ( - + ) } /> + : } /> : } + element={ + currentUser.id ? : + } /> + } /> + + } /> + : } + element={currentUser.id ? : } />
diff --git a/src/components/AboutUs.css b/src/components/AboutUs.css index c430351..53b5bfe 100644 --- a/src/components/AboutUs.css +++ b/src/components/AboutUs.css @@ -3,12 +3,17 @@ flex-wrap: wrap; justify-content: center; align-items: center; + /* position: absolute; + top: 30px; */ } .AboutUsContainer { display: flex; flex-direction: column; - font-family: Varela Round; + font-family: 'Xhers', sans-serif; + position: absolute; + top: 300px; + left: 90px; } .ImageContainer { height: 170px; @@ -22,11 +27,11 @@ .TeamMember { height: 400=px; display: flex; - background-color: lightgreen; + background-color: #7e8f31; align-items: center; flex-wrap: wrap; /* padding-left: 20px; */ - font-family: Varela Round; + font-family: 'Xhers', sans-serif; margin: 40px; border: 3px black solid; -webkit-box-shadow: 6px 9px 18px -3px rgba(0, 0, 0, 0.39); diff --git a/src/components/AboutUs.jsx b/src/components/AboutUs.jsx index 9cb9e2c..176dd26 100644 --- a/src/components/AboutUs.jsx +++ b/src/components/AboutUs.jsx @@ -16,7 +16,7 @@ export default function AboutUs() {
- +

Beth Melesse

@@ -24,7 +24,7 @@ export default function AboutUs() {
- +

Jeff Allison

@@ -32,7 +32,7 @@ export default function AboutUs() {
- +

Hailey Steineke

diff --git a/src/components/FavoritesList.css b/src/components/FavoritesList.css new file mode 100644 index 0000000..bdc43de --- /dev/null +++ b/src/components/FavoritesList.css @@ -0,0 +1,5 @@ +.FavoritesList { + display: flex; + justify-content: center; + flex-direction: rows; +} diff --git a/src/components/FavoritesList.jsx b/src/components/FavoritesList.jsx new file mode 100644 index 0000000..cd375ea --- /dev/null +++ b/src/components/FavoritesList.jsx @@ -0,0 +1,24 @@ +import { useEffect, useState } from 'react'; +import { getFavorites } from '../../state/services/fetch-utils'; +import Post from './Post'; +import styles from './FavoritesList.css'; + +export default function FavoritesList() { + const [favPosts, setFavPosts] = useState([]); + + async function fetch() { + const postData = await getFavorites(); + setFavPosts(postData); + } + useEffect(() => { + fetch(); + }, []); + + return ( +
+ {favPosts.map((post) => ( + + ))} +
+ ); +} diff --git a/src/components/LandingPage.css b/src/components/LandingPage.css new file mode 100644 index 0000000..e33ad70 --- /dev/null +++ b/src/components/LandingPage.css @@ -0,0 +1,18 @@ +.landingPageImage { + display: flex; + flex-direction: row; + flex-wrap: nowrap; + justify-content: center; + align-items: center; + align-content: stretch; + width: auto; +} + +.Button { + margin: auto; + margin-top: 100px; + width: 50%; + padding: 10px; + padding: 50px; + margin-bottom: 75px; +} diff --git a/src/components/LandingPage.jsx b/src/components/LandingPage.jsx new file mode 100644 index 0000000..bde0789 --- /dev/null +++ b/src/components/LandingPage.jsx @@ -0,0 +1,22 @@ +import React from 'react'; +import styles from './LandingPage.css'; +import { useNavigate } from 'react-router-dom'; + +export default function LandingPage() { + const history = useNavigate(); + + async function gotoFeed() { + history('/posts'); + } + + return ( + <> +
+ +
+ + + ); +} diff --git a/src/components/LinkButton.jsx b/src/components/LinkButton.jsx index 6d2f36b..8cbd5b4 100644 --- a/src/components/LinkButton.jsx +++ b/src/components/LinkButton.jsx @@ -7,10 +7,10 @@ import { LinkedIn } from '@mui/icons-material'; export default function LinkButton({ text, link, linkedin }) { const ColorButton = styled(Button)(({ theme }) => ({ color: theme.palette.getContrastText('#221F1F'), - backgroundColor: 'grey', + backgroundColor: 'black', width: '20px', '&:hover': { - backgroundColor: 'green', + backgroundColor: '#ccb3ff', }, })); return ( diff --git a/src/components/Navigation.jsx b/src/components/Navigation.jsx index a2fbe83..4dd85cd 100644 --- a/src/components/Navigation.jsx +++ b/src/components/Navigation.jsx @@ -5,7 +5,8 @@ import EmojiPeopleIcon from '@mui/icons-material/EmojiPeople'; import ExitToAppIcon from '@mui/icons-material/ExitToApp'; import AddBoxIcon from '@mui/icons-material/AddBox'; import HomeIcon from '@mui/icons-material/Home'; -import { AppBar, Toolbar, Stack, Button } from '@mui/material'; +import FavoriteIcon from '@mui/icons-material/Favorite'; +import { AppBar, Toolbar, Stack, Button, Box, Typography } from '@mui/material'; import { Link } from 'react-router-dom'; import { logoutUser } from '../../state/services/fetch-utils'; @@ -18,9 +19,9 @@ export default function Navigation() { setCurrentUser({}); } return ( - - - + + + + - + + +
- + +
); } diff --git a/src/components/PostForm.css b/src/components/PostForm.css index c0577a2..1ba7b80 100644 --- a/src/components/PostForm.css +++ b/src/components/PostForm.css @@ -1,18 +1,19 @@ .Container { position: absolute; left: 50%; - top: 50%; + top: 65%; transform: translate(-50%, -50%); border: 5px solid #ffff00; padding: 20px; box-shadow: 12px 12px 2px 1px rgba(0, 0, 255, 0.2); - width: 500px; - height: 550px; + width: 525px; + height: 525px; border: 1px solid #2d2d2d; margin: 20px; border-radius: 10%; background-color: #7e8f31; font-family: 'Xhers', sans-serif; + margin-bottom: 30px; } .FormContainer { diff --git a/src/components/PostForm.jsx b/src/components/PostForm.jsx index cfc0587..7dc321f 100644 --- a/src/components/PostForm.jsx +++ b/src/components/PostForm.jsx @@ -1,15 +1,16 @@ /* eslint-disable max-len */ -import { useState, useEffect } from 'react'; -import { insertImage } from '../../state/services/fetch-utils.js'; +import { useState } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { getAllPosts, insertImage } from '../../state/services/fetch-utils.js'; import { createPost } from '../../state/services/fetch-utils.js'; import { getUser } from '../../state/services/fetch-utils.js'; import styles from './PostForm.css'; -export default function PostForm() { +export default function PostForm({ setPosts }) { const [fileInputState, setFileInputState] = useState(''); const [previewSource, setPreviewSource] = useState(''); - const [selectedFile, setSelectedFile] = useState(''); - const [caption, setCaption] = useState(''); + const [caption, setCaption] = useState('Is it trash?'); + const history = useNavigate(); const handleFileInputChange = (e) => { const file = e.target.files[0]; @@ -24,10 +25,13 @@ export default function PostForm() { }; }; - const handleSubmit = (e) => { + const handleSubmit = async (e) => { e.preventDefault(); if (!previewSource) return; - uploadImage(previewSource); + await uploadImage(previewSource); + const posts = await getAllPosts(); + setPosts(posts); + history('/posts'); }; const uploadImage = async (image) => { @@ -73,13 +77,6 @@ export default function PostForm() { - - {/*
-

{post.caption}

-

{post.created_at}

-

{post.username}

- -
*/} ); } diff --git a/src/components/PostList.css b/src/components/PostList.css index aeba37a..33f79c6 100644 --- a/src/components/PostList.css +++ b/src/components/PostList.css @@ -1,4 +1,4 @@ .PostListContainer { display: grid; justify-content: center; -} \ No newline at end of file +} diff --git a/src/components/PostList.jsx b/src/components/PostList.jsx index ed9e3e2..ce1af7b 100644 --- a/src/components/PostList.jsx +++ b/src/components/PostList.jsx @@ -1,18 +1,23 @@ +/* eslint-disable no-unused-vars */ + /* eslint-disable max-len */ import Post from './Post.jsx'; import { useState, useEffect } from 'react'; import { getAllPosts } from '../../state/services/fetch-utils'; import styles from './PostList.css'; +import SearchBar from './SearchBar.jsx'; -export default function PostList() { - const [posts, setPosts] = useState(null); - // store boolean state value, pass down setUpdatedpost into each mapped post, after update set vote values to true, useeffect to watch boolean state value & refetches +export default function PostList({ posts, setPosts }) { + const [filteredData, setFilteredData] = useState(false); + const [search, setSearch] = useState(''); + const [filteredResults, setFilteredResults] = useState([]); - //in post.jsx check at button if trashvote is < than state value then display trash reaction, otherwise display trashIncrement + useEffect(() => { + getTrashPostsOnLoad(); + }, []); async function getTrashPostsOnLoad() { const trashPosts = await getAllPosts(); - console.log('trashPosts', trashPosts); if (trashPosts) { setPosts(trashPosts); @@ -20,20 +25,42 @@ export default function PostList() { } useEffect(() => { - getTrashPostsOnLoad(); - }, []); - - if (!posts) return null; + if (search) { + const filteredPosts = posts.filter((value) => { + return value.caption.toLowerCase().includes(search.toLowerCase()); + }); + setFilteredResults(filteredPosts); + } + }, [search]); - return ( -
- Post List - {posts.length && + function conditionalRender() { + if (!filteredResults.length) { + return ( + posts.length && posts.map((post) => ( - //

{post.caption}

; + )) + ); + } else { + return filteredResults.map((post) => ( + + )); + } + } - ))} -
+ if (!posts) return null; + + return ( + <> +
+ +
+
{conditionalRender()}
+ ); } diff --git a/src/components/SearchBar.css b/src/components/SearchBar.css new file mode 100644 index 0000000..0036321 --- /dev/null +++ b/src/components/SearchBar.css @@ -0,0 +1,23 @@ +.SearchBar { + display: flex; + margin-left: 50px; +} + +.SearchForm { + height: 300px; + width: 300px; + border-radius: 50%; + font-family: 'Xhers', sans-serif; + color: white; +} + +.SearchButton { + background: lightgrey; +} + +.ButtonDiv { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; +} diff --git a/src/components/SearchBar.jsx b/src/components/SearchBar.jsx new file mode 100644 index 0000000..3c30e58 --- /dev/null +++ b/src/components/SearchBar.jsx @@ -0,0 +1,49 @@ +/* eslint-disable no-unused-vars */ +/* eslint-disable max-len */ +import { useState } from 'react'; +import styles from './SearchBar.css'; +import image from '../../public/trash.png'; + +// import "./SearchBar.css"; + +export default function SearchBar({ setFilteredResults, setFilteredData, search, setSearch }) { + const [query, setQuery] = useState(''); + const handleSearch = (e) => { + e.preventDefault(); + setSearch(query); + setQuery(''); + }; + + const reset = () => { + setQuery(''); + setFilteredResults([]); + }; + + return ( +
+
+
+

Filter Your Trash

+ setQuery(e.target.value)} + type="text" + value={query} + placeholder="Search Posts" + /> +
+ + {search.length ? ( + + ) : null} +
+
+
+
+ ); +} diff --git a/src/components/SearchFilter.jsx b/src/components/SearchFilter.jsx deleted file mode 100644 index e69de29..0000000 diff --git a/src/components/SignIn.css b/src/components/SignIn.css index 556fe2f..e21673b 100644 --- a/src/components/SignIn.css +++ b/src/components/SignIn.css @@ -13,7 +13,7 @@ form { justify-content: center; align-items: center; margin: 3px; - font-family: 'Varela Round'; + font-family: 'Xhers', sans-serif; } button { @@ -24,7 +24,7 @@ button { /* padding: 20px; */ border-radius: 10px; font-size: 15px; - font-family: 'Varela Round'; + font-family: 'Xhers', sans-serif; font-weight: 500; display: flex; flex-direction: column; diff --git a/src/components/SignIn.jsx b/src/components/SignIn.jsx index 1816f6d..3db7046 100644 --- a/src/components/SignIn.jsx +++ b/src/components/SignIn.jsx @@ -3,6 +3,8 @@ import { useState } from 'react'; import './SignIn.css'; import { getUser, signInUserFunction } from '../../state/services/fetch-utils'; import { NavLink } from 'react-router-dom'; + + export default function SignIn({ setCurrentUser }) { const [signInUser, setSignInUser] = useState({ email: '', password: '' }); @@ -15,7 +17,6 @@ export default function SignIn({ setCurrentUser }) { return (
-

THIS IS OUR LOGO

- +
+ + + Back to Sign In + +
diff --git a/src/components/UseSearch.jsx b/src/components/UseSearch.jsx new file mode 100644 index 0000000..137ab57 --- /dev/null +++ b/src/components/UseSearch.jsx @@ -0,0 +1,26 @@ +import { useState, useEffect } from 'react'; +import { useSearchParams } from 'react-router-dom'; + +export function useSearch() { + const [searchParams, setSearchParams] = useSearchParams(); + const [params, setParamsObject] = useState({}); + + useEffect(() => { + setParamsObject(Object.fromEntries(searchParams.entries())); + }, [searchParams.toString()]); + + const setParams = (search) => { + const clean = removeEmptyKeys(search); + setSearchParams(clean); + }; + + return { params, setParams }; +} + +export function removeEmptyKeys(object) { + const filtered = Object.entries(object).filter( + ([, value]) => value !== undefined && value !== null && value !== '' + ); + + return Object.fromEntries(filtered); +} diff --git a/src/components/justincase.jsx b/src/components/justincase.jsx deleted file mode 100644 index ad07b7a..0000000 --- a/src/components/justincase.jsx +++ /dev/null @@ -1,82 +0,0 @@ -// import { useState, useEffect } from 'react'; -// import { insertImage } from '../../state/services/fetch-utils.js'; -// import Alert from './Alert.jsx'; - -// export default function Post() { -// const [fileInputState, setFileInputState] = useState(''); -// const [previewSource, setPreviewSource] = useState(''); -// const [selectedFile, setSelectedFile] = useState(''); -// const [successMsg, setSuccessMsg] = useState(''); -// const [errMsg, setErrMsg] = useState(''); - -// const handleFileInputChange = (e) => { -// const file = e.target.files[0]; -// previewFile(file); -// setSelectedFile(file); -// setFileInputState(e.target.value); -// }; - -// const previewFile = (file) => { -// const reader = new FileReader(); -// reader.readAsDataURL(file); -// reader.onloadend = () => { -// setPreviewSource(reader.result); -// }; -// }; - -// // const handleSubmit = (e) => { -// // e.preventDefault(); -// // if (!previewSource) return; -// // uploadImage(previewSource); -// // }; - -// const handleSubmitFile = (e) => { -// e.preventDefault(); -// if (!selectedFile) return; -// const reader = new FileReader(); -// reader.readAsDataURL(selectedFile); -// reader.onloadend = async () => { -// await insertImage(image); -// reader.result; -// }; -// reader.onerror = () => { -// console.error('AHHHHHHHH!!'); -// setErrMsg('something went wrong!'); -// }; -// }; - -// const uploadImage = async (image) => { -// console.log('image', image); -// try { -// await insertImage(image); -// setFileInputState(''); -// setPreviewSource(''); -// setSuccessMsg('Image uploaded successfully'); -// } catch (error) { -// console.error(error); -// console.error(err); -// setErrMsg('Something went wrong!'); -// } -// }; - -// return ( -//
-// -// -//
-//

upload pic here

-// - -// -//
-// {previewSource && image-preview} -// Post -//
-// ); -// } diff --git a/state/services/fetch-utils.js b/state/services/fetch-utils.js index f12e6d0..9eebbc9 100644 --- a/state/services/fetch-utils.js +++ b/state/services/fetch-utils.js @@ -4,28 +4,56 @@ export async function getAllPosts() { return res.json(); } +export async function addtoFavorites(id) { + const response = await fetch(`${process.env.REACT_APP_API_URL}/posts/favorites`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ id }), + }); + const data = await response.json(); + return data; +} + +export async function getFavorites() { + const response = await fetch(`${process.env.REACT_APP_API_URL}/posts/favorites`, { + method: 'GET', + headers: { 'Content-Type': 'application/json' }, + }); + const data = await response.json(); + return data; +} + // export async function getAllReactions() { // const res = await fetch(`${process.env.REACT_APP_API_URL}/reactions`); // } export async function createPost(post) { - const response = await fetch(`${process.env.REACT_APP_API_URL}/posts`, { + const res = await fetch(`${process.env.REACT_APP_API_URL}/posts`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(post), }); - const data = await response.json(); + const data = await res.json(); return data; } export async function updatePost(post) { - const response = await fetch(`${process.env.REACT_APP_API_URL}/posts/${post.id}`, { + const res = await fetch(`${process.env.REACT_APP_API_URL}/posts/${post.id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(post), }); - const data = await response.json(); - console.log(data, 'A FUNKY STRING OF DATA'); + const data = await res.json(); + return data; +} + +export async function deletePost(post) { + const res = await fetch(`${process.env.REACT_APP_API_URL}/posts/${post.id}`, { + method: 'DELETE', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(post), + }); + const data = await res.json(); return data; } @@ -48,25 +76,25 @@ export async function insertImage(image_url) { } export async function signUpUserFunction(user) { - const response = await fetch(`${process.env.REACT_APP_API_URL}/users`, { + const res = await fetch(`${process.env.REACT_APP_API_URL}/users`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'include', mode: 'cors', body: JSON.stringify(user), }); - const data = await response.json(); + const data = await res.json(); return data; } export async function signInUserFunction(user) { - const response = await fetch(`${process.env.REACT_APP_API_URL}/users/sessions`, { + const res = await fetch(`${process.env.REACT_APP_API_URL}/users/sessions`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'include', mode: 'cors', body: JSON.stringify(user), }); - const data = await response.json(); + const data = await res.json(); return data; } export async function logoutUser() { @@ -78,12 +106,12 @@ export async function logoutUser() { }); } export async function getUser() { - const response = await fetch(`${process.env.REACT_APP_API_URL}/users/me`, { + const res = await fetch(`${process.env.REACT_APP_API_URL}/users/me`, { method: 'GET', headers: { 'Content-Type': 'application/json' }, credentials: 'include', mode: 'cors', }); - const data = await response.json(); + const data = await res.json(); return data; } diff --git a/state/services/toaster.js b/state/services/toaster.js index 0515b9a..ab984e4 100644 --- a/state/services/toaster.js +++ b/state/services/toaster.js @@ -6,4 +6,4 @@ export function showSuccess(msg) { export function showError(msg) { toast.error(msg); -} \ No newline at end of file +}