Skip to content

Commit

Permalink
Merge pull request #11 from ktvtk/module7-task3
Browse files Browse the repository at this point in the history
  • Loading branch information
keksobot authored Nov 30, 2024
2 parents e3a50ed + 7fb6ec3 commit 34c9812
Show file tree
Hide file tree
Showing 10 changed files with 302 additions and 201 deletions.
2 changes: 1 addition & 1 deletion src/components/private-route/private-route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export function PrivateRouteAuthorized(props: PrivateRouteProps): JSX.Element {
const {children} = props;
const isAuthorized = useAppSelector((state) => state.authorizationStatus) === AuthorizationStatus.Authorized;
return (
isAuthorized
isAuthorized
? children
: <Navigate to={AppRoute.Login} />
);
Expand Down
45 changes: 39 additions & 6 deletions src/components/review-form/review-form.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,55 @@
import React, {JSX} from 'react';
import {useState} from 'react';
import {minCommentLength, maxCommentLength} from '../../const.ts';
import {store} from '../../store';
import {sendReview} from '../../store/api-actions.ts';
import {useAppSelector} from '../../hooks';

export default function ReviewForm(): JSX.Element {
const [formData, setFormData] = useState({
review: '',
rating: 0
});

const offerId = useAppSelector((state) => state.detailOffer)!.id;
const handleSubmit: React.FormEventHandler<HTMLFormElement> = (evt) => {
evt.preventDefault();
store.dispatch(
sendReview({
offerId,
rating: formData.rating,
comment: formData.review,
}),
).then(() => {
setFormData({rating: 0, review: ''});
});
};

const isValid =
formData.review.length >= minCommentLength &&
formData.review.length <= maxCommentLength &&
formData.rating !== null;

const handleFieldChange = (evt: React.ChangeEvent<HTMLInputElement|HTMLTextAreaElement>) => {
const {name, value} = evt.target;
setFormData({...formData, [name]: value});
const handleFieldChange = (evt: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
const { name, value } = evt.target;
setFormData({
...formData,
[name]: name === 'rating' ? Number(value) : value,
});
};

function renderRatingInput(value: number, title: string) {
return (
<>
<input className="form__rating-input visually-hidden" onChange={handleFieldChange} name="rating" value={value} id={`${value}-stars`} type="radio" />
<input
className="form__rating-input visually-hidden"
onChange={handleFieldChange}
name="rating"
value={value}
id={`${value}-stars`}
type="radio"
checked={formData.rating === value}
/>
<label htmlFor={`${value}-stars`} className="reviews__rating-label form__rating-label" title={title}>
<svg className="form__star-image" width="37" height="33">
<use xlinkHref="#icon-star"></use>
Expand All @@ -32,7 +60,7 @@ export default function ReviewForm(): JSX.Element {
}

return (
<form className="reviews__form form" action="#" method="post">
<form className="reviews__form form" onSubmit={handleSubmit}>
<label className="reviews__label form__label" htmlFor="review">Your review</label>
<div className="reviews__rating-form form__rating">
{renderRatingInput(5, 'perfect')}
Expand All @@ -46,7 +74,12 @@ export default function ReviewForm(): JSX.Element {
<p className="reviews__help">
To submit review please make sure to set <span className="reviews__star">rating</span> and describe your stay with at least <b className="reviews__text-amount">{minCommentLength} characters</b>.
</p>
<button className="reviews__submit form__submit button" type="submit" disabled={!isValid}>Submit</button>
<button
className="reviews__submit form__submit button"
type="submit"
disabled={!isValid}
>Submit
</button>
</div>
</form>
);
Expand Down
15 changes: 7 additions & 8 deletions src/pages/login-screen/login-screen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ export function LoginScreen() : JSX.Element {
const submitHandle = (evt: FormEvent) => {
evt.preventDefault();
store.dispatch(login(loginInfo));
console.log(loginInfo)
}
};

return (
<div className="page page--gray page--login">
Expand Down Expand Up @@ -51,9 +50,9 @@ export function LoginScreen() : JSX.Element {
setLoginInfo({
...loginInfo,
email: event.target.value
})
}
required/>
})}
required
/>
</div>
<div className="login__input-wrapper form__input-wrapper">
<label className="visually-hidden">Password</label>
Expand All @@ -66,9 +65,9 @@ export function LoginScreen() : JSX.Element {
setLoginInfo({
...loginInfo,
password: event.target.value
})
}
required/>
})}
required
/>
</div>
<button
className="login__submit form__submit button"
Expand Down
62 changes: 42 additions & 20 deletions src/pages/main-screen/main-screen.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import {JSX} from 'react';
import {JSX, useState} from 'react';
import {Helmet} from 'react-helmet-async';
import {OffersList} from '../../components/offers-list/offers-list.tsx';
import {Link} from 'react-router-dom';
import {AppRoute} from '../../const.ts';
import {useState} from 'react';
import {AppRoute, AuthorizationStatus} from '../../const.ts';
import {Map} from '../../components/map/map.tsx';
import {CitiesList} from '../../components/cities-list/cities-list.tsx';
import {useAppSelector} from '../../hooks';
import {Sorting} from '../../components/sorting/sorting.tsx';
import {SortOption} from '../../types/sort-option.ts';
import {store} from '../../store';
import {logout} from '../../store/api-actions.ts';


export function MainScreen(): JSX.Element {
Expand Down Expand Up @@ -39,6 +40,11 @@ export function MainScreen(): JSX.Element {
setSortingOption(option);
};

const isAuth = useAppSelector((state) => state.authorizationStatus) === AuthorizationStatus.Authorized;

const logoutHandle = () => {
store.dispatch(logout());
};

return (
<div className="page page--gray page--main">
Expand All @@ -53,23 +59,39 @@ export function MainScreen(): JSX.Element {
<img className="header__logo" src="img/logo.svg" alt="6 cities logo" width="81" height="41"/>
</a>
</div>
<nav className="header__nav">
<ul className="header__nav-list">
<li className="header__nav-item user">
<Link className="header__nav-link header__nav-link--profile" to={AppRoute.Favorites}>
<div className="header__avatar-wrapper user__avatar-wrapper">
</div>
<span className="header__user-name user__name">[email protected]</span>
<span className="header__favorite-count">{favoritesCount}</span>
</Link>
</li>
<li className="header__nav-item">
<a className="header__nav-link" href="#">
<span className="header__signout">Sign out</span>
</a>
</li>
</ul>
</nav>
{isAuth ? (
<nav className="header__nav">
<ul className="header__nav-list">
<li className="header__nav-item user">
<Link className="header__nav-link header__nav-link--profile" to={AppRoute.Favorites}>
<div className="header__avatar-wrapper user__avatar-wrapper">
</div>
<span className="header__user-name user__name">[email protected]</span>
<span className="header__favorite-count">{favoritesCount}</span>
</Link>
</li>
<li className="header__nav-item">
<a className="header__nav-link" onClick={logoutHandle}>
<span className="header__signout">Sign out</span>
</a>
</li>
</ul>
</nav>
) : (
<nav className="header__nav">
<ul className="header__nav-list">
<li className="header__nav-item user">
<Link
className="header__nav-link header__nav-link--profile"
to={AppRoute.Login}
>
<div className="header__avatar-wrapper user__avatar-wrapper"></div>
<span className="header__login">Sign in</span>
</Link>
</li>
</ul>
</nav>
)}
</div>
</div>
</header>
Expand Down
Loading

0 comments on commit 34c9812

Please sign in to comment.