Compare commits
3 Commits
1dc07f39e5
...
75f98755b7
Author | SHA1 | Date | |
---|---|---|---|
75f98755b7 | |||
00fcac1145 | |||
83a42fd660 |
@ -1,6 +1,7 @@
|
||||
import { configureStore } from "@reduxjs/toolkit";
|
||||
import postsReducer from "../features/posts/postsSlice";
|
||||
import usersReducer from "../features/users/usersSlice";
|
||||
|
||||
export const store = configureStore({
|
||||
reducer: { posts: postsReducer },
|
||||
reducer: { posts: postsReducer, users: usersReducer },
|
||||
});
|
||||
|
@ -1,23 +1,38 @@
|
||||
import { useState } from "react";
|
||||
import { postAdded } from "./postsSlice";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
|
||||
import { selectAllUsers } from "../users/usersSlice";
|
||||
|
||||
const AddPostForm = () => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const [title, setTitle] = useState(""); // Temporary state for adding information in form
|
||||
const [content, setContent] = useState("");
|
||||
const dispatch = useDispatch();
|
||||
const [userId, setUserId] = useState("");
|
||||
|
||||
const users = useSelector(selectAllUsers); // get users from Redux store
|
||||
|
||||
const onTitleChanged = (e) => setTitle(e.target.value);
|
||||
const onContentChanged = (e) => setContent(e.target.value);
|
||||
const onAuthorChanged = (e) => setUserId(e.target.value);
|
||||
|
||||
const onSavePostClicked = () => {
|
||||
if (title && content) {
|
||||
dispatch(postAdded(title, content));
|
||||
dispatch(postAdded(title, content, userId));
|
||||
setTitle("");
|
||||
setContent("");
|
||||
}
|
||||
};
|
||||
|
||||
const canSave = Boolean(title) && Boolean(content) && Boolean(userId);
|
||||
|
||||
const usersOptions = users.map((user) => (
|
||||
<option key={user.id} value={user.id}>
|
||||
{user.name}
|
||||
</option>
|
||||
));
|
||||
|
||||
return (
|
||||
<section>
|
||||
<h2>Add a New Post</h2>
|
||||
@ -30,6 +45,11 @@ const AddPostForm = () => {
|
||||
value={title}
|
||||
onChange={onTitleChanged}
|
||||
/>
|
||||
<label htmlFor="postAuthor">Author:</label>
|
||||
<select id="postAuthor" value={userId} onChange={onAuthorChanged}>
|
||||
<option value=""></option>
|
||||
{usersOptions}
|
||||
</select>
|
||||
<label htmlFor="postContent">Content:</label>
|
||||
<textarea
|
||||
id="postContent"
|
||||
@ -37,7 +57,7 @@ const AddPostForm = () => {
|
||||
value={content}
|
||||
onChange={onContentChanged}
|
||||
/>
|
||||
<button type="button" onClick={onSavePostClicked}>
|
||||
<button type="button" onClick={onSavePostClicked} disabled={!canSave}>
|
||||
Save Post
|
||||
</button>
|
||||
</form>
|
||||
|
10
02_lesson_starter/src/features/posts/PostAuthor.js
Normal file
10
02_lesson_starter/src/features/posts/PostAuthor.js
Normal file
@ -0,0 +1,10 @@
|
||||
import { useSelector } from "react-redux";
|
||||
import { selectAllUsers } from "../users/usersSlice";
|
||||
|
||||
const PostAuthor = ({ userId }) => {
|
||||
const users = useSelector(selectAllUsers);
|
||||
const author = users.find((user) => user.id === userId);
|
||||
return <span>by {author ? author.name : "Unknown author"}</span>;
|
||||
};
|
||||
|
||||
export default PostAuthor;
|
@ -1,5 +1,6 @@
|
||||
import { useSelector } from "react-redux";
|
||||
import { selectAllPosts } from "./postsSlice";
|
||||
import PostAuthor from "./PostAuthor";
|
||||
|
||||
const PostsList = () => {
|
||||
const posts = useSelector(selectAllPosts);
|
||||
@ -8,6 +9,9 @@ const PostsList = () => {
|
||||
<article key={post.id}>
|
||||
<h3>{post.title}</h3>
|
||||
<p>{post.content.substring(0, 100)}</p>
|
||||
<p className="postCredit">
|
||||
<PostAuthor userId={post.userId} />
|
||||
</p>
|
||||
</article>
|
||||
));
|
||||
|
||||
|
@ -21,12 +21,14 @@ const postsSlice = createSlice({
|
||||
reducer: (state, action) => {
|
||||
state.push(action.payload);
|
||||
},
|
||||
prepare(title, content) {
|
||||
prepare(title, content, userId) {
|
||||
// adding new post also need userid (author)
|
||||
return {
|
||||
payload: {
|
||||
id: nanoid(),
|
||||
title,
|
||||
content,
|
||||
userId,
|
||||
},
|
||||
};
|
||||
},
|
||||
|
17
02_lesson_starter/src/features/users/usersSlice.js
Normal file
17
02_lesson_starter/src/features/users/usersSlice.js
Normal file
@ -0,0 +1,17 @@
|
||||
import { createSlice } from "@reduxjs/toolkit";
|
||||
const initialState = [
|
||||
{ id: "0", name: "Dude Lebowski" },
|
||||
{ id: "1", name: "Neil Young" },
|
||||
{ id: "2", name: "Dave Gray" },
|
||||
];
|
||||
|
||||
const usersSlice = createSlice({
|
||||
name: "users",
|
||||
initialState,
|
||||
reducers: {},
|
||||
});
|
||||
|
||||
// Selectors
|
||||
export const selectAllUsers = (state) => state.users;
|
||||
|
||||
export default usersSlice.reducer;
|
Loading…
x
Reference in New Issue
Block a user