diff --git a/src/App.css b/src/App.css
index 01cc586..5730ebf 100644
--- a/src/App.css
+++ b/src/App.css
@@ -1,39 +1,12 @@
.App {
text-align: center;
+ margin: 0;
+ padding: 0;
}
-.App-logo {
- height: 40vmin;
- pointer-events: none;
-}
-
-@media (prefers-reduced-motion: no-preference) {
- .App-logo {
- animation: App-logo-float infinite 3s ease-in-out;
- }
-}
-
-.App-header {
- min-height: 100vh;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- font-size: calc(10px + 2vmin);
-}
-
-.App-link {
- color: rgb(112, 76, 182);
-}
-
-@keyframes App-logo-float {
- 0% {
- transform: translateY(0);
- }
- 50% {
- transform: translateY(10px);
- }
- 100% {
- transform: translateY(0px);
- }
-}
+.navbar {
+ display: inline-flex;
+ flex-direction: row;
+ justify-content: space-between;
+ align-items: baseline;
+}
\ No newline at end of file
diff --git a/src/App.js b/src/App.js
index a40f66d..99c00b2 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,58 +1,15 @@
import React from 'react';
-import logo from './logo.svg';
-import { Counter } from './features/counter/Counter';
import './App.css';
+import Navbar from './features/navbar/Navbar';
+import redditSlice from './features/reddit/redditSlice';
function App() {
return (
);
}
-export default App;
+export default App;
\ No newline at end of file
diff --git a/src/App.test.js b/src/App.test.js
index 659cc13..f6847b2 100644
--- a/src/App.test.js
+++ b/src/App.test.js
@@ -4,12 +4,16 @@ import { Provider } from 'react-redux';
import { store } from './app/store';
import App from './App';
-test('renders learn react link', () => {
+test('renders text', () => {
const { getByText } = render(
);
- expect(getByText(/learn/i)).toBeInTheDocument();
+ expect(getByText(/Stuff/)).toBeInTheDocument();
});
+
+test('store is not empty or falsy', () => {
+ expect(store).not.toBeNull();
+})
\ No newline at end of file
diff --git a/src/app/store.js b/src/app/store.js
index 9eca6d2..382977d 100644
--- a/src/app/store.js
+++ b/src/app/store.js
@@ -1,8 +1,10 @@
import { configureStore } from '@reduxjs/toolkit';
-import counterReducer from '../features/counter/counterSlice';
+import postsSlice from '../features/posts/postsSlice';
+import redditSlice from '../features/reddit/redditSlice';
export const store = configureStore({
reducer: {
- counter: counterReducer,
+ redditSlice: redditSlice,
+ postsSlice: postsSlice,
},
});
diff --git a/src/features/counter/Counter.js b/src/features/counter/Counter.js
deleted file mode 100644
index 772a6ba..0000000
--- a/src/features/counter/Counter.js
+++ /dev/null
@@ -1,67 +0,0 @@
-import React, { useState } from 'react';
-import { useSelector, useDispatch } from 'react-redux';
-import {
- decrement,
- increment,
- incrementByAmount,
- incrementAsync,
- incrementIfOdd,
- selectCount,
-} from './counterSlice';
-import styles from './Counter.module.css';
-
-export function Counter() {
- const count = useSelector(selectCount);
- const dispatch = useDispatch();
- const [incrementAmount, setIncrementAmount] = useState('2');
-
- const incrementValue = Number(incrementAmount) || 0;
-
- return (
-
-
-
- {count}
-
-
-
- setIncrementAmount(e.target.value)}
- />
-
-
-
-
-
- );
-}
diff --git a/src/features/counter/Counter.module.css b/src/features/counter/Counter.module.css
deleted file mode 100644
index 004ae33..0000000
--- a/src/features/counter/Counter.module.css
+++ /dev/null
@@ -1,78 +0,0 @@
-.row {
- display: flex;
- align-items: center;
- justify-content: center;
-}
-
-.row > button {
- margin-left: 4px;
- margin-right: 8px;
-}
-.row:not(:last-child) {
- margin-bottom: 16px;
-}
-
-.value {
- font-size: 78px;
- padding-left: 16px;
- padding-right: 16px;
- margin-top: 2px;
- font-family: 'Courier New', Courier, monospace;
-}
-
-.button {
- appearance: none;
- background: none;
- font-size: 32px;
- padding-left: 12px;
- padding-right: 12px;
- outline: none;
- border: 2px solid transparent;
- color: rgb(112, 76, 182);
- padding-bottom: 4px;
- cursor: pointer;
- background-color: rgba(112, 76, 182, 0.1);
- border-radius: 2px;
- transition: all 0.15s;
-}
-
-.textbox {
- font-size: 32px;
- padding: 2px;
- width: 64px;
- text-align: center;
- margin-right: 4px;
-}
-
-.button:hover,
-.button:focus {
- border: 2px solid rgba(112, 76, 182, 0.4);
-}
-
-.button:active {
- background-color: rgba(112, 76, 182, 0.2);
-}
-
-.asyncButton {
- composes: button;
- position: relative;
-}
-
-.asyncButton:after {
- content: '';
- background-color: rgba(112, 76, 182, 0.15);
- display: block;
- position: absolute;
- width: 100%;
- height: 100%;
- left: 0;
- top: 0;
- opacity: 0;
- transition: width 1s linear, opacity 0.5s ease 1s;
-}
-
-.asyncButton:active:after {
- width: 0%;
- opacity: 1;
- transition: 0s;
-}
diff --git a/src/features/counter/counterAPI.js b/src/features/counter/counterAPI.js
deleted file mode 100644
index cc9b4a4..0000000
--- a/src/features/counter/counterAPI.js
+++ /dev/null
@@ -1,6 +0,0 @@
-// A mock function to mimic making an async request for data
-export function fetchCount(amount = 1) {
- return new Promise((resolve) =>
- setTimeout(() => resolve({ data: amount }), 500)
- );
-}
diff --git a/src/features/counter/counterSlice.js b/src/features/counter/counterSlice.js
deleted file mode 100644
index 8dc4b5c..0000000
--- a/src/features/counter/counterSlice.js
+++ /dev/null
@@ -1,73 +0,0 @@
-import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
-import { fetchCount } from './counterAPI';
-
-const initialState = {
- value: 0,
- status: 'idle',
-};
-
-// The function below is called a thunk and allows us to perform async logic. It
-// can be dispatched like a regular action: `dispatch(incrementAsync(10))`. This
-// will call the thunk with the `dispatch` function as the first argument. Async
-// code can then be executed and other actions can be dispatched. Thunks are
-// typically used to make async requests.
-export const incrementAsync = createAsyncThunk(
- 'counter/fetchCount',
- async (amount) => {
- const response = await fetchCount(amount);
- // The value we return becomes the `fulfilled` action payload
- return response.data;
- }
-);
-
-export const counterSlice = createSlice({
- name: 'counter',
- initialState,
- // The `reducers` field lets us define reducers and generate associated actions
- reducers: {
- increment: (state) => {
- // Redux Toolkit allows us to write "mutating" logic in reducers. It
- // doesn't actually mutate the state because it uses the Immer library,
- // which detects changes to a "draft state" and produces a brand new
- // immutable state based off those changes
- state.value += 1;
- },
- decrement: (state) => {
- state.value -= 1;
- },
- // Use the PayloadAction type to declare the contents of `action.payload`
- incrementByAmount: (state, action) => {
- state.value += action.payload;
- },
- },
- // The `extraReducers` field lets the slice handle actions defined elsewhere,
- // including actions generated by createAsyncThunk or in other slices.
- extraReducers: (builder) => {
- builder
- .addCase(incrementAsync.pending, (state) => {
- state.status = 'loading';
- })
- .addCase(incrementAsync.fulfilled, (state, action) => {
- state.status = 'idle';
- state.value += action.payload;
- });
- },
-});
-
-export const { increment, decrement, incrementByAmount } = counterSlice.actions;
-
-// The function below is called a selector and allows us to select a value from
-// the state. Selectors can also be defined inline where they're used instead of
-// in the slice file. For example: `useSelector((state: RootState) => state.counter.value)`
-export const selectCount = (state) => state.counter.value;
-
-// We can also write thunks by hand, which may contain both sync and async logic.
-// Here's an example of conditionally dispatching actions based on current state.
-export const incrementIfOdd = (amount) => (dispatch, getState) => {
- const currentValue = selectCount(getState());
- if (currentValue % 2 === 1) {
- dispatch(incrementByAmount(amount));
- }
-};
-
-export default counterSlice.reducer;
diff --git a/src/features/counter/counterSlice.spec.js b/src/features/counter/counterSlice.spec.js
deleted file mode 100644
index c1fed2c..0000000
--- a/src/features/counter/counterSlice.spec.js
+++ /dev/null
@@ -1,33 +0,0 @@
-import counterReducer, {
- increment,
- decrement,
- incrementByAmount,
-} from './counterSlice';
-
-describe('counter reducer', () => {
- const initialState = {
- value: 3,
- status: 'idle',
- };
- it('should handle initial state', () => {
- expect(counterReducer(undefined, { type: 'unknown' })).toEqual({
- value: 0,
- status: 'idle',
- });
- });
-
- it('should handle increment', () => {
- const actual = counterReducer(initialState, increment());
- expect(actual.value).toEqual(4);
- });
-
- it('should handle decrement', () => {
- const actual = counterReducer(initialState, decrement());
- expect(actual.value).toEqual(2);
- });
-
- it('should handle incrementByAmount', () => {
- const actual = counterReducer(initialState, incrementByAmount(2));
- expect(actual.value).toEqual(5);
- });
-});
diff --git a/src/features/navbar/Navbar.js b/src/features/navbar/Navbar.js
new file mode 100644
index 0000000..2990440
--- /dev/null
+++ b/src/features/navbar/Navbar.js
@@ -0,0 +1,11 @@
+import React from "react";
+
+export default function Navbar() {
+ 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/Post.js b/src/features/posts/Post.js
new file mode 100644
index 0000000..e69de29
diff --git a/src/features/posts/postsSlice.js b/src/features/posts/postsSlice.js
new file mode 100644
index 0000000..9413cee
--- /dev/null
+++ b/src/features/posts/postsSlice.js
@@ -0,0 +1,50 @@
+import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
+
+export const fetchBySub = createAsyncThunk(
+ 'reddit/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
+ let response = await fetch(myRequest);
+ let json = await response.json();
+ let postsArray = json.data.children; // unpacks individual post objects from the subreddit JSON file, as an array
+ return postsArray;
+ } catch(e) {
+ console.log(e);
+ }
+ }
+);
+
+export const postsSlice = createSlice({
+ name: 'posts',
+ initialState: {
+ posts: [],
+ requestsPending: false,
+ requestDenied: false,
+ },
+ 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));
+ }
+ },
+ extraReducers: (builder) => {
+ builder.addCase(fetchBySub.pending, (state,action) => {
+ state.requestsPending = true;
+ state.requestDenied = false;
+ })
+ builder.addCase(fetchBySub.rejected, (state,action) => {
+ state.requestsPending = false;
+ state.requestDenied = true;
+ })
+ builder.addCase(fetchBySub.fulfilled, (state,action) => {
+ state.requestsPending = false;
+ state.requestDenied = false;
+ for (let sub in action.payload) { // iterates over postsArray to avoid
+ state.posts.push(sub); // nesting arrays within the state's posts
+ }
+ })
+ }
+});
+
+export default postsSlice.reducer;
+export const { filterPosts } = postsSlice.actions;
\ No newline at end of file
diff --git a/src/features/reddit/redditSlice.js b/src/features/reddit/redditSlice.js
new file mode 100644
index 0000000..ae2524f
--- /dev/null
+++ b/src/features/reddit/redditSlice.js
@@ -0,0 +1,76 @@
+import { createSlice } from "@reduxjs/toolkit";
+
+const urlBase = 'https://www.reddit.com/';
+
+export const redditSlice = createSlice({
+ name: 'redditSlice',
+ initialState: {
+ subreddits: {
+ 'r/cats': {
+ name: 'r/cats',
+ access: `${urlBase}r/cats.json`,
+ isSelected: true
+ },
+ 'r/IllegallySmolCats': {
+ name: 'r/IllegallySmolCats',
+ access: `${urlBase}r/IllegallySmolCats.json`,
+ isSelected: true
+ },
+ 'r/Catswhoyell': {
+ name: 'r/Catswhoyell',
+ access: `${urlBase}r/Catswhoyell.json`,
+ isSelected: true
+ },
+ 'r/ActivationSound': {
+ name: 'r/ActivationSound',
+ access: `${urlBase}r/ActivationSound.json`,
+ isSelected: true,
+ },
+ 'r/CatSlaps': {
+ name: 'r/CatSlaps',
+ access: `${urlBase}r/CatSlaps.json`,
+ isSelected: true
+ },
+ 'r/CatTaps': {
+ name: 'r/CatTaps',
+ access: `${urlBase}r/CatTaps.json`,
+ isSelected: true
+ },
+ 'r/catsinboxes': {
+ name: 'r/catsinboxes',
+ access: `${urlBase}r/catsinboxes.json`,
+ isSelected: true,
+ },
+ 'r/Thisismylifemeow': {
+ name: 'r/Thisismylifemeow',
+ access: `${urlBase}r/Thisismylifemeow.json`,
+ isSelected: true
+ },
+ 'r/scrungycats': {
+ name: 'r/scrungycats',
+ access: `${urlBase}r/scrungycats.json`,
+ isSelected: true,
+ },
+ 'r/notmycat': {
+ name: 'r/notmycat',
+ access: `${urlBase}r/notmycat.json`,
+ isSelected: true,
+ },
+ 'r/StartledCats': {
+ name: 'r/StartledCats',
+ access: `${urlBase}r/StartledCats.json`,
+ isSelected: true
+ }
+ },
+ },
+ reducers: {
+ updateSubVisibility(state,action) {
+ // reads state of buttons in Sidebar component to determine whether each is active
+ // connects with post rendering, filtering out posts belonging to inactive subreddits
+ }
+ },
+ extraReducers: {},
+});
+
+export default redditSlice.reducer;
+export const { updateSubVisibility } = redditSlice.actions;
\ No newline at end of file
diff --git a/src/features/reddit/redditSlice.test.js b/src/features/reddit/redditSlice.test.js
new file mode 100644
index 0000000..e69de29
diff --git a/src/features/searchBar/searchBar.js b/src/features/searchBar/searchBar.js
new file mode 100644
index 0000000..e69de29
diff --git a/src/features/sidebar/Sidebar.js b/src/features/sidebar/Sidebar.js
new file mode 100644
index 0000000..e69de29