master

parent 1dd2db46
import { FunctionComponent, ReactElement, useState, ChangeEvent, FormEvent } from 'react';
import { AppDispatch, AppState } from '../../store/store';
import { shallowEqual, useDispatch } from 'react-redux';
import {
FunctionComponent,
ReactElement,
useState,
ChangeEvent,
FormEvent,
} from 'react';
import {AppDispatch, AppState} from '../../store/store';
import {shallowEqual, useDispatch} from 'react-redux';
import IPostDto from '../../interfaces/IPostDto';
import { createPost } from '../../store/posts/posts.slice';
import { useSelector } from 'react-redux';
import {createPost} from '../../store/posts/posts.slice';
import {useSelector} from 'react-redux';
const CreatePost: FunctionComponent = (): ReactElement => {
const { user } = useSelector((state: AppState) => state.user,shallowEqual);
const dispatch: AppDispatch = useDispatch()
const {user} = useSelector((state: AppState) => state.user, shallowEqual);
const dispatch: AppDispatch = useDispatch();
const [post, setPost] = useState<IPostDto>({
title: '',
description: '',
image: undefined
})
const [post, setPost] = useState<IPostDto>({
title: '',
description: '',
image: undefined,
});
const [fileName, setFileName] = useState<string>('')
const [fileName, setFileName] = useState<string>('');
const inputHandler = (e: ChangeEvent<HTMLInputElement>): void => {
setPost(prevState => {
return { ...prevState, [e.target.name]: e.target.value }
})
}
const inputHandler = (e: ChangeEvent<HTMLInputElement>): void => {
setPost((prevState) => {
return {...prevState, [e.target.name]: e.target.value};
});
};
const inputFileHandler = (e: ChangeEvent<HTMLInputElement>): void => {
setPost(prevState => {
return {
...prevState,
image: e.target.files ? e.target.files[0] : undefined
}
})
setFileName(e.target.files && e.target.files[0] ? e.target.files[0].name : '')
}
const submitHandler = (e: FormEvent) => {
e.preventDefault()
const inputFileHandler = (e: ChangeEvent<HTMLInputElement>): void => {
setPost((prevState) => {
return {
...prevState,
image: e.target.files ? e.target.files[0] : undefined,
};
});
setFileName(
e.target.files && e.target.files[0] ? e.target.files[0].name : ''
);
};
const submitHandler = (e: FormEvent) => {
e.preventDefault();
const formData = new FormData();
formData.append('title', post.title);
formData.append('description', post.description);
formData.append('user', user._id);
dispatch(createPost(formData));
setPost(post);
};
return (
<div className="bg-gray-100 p-4">
<form
onSubmit={submitHandler}
className="flex gap-4 flex-col items-center"
>
<input
name="title"
type="text"
placeholder="Title"
value={post.title}
onChange={inputHandler}
className="border border-gray-400 rounded-md px-3 py-2 focus:outline-none focus:border-blue-400 flex-grow"
/>
const formData = new FormData();
Object.keys(post).forEach((key: any) => {
//@ts-ignore
formData.append(key, post[key])
})
formData.append("user", user._id)
<input
name="description"
type="text"
placeholder="Description"
value={post.description}
onChange={inputHandler}
className="border border-gray-400 rounded-md px-3 py-2 focus:outline-none focus:border-blue-400 flex-grow"
/>
dispatch(createPost(formData))
setPost(post)
}
return (
<div className="bg-gray-100 p-4">
<form onSubmit={submitHandler} className="flex gap-4 flex-col items-center">
<input
name="title"
type="text"
placeholder="Title"
value={post.title}
onChange={inputHandler}
className="border border-gray-400 rounded-md px-3 py-2 focus:outline-none focus:border-blue-400 flex-grow"
/>
<label className="relative flex items-center justify-center bg-white border border-gray-400 rounded-md px-4 py-2 cursor-pointer">
<input
type="file"
name="image"
onChange={inputFileHandler}
className="hidden"
/>
<span className="text-gray-500 font-medium mr-2">CHOOSE FILE</span>
<span className="text-gray-500 font-medium">{fileName}</span>
</label>
<input
name="description"
type="text"
placeholder="Description"
value={post.description}
onChange={inputHandler}
className="border border-gray-400 rounded-md px-3 py-2 focus:outline-none focus:border-blue-400 flex-grow"
/>
<button className="bg-blue-500 hover:bg-blue-600 text-white py-2 px-4 rounded-md">
SEND
</button>
</form>
</div>
);
};
<label className="relative flex items-center justify-center bg-white border border-gray-400 rounded-md px-4 py-2 cursor-pointer">
<input
type="file"
name="image"
onChange={inputFileHandler}
className="hidden"
/>
<span className="text-gray-500 font-medium mr-2">CHOOSE FILE</span>
<span className="text-gray-500 font-medium">{fileName}</span>
</label>
<button className="bg-blue-500 hover:bg-blue-600 text-white py-2 px-4 rounded-md">
SEND
</button>
</form>
</div>
)
}
export default CreatePost
export default CreatePost;
import {createAsyncThunk, createSlice} from '@reduxjs/toolkit';
import IPost from '../../interfaces/IPost'
import { postApi } from '../../api/postApi'
import IResponse from '../../interfaces/IResponse'
import IPost from '../../interfaces/IPost';
import {postApi} from '../../api/postApi';
import IResponse from '../../interfaces/IResponse';
interface IPostState {
posts: IPost[]
post: IPost
loadingPosts: boolean
messagePosts: string
posts: IPost[];
post: IPost;
loadingPosts: boolean;
messagePosts: string;
}
const initialState:IPostState = {
posts: [] as IPost[],
post: {} as IPost,
loadingPosts: false,
messagePosts: ''
}
const namespace = 'posts'
const initialState: IPostState = {
posts: [] as IPost[],
post: {} as IPost,
loadingPosts: false,
messagePosts: '',
};
const namespace = 'posts';
export const getPosts = createAsyncThunk(
`${namespace}/getPosts`,
async (): Promise<IResponse<IPost[] | undefined>> => {
return postApi.getPosts()
}
)
`${namespace}/getPosts`,
async (): Promise<IResponse<IPost[] | undefined>> => {
return await postApi.getPosts();
}
);
export const getPostById = createAsyncThunk(
`${namespace}/getPostById`,
async (id: string): Promise<IResponse<IPost | undefined>> => {
return postApi.getPostById(id)
}
)
`${namespace}/getPostById`,
async (id: string): Promise<IResponse<IPost | undefined>> => {
return await postApi.getPostById(id);
}
);
export const createPost = createAsyncThunk(
`${namespace}/createPost`,
async (post: FormData) => {
return postApi.createPost(post)
}
)
`${namespace}/createPost`,
async (post: FormData) => {
return await postApi.createPost(post);
}
);
export const deletePostById = createAsyncThunk(
`${namespace}/deletePostById`,
async (id: string) => {
return postApi.deletePostById(id)
}
)
`${namespace}/deletePostById`,
async (id: string) => {
return await postApi.deletePostById(id);
}
);
export const postsSlice = createSlice({
name: namespace,
initialState,
reducers: {},
extraReducers: (builder) => {
builder
.addCase(getPosts.rejected, (state) => {
state.loadingPosts = false
})
.addCase(getPosts.pending, (state) => {
state.loadingPosts = true
})
.addCase(getPosts.fulfilled, (state, action) => {
state.loadingPosts = false
state.posts = action.payload.result as IPost[]
state.messagePosts = action.payload.message
})
.addCase(getPostById.rejected, (state) => {
state.loadingPosts = false
})
.addCase(getPostById.pending, (state) => {
state.loadingPosts = true
})
.addCase(getPostById.fulfilled, (state, action) => {
state.loadingPosts = false
state.post = action.payload.result as IPost
state.messagePosts = action.payload.message
})
.addCase(createPost.rejected, (state) => {
state.loadingPosts = false
})
.addCase(createPost.pending, (state) => {
state.loadingPosts = true
})
.addCase(createPost.fulfilled, (state, action) => {
state.loadingPosts = false
state.messagePosts = action.payload.message
})
.addCase(deletePostById.rejected, (state) => {
state.loadingPosts = false
})
.addCase(deletePostById.pending, (state) => {
state.loadingPosts = true
})
.addCase(deletePostById.fulfilled, (state, action) => {
state.loadingPosts = false
state.messagePosts = action.payload.message
})
}
})
name: namespace,
initialState,
reducers: {},
extraReducers: (builder) => {
builder
.addCase(getPosts.rejected, (state) => {
state.loadingPosts = false;
})
.addCase(getPosts.pending, (state) => {
state.loadingPosts = true;
})
.addCase(getPosts.fulfilled, (state, action) => {
state.loadingPosts = false;
state.posts = action.payload.result as IPost[];
state.messagePosts = action.payload.message;
})
.addCase(getPostById.rejected, (state) => {
state.loadingPosts = false;
})
.addCase(getPostById.pending, (state) => {
state.loadingPosts = true;
})
.addCase(getPostById.fulfilled, (state, action) => {
state.loadingPosts = false;
state.post = action.payload.result as IPost;
state.messagePosts = action.payload.message;
})
.addCase(createPost.rejected, (state) => {
state.loadingPosts = false;
})
.addCase(createPost.pending, (state) => {
state.loadingPosts = true;
})
.addCase(createPost.fulfilled, (state, action) => {
state.loadingPosts = false;
state.messagePosts = action.payload.message;
console.log(action.payload);
})
.addCase(deletePostById.rejected, (state) => {
state.loadingPosts = false;
})
.addCase(deletePostById.pending, (state) => {
state.loadingPosts = true;
})
.addCase(deletePostById.fulfilled, (state, action) => {
state.loadingPosts = false;
state.messagePosts = action.payload.message;
});
},
});
export default postsSlice.reducer;
\ No newline at end of file
export default postsSlice.reducer;
......@@ -104,6 +104,7 @@ export const userSlice = createSlice({
state.user.username = action.payload[0].username;
state.loading = false;
state.userLoggedIn = true;
state.user._id = action.payload[0]._id;
});
},
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment