diff --git a/package-lock.json b/package-lock.json index 969c081..b14bb7e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,9 @@ "react-dom": "^17.0.2", "react-redux": "^7.2.6", "react-scripts": "5.0.0" + }, + "devDependencies": { + "uuid": "^8.3.2" } }, "node_modules/@babel/code-frame": { diff --git a/package.json b/package.json index 4ab844f..7bd4505 100644 --- a/package.json +++ b/package.json @@ -32,5 +32,8 @@ "last 1 firefox version", "last 1 safari version" ] + }, + "devDependencies": { + "uuid": "^8.3.2" } } diff --git a/src/App.css b/src/App.css index 5730ebf..7b201a4 100644 --- a/src/App.css +++ b/src/App.css @@ -1,5 +1,7 @@ .App { - text-align: center; + display: flex; + flex-direction: column; + align-items: center; margin: 0; padding: 0; } @@ -9,4 +11,55 @@ flex-direction: row; justify-content: space-between; align-items: baseline; + width: 100%; + height: 5rem; + border-bottom: 1px solid black; +} + +.navbar > * { + padding: 0 2rem; +} + +.content-container { + display: inline-flex; + flex-direction: row; +} + +.feed { + display: inline-flex; + flex-direction: column; + align-items: center; + width: 90vw; +} + +.about-the-app { + display: hidden; + flex-direction: column; + align-items: center; +} + +.sidebar { + display: flex; + flex-direction: column; + width: 12rem; + position: fixed; + background-color: black; + color: white; + right: 0; + top: 5rem; + padding: 1.5rem; + transition: right 0.6s ease-out; +} + +.sidebar-hidden { + display: flex; + flex-direction: column; + width: 12rem; + position: fixed; + background-color: black; + color: white; + right: -15rem; + top: 5rem; + padding: 1.5rem; + transition: right 0.6s ease-out; } \ No newline at end of file diff --git a/src/App.js b/src/App.js index 99c00b2..d081c13 100644 --- a/src/App.js +++ b/src/App.js @@ -1,13 +1,29 @@ import React from 'react'; import './App.css'; import Navbar from './features/navbar/Navbar'; -import redditSlice from './features/reddit/redditSlice'; +import Post from './features/posts/Post'; +import Feed from './features/posts/Feed'; function App() { return (
-

Stuff

+
+ +
+ {/* To do: import posts from post directory */} + {/* Map post data onto individual post cards, handle undefined values */} + +
+ +
+ {/* To do: add mutable state to class name for this div, */} + {/* determining whether or not it's active based on the state of */} + {/* The action dispatched from the searchbar slice(?) */} + {/* Do I need a searchbar slice? */} +
+ +
); } diff --git a/src/features/navbar/Navbar.js b/src/features/navbar/Navbar.js index 2990440..9066a9d 100644 --- a/src/features/navbar/Navbar.js +++ b/src/features/navbar/Navbar.js @@ -1,11 +1,24 @@ -import React from "react"; +import React, { useState } from "react"; +import SearchBar from "../searchBar/searchBar"; +import Sidebar from "../sidebar/Sidebar"; export default function Navbar() { + const [collapsed, setCollapsed] = useState(true); + + const handleCollapse = () => { + setCollapsed(!collapsed); + } + return ( + <>

Reddit but it's all cats

-

Search bar here

-

Expand sidebar here

+ +
+
+ +
+ ) } \ No newline at end of file diff --git a/src/features/posts/Feed.js b/src/features/posts/Feed.js new file mode 100644 index 0000000..d5e878d --- /dev/null +++ b/src/features/posts/Feed.js @@ -0,0 +1,55 @@ +import React, { useState, useEffect } from "react"; +import postsSlice, { fetchBySub, updatePosts, selectPosts } from "./postsSlice"; +import { selectAllSubs } from "../reddit/redditSlice"; +import { useSelector, useDispatch } from "react-redux"; +import { v4 } from "uuid"; +import Post from "./Post"; + +export default function Feed() { + const [feed, setFeed] = useState(null); + const dispatch = useDispatch(); + + useEffect(() => { + let isActive = true; + + const getPosts = async() => { + let myPosts = await dispatch(fetchBySub('https://www.reddit.com/r/cats.json')); + myPosts = myPosts.payload; + console.log(myPosts); + + if (typeof myPosts === 'object' && isActive) { + let newFeed = []; + for (let post of myPosts) { + newFeed.push( + + ); + } + setFeed(newFeed); + } + }; + getPosts(); + + return () => { + isActive = false; + } + + }, [dispatch]) + + return ( + <> + {feed ? feed :

Loading cats for you...

} + + ); +} \ No newline at end of file diff --git a/src/features/posts/Post.css b/src/features/posts/Post.css new file mode 100644 index 0000000..7577f35 --- /dev/null +++ b/src/features/posts/Post.css @@ -0,0 +1,30 @@ +.post-body { + display: inline-flex; + flex-direction: column; + width: 75%; + padding: 2rem; + border: 1px solid black; + margin: 3rem 0; +} + +.image-placeholder { + display: inline-flex; + background-color: grey; + width: 30%; + height: 15rem; +} + +a { + font-size: 2rem; +} + +img, video { + max-height: 45rem; + object-fit: contain; +} + +.post-metadata { + display: inline-flex; + flex-direction: row; + justify-content: space-between; +} \ No newline at end of file diff --git a/src/features/posts/Post.js b/src/features/posts/Post.js index e69de29..bc65e4a 100644 --- a/src/features/posts/Post.js +++ b/src/features/posts/Post.js @@ -0,0 +1,31 @@ +import React, { useState, useEffect } from "react"; +import './Post.css'; + +export default function Post({title,author,subreddit,ups,comments,time,id,media,permalink,selftext,video}) { + const limit = 300; + const [body, setBody] = useState(selftext); + + useEffect(() => { + if (selftext.length > limit) { + setBody(selftext.substring(0,limit) + '...'); + } else { + return; + } + }) + + return ( + <> +
+ {title ? title : 'title'} + {media ? {title} : ''} + {video ? : ''} +

{body}

+
+

{author ? 'u/' + author : 'u/username'}

+

{time ? time : ''}

+

{comments ? comments : 'comments'}

+
+
+ + ); +} \ No newline at end of file diff --git a/src/features/posts/postsSlice.js b/src/features/posts/postsSlice.js index 9413cee..7c491a8 100644 --- a/src/features/posts/postsSlice.js +++ b/src/features/posts/postsSlice.js @@ -1,7 +1,7 @@ import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"; export const fetchBySub = createAsyncThunk( - 'reddit/fetchBySub', + 'posts/fetchBySub', async(subreddit) => { // expects an argument corresponding to the url, in json format, of a given subreddit try { const myRequest = new Request(subreddit); // initializes request @@ -25,7 +25,10 @@ export const postsSlice = createSlice({ reducers: { filterPosts(state,action) { // Expects action.payload to be the searchterm imported from the state of searchBar state.posts.filter(post => (post.data.title !== action.payload) && (post.data.selftext !== action.payload)); - } + }, + updatePosts(state,action) { + state.posts = action.payload; + }, }, extraReducers: (builder) => { builder.addCase(fetchBySub.pending, (state,action) => { @@ -47,4 +50,6 @@ export const postsSlice = createSlice({ }); export default postsSlice.reducer; -export const { filterPosts } = postsSlice.actions; \ No newline at end of file +export const selectPosts = state => state.postsSlice.posts; +export const { filterPosts, updatePosts } = postsSlice.actions; +// exports also includes fetchBySub (takes argument of a sub) \ No newline at end of file diff --git a/src/features/reddit/redditSlice.js b/src/features/reddit/redditSlice.js index ae2524f..537677d 100644 --- a/src/features/reddit/redditSlice.js +++ b/src/features/reddit/redditSlice.js @@ -73,4 +73,5 @@ export const redditSlice = createSlice({ }); export default redditSlice.reducer; +export const selectAllSubs = state => state.redditSlice.subreddits; export const { updateSubVisibility } = redditSlice.actions; \ No newline at end of file diff --git a/src/features/searchBar/searchBar.js b/src/features/searchBar/searchBar.js index e69de29..81d497a 100644 --- a/src/features/searchBar/searchBar.js +++ b/src/features/searchBar/searchBar.js @@ -0,0 +1,24 @@ +import React, { useState, useEffect } from "react"; + +export default function SearchBar() { + const [term, setTerm] = useState(''); + + const handleChange = (e) => { + e.preventDefault(); + setTerm(e.target.value); + } + + useEffect(() => { + if (term) { + // dispatch an action which filters content by {term} + } else { + return; + } + }, [term]) + + return ( + <> + + + ); +} \ No newline at end of file diff --git a/src/features/sidebar/Sidebar.js b/src/features/sidebar/Sidebar.js index e69de29..37aca36 100644 --- a/src/features/sidebar/Sidebar.js +++ b/src/features/sidebar/Sidebar.js @@ -0,0 +1,12 @@ +import React from "react"; + +export default function Sidebar({isCollapsed}) { + return ( +
+

Hard coded subreddit

+

Hard coded subreddit

+

Hard coded subreddit

+

Hard coded subreddit

+
+ ); +} \ No newline at end of file