-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #19 from HackYourFuture/customer-review
Customer review
- Loading branch information
Showing
5 changed files
with
230 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import React, { useState } from 'react' | ||
import axios from 'axios'; | ||
import { Button, Comment, Form, Header, Message } from 'semantic-ui-react'; | ||
import formatDate from '../../utils/formatDate'; | ||
import catchErrors from '../../utils/catchErrors'; | ||
import baseUrl from '../../utils/baseUrl'; | ||
import cookie from 'js-cookie'; | ||
import { useRouter } from 'next/router'; | ||
|
||
export default function AddCommentToProduct({ user, product, handleNewComment }) { | ||
const [comment, setComment] = useState(''); | ||
const [loading, setLoading] = useState(false); | ||
const [success, setSuccess] = useState(false); | ||
const [error, setError] = React.useState(""); | ||
|
||
const router = useRouter(); | ||
|
||
function handleChange(event) { | ||
const { value } = event.target; | ||
setComment(value); | ||
} | ||
|
||
async function handleSubmit(event) { | ||
event.preventDefault(); | ||
if (!user) { | ||
router.push('/login'); | ||
return; | ||
} | ||
|
||
try { | ||
setLoading(true); | ||
setError(""); | ||
const url = `${baseUrl}/api/product`; | ||
const token = cookie.get('token'); | ||
const payload = { comment, productId: product._id }; | ||
const headers = { Authorization: token }; | ||
const response = await axios.put(url, payload, { headers }); | ||
// { totalComments, product } | ||
setComment(''); | ||
handleNewComment(response.data); | ||
setSuccess(true); | ||
} catch (error) { | ||
catchErrors(error, setError); | ||
setSuccess(false); | ||
} finally { | ||
setLoading(false); | ||
} | ||
} | ||
|
||
return ( | ||
<> | ||
<Comment.Group minimal> | ||
<Form reply onSubmit={handleSubmit} loading={loading} error={Boolean(error)} success={success}> | ||
<Message error header="Oops!" content={error} /> | ||
<Message success header="Success" content="Thank you for your precious comment!" /> | ||
<Form.TextArea name="content" onChange={handleChange} value={comment} /> | ||
{ | ||
user ? | ||
<Button type="submit" content='Add Comment' labelPosition='left' icon='edit' primary disabled={loading || !comment.trim()} /> | ||
: | ||
<Button color='orange' content="Login to Add Comments" icon='sign in' onClick={() => router.push('/login')} /> | ||
} | ||
|
||
</Form> | ||
{ | ||
product.comments && product.comments.length > 0 && | ||
<> | ||
<Header as='h3' dividing> | ||
Comments | ||
</Header> | ||
{ | ||
product.comments.map(comment => ( | ||
<Comment key={`comment_id ${comment._id}`}> | ||
<Comment.Content> | ||
<Comment.Author as='span'>{comment.user.name}</Comment.Author> | ||
<Comment.Metadata> | ||
<span>{formatDate(comment.updated_at)}</span> | ||
</Comment.Metadata> | ||
<Comment.Text>{comment.content}</Comment.Text> | ||
</Comment.Content> | ||
</Comment> | ||
)) | ||
} | ||
</> | ||
} | ||
</Comment.Group> | ||
</> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { useRouter } from "next/router"; | ||
import { Container, Pagination } from "semantic-ui-react"; | ||
import { redirectUser } from '../../utils/auth' | ||
|
||
function CommentPagination({ productId, totalPages }, ctx) { | ||
const router = useRouter(); | ||
return ( | ||
<Container textAlign="center" style={{ margin: "2em" }}> | ||
<Pagination | ||
defaultActivePage={1} | ||
totalPages={totalPages} | ||
onPageChange={(event, data) => { | ||
data.activePage === 1 | ||
? redirectUser(ctx, `/product?_id=${productId}`) | ||
: redirectUser(ctx, `/product?_id=${productId}&page=${data.activePage}`) | ||
}} | ||
/> | ||
</Container> | ||
); | ||
} | ||
|
||
export default CommentPagination; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,53 @@ | ||
import React, { useEffect, useState } from 'react'; | ||
import axios from 'axios'; | ||
import ProductSummary from '../components/Product/ProductSummary'; | ||
import ProductAttributes from '../components/Product/ProductAttributes'; | ||
import AddCommentToProduct from '../components/Product/AddCommentToProduct'; | ||
import CommentPagination from '../components/Product/CommentPagination'; | ||
import baseUrl from '../utils/baseUrl'; | ||
import { useEffect } from 'react'; | ||
|
||
function Product({ product, user }) { | ||
function Product({ product, user, totalComments }) { | ||
const [displayedProduct, setDisplayedProduct] = useState(product); | ||
const [displayedTotalComments, setDisplayedTotalComments] = useState(totalComments); | ||
|
||
function handleNewComment({ totalComments: newTotalComments, product: newProduct }) { | ||
setDisplayedProduct(newProduct); | ||
setDisplayedTotalComments(newTotalComments); | ||
} | ||
|
||
useEffect(() => { | ||
async function incrementProductView() { | ||
const url = `${baseUrl}/api/view`; | ||
const payload = { productId: product._id }; | ||
await axios.post(url, payload); | ||
} | ||
incrementProductView(); | ||
}, [product]); | ||
|
||
setDisplayedProduct(product); | ||
setDisplayedTotalComments(totalComments); | ||
}, [product, totalComments]); | ||
|
||
return ( | ||
<> | ||
<ProductSummary user={user} {...product} /> | ||
<ProductAttributes user={user} {...product} /> | ||
<ProductSummary user={user} {...displayedProduct} /> | ||
<ProductAttributes user={user} {...displayedProduct} /> | ||
<AddCommentToProduct | ||
user={user} | ||
product={displayedProduct} | ||
handleNewComment={handleNewComment} | ||
/> | ||
{displayedTotalComments > 0 && ( | ||
<CommentPagination productId={product._id} totalPages={displayedTotalComments} /> | ||
)} | ||
</> | ||
); | ||
} | ||
|
||
Product.getInitialProps = async ({ query: { _id } }) => { | ||
Product.getInitialProps = async ({ query: { _id, page } }) => { | ||
const url = `${baseUrl}/api/product`; | ||
const payload = { params: { _id } }; | ||
const payload = { params: { _id, page } }; | ||
const response = await axios.get(url, payload); | ||
return { product: response.data }; | ||
return response.data; | ||
}; | ||
|
||
export default Product; |