Skip to content

Commit

Permalink
Merge pull request #18 from VartoSss/master
Browse files Browse the repository at this point in the history
  • Loading branch information
keksobot authored Jan 12, 2025
2 parents 4502025 + e155373 commit 28ec279
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 97 deletions.
7 changes: 7 additions & 0 deletions src/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ export enum AppRoutes {
}

export const BEST_RATING = 5;
export const RatingDescriptionsList = [
'terribly',
'badly',
'not bad',
'good',
'perfect',
];

export enum APIRoutes {
Offers = '/offers',
Expand Down
6 changes: 3 additions & 3 deletions src/pages/offer-page/offer-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
getSingleOffer,
getSingleOfferDataLoadingStatus,
} from '../../store/single-offer-data-process/single-offer-data-process.selectors';
import CommentForm from './comment-form';
import ReviewForm from './review-form';
import { ReviewList } from './review-list';
import { useEffect } from 'react';
import {
Expand Down Expand Up @@ -81,7 +81,7 @@ function OfferPage(): JSX.Element {
<h1 className="offer__name">{currentOffer.title}</h1>
<button
className={`offer__bookmark-button${
currentOffer.isFavorite ? '--active' : ''
currentOffer.isFavorite ? ' offer__bookmark-button--active' : ''
} button`}
type="button"
onClick={handleBookmarkClick}
Expand Down Expand Up @@ -169,7 +169,7 @@ function OfferPage(): JSX.Element {
</h2>
<ReviewList reviews={reviews} />
{isAuthorized && (
<CommentForm currentOfferId={currentOffer.id} />
<ReviewForm currentOfferId={currentOffer.id} />
)}
</section>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import {
getSingleOfferFormAcceptedStatus,
getSingleOfferReviewPostingStatus,
} from '../../store/single-offer-data-process/single-offer-data-process.selectors';
import { RatingDescriptionsList } from '../../consts';
import React from 'react';

type CommentFormProps = {
type ReviewFormProps = {
currentOfferId: string;
};

function CommentForm({ currentOfferId }: CommentFormProps): JSX.Element {
function ReviewForm({ currentOfferId }: ReviewFormProps): JSX.Element {
const [formState, setFormState] = useState({ rating: 0, review: '' });
const [isFormValid, setIsFormValid] = useState(false);
const isFormAccepted = useAppSelector(getSingleOfferFormAcceptedStatus);
Expand All @@ -32,15 +34,17 @@ function CommentForm({ currentOfferId }: CommentFormProps): JSX.Element {
id: currentOfferId,
})
);
};

useEffect(() => {
if (isFormAccepted) {
setFormState({
review: '',
rating: 0,
});
dispatch(setFormAcceptedStatus(false));
}
};
}, [isFormAccepted, dispatch]);

useEffect(() => {
if (
Expand All @@ -64,91 +68,28 @@ function CommentForm({ currentOfferId }: CommentFormProps): JSX.Element {
Your review
</label>
<div className="reviews__rating-form form__rating">
<input
className="form__rating-input visually-hidden"
name="rating"
id="5-stars"
type="radio"
onChange={handleChange}
value={5}
/>
<label
htmlFor="5-stars"
className="reviews__rating-label form__rating-label"
title="perfect"
>
<svg className="form__star-image" width={37} height={33}>
<use xlinkHref="#icon-star" />
</svg>
</label>
<input
className="form__rating-input visually-hidden"
name="rating"
id="4-stars"
type="radio"
onChange={handleChange}
value={4}
/>
<label
htmlFor="4-stars"
className="reviews__rating-label form__rating-label"
title="good"
>
<svg className="form__star-image" width={37} height={33}>
<use xlinkHref="#icon-star" />
</svg>
</label>
<input
className="form__rating-input visually-hidden"
name="rating"
id="3-stars"
type="radio"
onChange={handleChange}
value={3}
/>
<label
htmlFor="3-stars"
className="reviews__rating-label form__rating-label"
title="not bad"
>
<svg className="form__star-image" width={37} height={33}>
<use xlinkHref="#icon-star" />
</svg>
</label>
<input
className="form__rating-input visually-hidden"
name="rating"
id="2-stars"
type="radio"
onChange={handleChange}
value={2}
/>
<label
htmlFor="2-stars"
className="reviews__rating-label form__rating-label"
title="badly"
>
<svg className="form__star-image" width={37} height={33}>
<use xlinkHref="#icon-star" />
</svg>
</label>
<input
className="form__rating-input visually-hidden"
name="rating"
id="1-star"
type="radio"
onChange={handleChange}
value={1}
/>
<label
htmlFor="1-star"
className="reviews__rating-label form__rating-label"
title="terribly"
>
<svg className="form__star-image" width={37} height={33}>
<use xlinkHref="#icon-star" />
</svg>
</label>
{[5, 4, 3, 2, 1].map((i) => (
<React.Fragment key={i}>
<input
className="form__rating-input visually-hidden"
name="rating"
id={`${i}-stars`}
type="radio"
onChange={handleChange}
value={`${i}`}
checked={formState.rating.toString() === `${i}`}
/>
<label
htmlFor={`${i}-stars`}
className="reviews__rating-label form__rating-label"
title={RatingDescriptionsList[i + 1]}
>
<svg className="form__star-image" width={37} height={33}>
<use xlinkHref="#icon-star" />
</svg>
</label>
</React.Fragment>
))}
</div>
<textarea
className="reviews__textarea form__textarea"
Expand All @@ -167,7 +108,7 @@ function CommentForm({ currentOfferId }: CommentFormProps): JSX.Element {
<button
className="reviews__submit form__submit button"
type="submit"
disabled={!isFormValid}
disabled={!isFormValid || isPosting}
>
Submit
</button>
Expand All @@ -176,4 +117,4 @@ function CommentForm({ currentOfferId }: CommentFormProps): JSX.Element {
);
}

export default CommentForm;
export default ReviewForm;
8 changes: 4 additions & 4 deletions src/store/api-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export const fetchReviewsAction = createAsyncThunk<
});

export const postReviewAction = createAsyncThunk<
void,
ReviewFromPerson,
ReviewData,
{
dispatch: AppDispatch;
Expand All @@ -63,13 +63,13 @@ export const postReviewAction = createAsyncThunk<
}
>(
'review/postReview',
async ({ comment, rating, id }, { dispatch, extra: api }) => {
async ({ comment, rating, id }, { extra: api }) => {
const parsedRating = Number(rating);
await api.post(`${APIRoutes.Comments}/${id}`, {
const response = await api.post(`${APIRoutes.Comments}/${id}`, {
comment,
rating: parsedRating,
});
dispatch(fetchReviewsAction({ offerId: id }));
return response.data as ReviewFromPerson;
}
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
fetchNearbyOffersAction,
fetchReviewsAction,
fetchSingleOfferAction,
postReviewAction,
} from '../api-actions';

const initialState: SingleOfferDataProcess = {
Expand Down Expand Up @@ -96,6 +97,17 @@ export const singleOfferDataProcess = createSlice({
})
.addCase(fetchSingleOfferAction.pending, (state) => {
state.isSingleOfferDataLoading = true;
})
.addCase(postReviewAction.pending, (state) => {
state.isReviewPosting = true;
})
.addCase(postReviewAction.fulfilled, (state, action) => {
state.reviews?.push(action.payload);
state.isReviewPosting = false;
state.isFormAccepted = true;
})
.addCase(postReviewAction.rejected, (state) => {
state.isReviewPosting = false;
});
},
});
Expand Down

0 comments on commit 28ec279

Please sign in to comment.