Last active
July 12, 2020 11:38
-
-
Save liroan/32da9beeee356e332d3da0e0d11752b5 to your computer and use it in GitHub Desktop.
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
class App extends React.Component { | |
componentDidMount() { | |
this.props.startApp() | |
} | |
render() { | |
if (!this.props.isStartApp) | |
return <Preloader/>; | |
return ( | |
<> | |
<BrowserRouter basename={process.env.PUBLIC_URL}> | |
<div className='main-app'> | |
<div className={(this.props.activePageSite === 'MAIN' || this.props.activePageSite === 'LOGIN') ? 'main-window-off' : null}> | |
<Header/> | |
<div className={"main_window " + (this.props.themeIsDark ? "dark-theme" : "")}> | |
<Navbar/> | |
<div onClick={() => this.props.editMenu(false)} className={this.props.isMenuOpen ? 'app-window menu-open' : "app-window"}> | |
<Route path='/profile/:id?' component={ProfileContainer}/> | |
<Route path='/dialogs/:id?' component={DialogsContainer}/> | |
<Route path='/users' component={UsersContainer}/> | |
<Route path='/friends' component={FriendsContainer}/> | |
<Route path='/settings' component={SettingsContainer}/> | |
</div> | |
</div> | |
</div> | |
<Route path='/' component={MainPageContainer} exact={true}/> | |
<Route path='/login' component={Login}/> | |
</div> | |
</BrowserRouter> | |
</> | |
); | |
} | |
} |
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
class DialogsContainer extends React.Component { | |
componentDidMount() { | |
this.props.setActivePageSite("DIALOGS"); | |
} | |
correspondence = (id, exitOnInterlocutors) => { | |
this.props.history.push('/dialogs/' + id); | |
this.props.getMessage(id); | |
this.props.setActiveUser(id); | |
if (window.innerWidth <= 500) { | |
exitOnInterlocutors(true, false) | |
} | |
}; | |
render() { | |
return( | |
<Dialogs correspondence={this.correspondence} usersMessage={this.props.usersMessage} | |
sendMessage={this.props.sendMessage} | |
messages={this.props.messages} | |
activeUser={this.props.activeUser} | |
/> | |
) | |
} | |
} | |
//Dialog | |
const Dialogs = (props) => { | |
let exitOnInterlocutors = (showMessages, showInterlocutors) => { | |
setShowMessages(showMessages); | |
setShowInterlocutors(showInterlocutors) | |
}; | |
let [showMessages, setShowMessages] = useState(window.innerWidth >= 500); | |
let [ShowInterlocutors, setShowInterlocutors] = useState(true); | |
let usersMessage = props.usersMessage.map(user => <DialogsUsers img={user.img} | |
name={user.name} | |
key={user.id} | |
correspondence={props.correspondence} | |
id={user.id} | |
activeUser={props.activeUser} | |
setShowMessages={setShowMessages} | |
exitOnInterlocutors={exitOnInterlocutors}/>); | |
let message = 0; | |
if (props.messages.length !== 0) | |
message = props.messages.map(message => <DialogsMessages key={message.id} id={message.id} text={message.text} sender={message.sender} users={props.usersMessage}/>); | |
let onSubmit = (object) => { | |
props.sendMessage(object.dialog) | |
}; | |
return ( | |
<section className='dialogs main-bg'> | |
<div className="dialogs__bg-header"> | |
<div className="dialogs__header"> | |
<div className='dialogs__title title'> | |
<h1>Ваши сообщения</h1> | |
<h3>Добро пожаловать в ваши сообщения, здесь вы будете видеть смешные, | |
грустные, тупые или прекраснецшие сообщения от ваших друзей(ну или не друзей, как повезет) | |
</h3> | |
</div> | |
<div className="dialogs__subtitle"> | |
<div><img src={cactus} alt=""/></div> | |
<div><img src={coct} alt=""/></div> | |
<div><img src={pk} alt=""/></div> | |
<div><img src={lampa} alt=""/></div> | |
<div><img src={joystick} alt=""/></div> | |
</div> | |
</div> | |
</div> | |
<div className="dialogs__container container side-card"> | |
{ShowInterlocutors ? <li className="dialogs__interlocutors">{usersMessage}</li> : null} | |
{showMessages ? <div className="dialogs__window-messages"> | |
<div className="dialogs__exit"><img src={exit} alt="" onClick={() => exitOnInterlocutors(false, true)}/></div> | |
<div className="dialogs__window-messages-container"> | |
<div className="dialogs__all-messages"> | |
{props.messages.length !== 0 ? message : | |
<div className='dialogs__empty-message'> | |
<div><img src={empty} alt=""/></div> | |
</div> | |
} | |
</div> | |
<FormDialogs onSubmit={onSubmit}/> | |
</div> | |
</div> : null} | |
</div> | |
</section> | |
) | |
}; | |
//Form Dialogs | |
const FormDialogs = (props) => { | |
return( | |
<form onSubmit={props.handleSubmit} className='dialogs__text-form'> | |
<div className="dialogs__form form"><Field component={Textarea} name='dialog'/></div> | |
<div className="dialogs__submit-button submit-button"><button>Отправить</button></div> | |
</form> | |
) | |
}; | |
export default reduxForm({form: "dialogs"})(FormDialogs) | |
//DialogsUser | |
const DialogsUsers = ({id, correspondence, img, name, activeUser, exitOnInterlocutors}) => { | |
return( | |
<ul className={"dialogs__interlocutor" + (id === activeUser ? " active-interlocutor": "")} onClick={() => correspondence(id, exitOnInterlocutors)}> | |
<div><img src={img} alt=""/></div> | |
<div className="dialogs__interlocutor-name main-text"><p>{name}</p></div> | |
</ul> | |
) | |
}; | |
//DialogsMessage | |
const DialogsMessages = ({id, sender, text, users}) => { | |
return ( | |
<div className={!sender ? "dialogs__your-message dialogs__message" : "dialogs__message"}> | |
<div className="dialogs__message-img"><img src={sender ? users[sender - 1].img : pk} alt=""/></div> | |
<p>{text}</p> | |
</div> | |
) | |
}; | |
export default DialogsMessages | |
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
//FriendsContainer | |
class FriendsContainer extends React.Component { | |
componentDidMount() { | |
this.props.getFriends(this.props.activePage, this.props.pageSize); | |
this.props.setActivePageSite("FRIENDS"); | |
} | |
componentDidUpdate(prevProps, prevState, snapshot) { | |
if (prevProps.activePage !== this.props.activePage) | |
this.props.getFriends(this.props.activePage, this.props.pageSize) | |
} | |
onSubmit = (formData) => { | |
this.props.getFriends(this.props.activePage,this.props.pageSize, formData.term) | |
}; | |
render() { | |
return ( | |
<> | |
{this.props.isPreloader ? <Preloader/> : null} | |
<Friends friends={this.props.friends} | |
follow={this.props.follow} | |
unFollow={this.props.unFollow} | |
totalCount={this.props.totalCount} | |
activePage={this.props.activePage} | |
pageSize={this.props.pageSize} | |
waitingSubscripe={this.props.waitingSubscripe} | |
setActivePage={this.props.setActivePage} | |
onSubmit={this.onSubmit} | |
/> | |
</> | |
) | |
} | |
} | |
let mapStateToProps = (state) => { | |
return { | |
friends: state.friendsPage.friends, | |
totalCount: state.usersPage.totalCount, | |
activePage: state.friendsPage.activePage, | |
pageSize: state.usersPage.pageSize, | |
waitingSubscripe: state.usersPage.waitingSubscripe, | |
isPreloader: state.friendsPage.isPreloader | |
} | |
}; | |
//Friends | |
const Friends = (props) => { | |
let friends = props.friends.map(friend => <User name={friend.name} | |
status={friend.status} | |
img={friend.photos.small} | |
id={friend.id} | |
key={friend.id} | |
follow={props.follow} | |
followed={friend.followed} | |
unFollow={props.unFollow} | |
waitingSubscripe={props.waitingSubscripe}/>); | |
return( | |
<FriendsOrUsers title={"Ваши друзья"} | |
text={"Добро пожаловать на страницу ваших друзей, здесь вы будете видеть смешных,грустных, тупых или прекраснейших ваших друзей"} | |
img={mans} | |
totalCount={props.totalCount} | |
activePage={props.activePage} | |
setActivePage={props.setActivePage} | |
pageSize={props.pageSize} | |
countPagesInPortion={window.innerWidth > 960 ? 10 : 5} | |
people={friends} | |
onSubmit={props.onSubmit} | |
/> | |
) | |
}; | |
//FriendsOrUsers | |
const FriendsOrUsers = (props) => { | |
return( | |
<section className='users main-bg'> | |
<div className={props.page === "users" ? "users__bg-header" : "friends__bg-header"}> | |
<div className={props.page === "users" ? "users__header" : "friends__header"}> | |
<div className='users__title title'> | |
<h1>{props.title}</h1> | |
<h3>{props.text}</h3> | |
</div> | |
<div className={props.page === "users" ? "users__subtitle" : "friends__subtitle"}> | |
<img src={props.img} alt=""/> | |
</div> | |
</div> | |
</div> | |
<div className="users__container container"> | |
<div className="users__paginator"> | |
<Paginator totalCount={props.totalCount} | |
activePage={props.activePage} | |
setActivePage={props.setActivePage} | |
pageSize={props.pageSize} | |
countPagesInPortion={props.countPagesInPortion} | |
/> | |
</div> | |
<UsersForm onSubmit={props.onSubmit}/> | |
<div className="users__cards"> | |
{props.people.length > 0 ? props.people : | |
<div className='user__error-search'> | |
<img src={smile} alt=""/> | |
<p className='main-text'>Мы никого не нашли</p> | |
</div> | |
} | |
</div> | |
</div> | |
</section> | |
) | |
}; |
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
const Header = (props) => { | |
return ( | |
<> | |
{props.isPreloader ? <Preloader/> : null} | |
<header className='header-app'> | |
<p className='header-app__active_page'>{props.activePageSite} PAGE</p> | |
<div className="header-app__user-avatar"> | |
<div className=""> | |
<img src={user} alt=""/> | |
</div> | |
<p>{props.login}</p> | |
{props.isAuth && <button onClick={props.logOutMe}><img src={exit} alt=""/></button>} | |
</div> | |
</header> | |
</> | |
) | |
}; |
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
//Login | |
class Login extends React.Component { | |
componentDidMount() { | |
this.props.setActivePageSite("LOGIN") | |
} | |
state = { | |
login: true | |
}; | |
onSubmit = (loginForm) => { | |
this.props.loginMe(loginForm) | |
}; | |
render() { | |
if (this.props.isAuth) | |
return <Redirect to={"/profile"}/>; | |
return ( | |
<section className='login'> | |
<div className='login__bg-header'> | |
<div className="login__container container"> | |
<div className='login__info'> | |
<h1>Welcome to the Biggest Social Network in the World</h1> | |
<h2>We are the best and biggest social network with 5 billion active users all around the | |
world. Share you thoughts, write blog posts, show your favourite music via Stopify, | |
earn badges and much more! | |
</h2> | |
<a href="https://social-network.samuraijs.com/signUp" rel="noopener noreferrer" target="_blank">Зарегистрируйся сейчас</a> | |
</div> | |
<div className={this.props.captcha ? "login__input-window login__input-window-with-captcha" : "login__input-window"}> | |
<div className='login__switch-panel'> | |
<button onClick={() => this.setState({login: true})}><img src={on} alt=""/></button> | |
<button onClick={() => this.setState({login: false})}><img src={on} alt=""/></button> | |
</div> | |
{this.state.login && | |
<div className="login__input-fields"> | |
<LoginForm onSubmit={this.onSubmit} captcha={this.props.captcha}/> | |
<div className="login__additional-network"> | |
<p className='or additional-text'>OR</p> | |
<div className="submit-button"><button><img src={facebook} alt=""/>Login with Facebook</button></div> | |
<div className="submit-button"><button><img src={twitter} alt=""/>Login with Twitter</button></div> | |
</div> | |
</div> | |
} | |
{!this.state.login && | |
<div className="login__registration login__input-fields"> | |
<div className="login__window-title"><h3>Регистрация!</h3></div> | |
<div className="login__input-field"> | |
<p className='main-text'>К сожалению регистрация пока отсуствует на этом сайте, для того чтобы зарегистрироваться нужно перейти на <a href="https://social-network.samuraijs.com/signUp" rel="noopener noreferrer" target="_blank">сайт нашей базы данных</a>, там зарегистрироваться и перейти обратно</p> | |
<p className='main-text'>Это единственный способ зарегистрироваться</p> | |
<p className='main-text'>Спасибо за понимание</p> | |
<img src={smile2} alt=""/> | |
</div> | |
</div> | |
} | |
</div> | |
</div> | |
</div> | |
</section> | |
) | |
} | |
} | |
//LoginForm | |
const LoginForm = (props) => { | |
return( | |
<form onSubmit={props.handleSubmit}> | |
<div className="login__window-title"><h3>Входите и наслаждайтесь!</h3></div> | |
<div className='login__input-field'> | |
<div className='login__field'> | |
<Field component={InputWithPlaceholder} name='email' validate={[FieldIsRequared]} type="text" id="inp" placeholders="Your Email" placeholder=' '/> | |
</div> | |
<div className='login__field'> | |
<Field component={InputWithPlaceholder} name='password' validate={[FieldIsRequared]} type="password" id="inp" placeholders="Your Password" placeholder=' '/> | |
</div> | |
<div className='login__field-checkbox login__field'> | |
<Field component={Input} type='checkbox' name='rememberMe'/> | |
<label>Запомнить меня</label> | |
</div> | |
{props.error ? | |
<p className='login__full_error full_error main-text'>{props.error}</p> : null | |
} | |
{props.captcha ? | |
<> | |
<div className='login__field'> | |
<Field component={InputWithPlaceholder} name='captcha' validate={[FieldIsRequared]} type="text" id="inp" placeholders="Your Captcha" placeholder=' '/> | |
</div> | |
<div className='login__capctha'><img src={props.captcha} alt=""/></div> | |
</> : null} | |
<div className="submit-button"><button>Войти</button></div> | |
</div> | |
</form> | |
) | |
}; | |
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
class MainPageContainer extends React.Component { | |
componentDidMount() { | |
this.props.setActivePageSite("MAIN") | |
} | |
render() { | |
return( | |
<MainPage/> | |
) | |
} | |
} | |
const parallax = (setTranslateX, setTranslateX2, setTranslateX3, setTranslateY, setTranslateY2, setTranslateY3, e) => { | |
setTranslateX(-e.clientX*10/800); | |
setTranslateX2(-e.clientX*40/800); | |
setTranslateX3(-e.clientX*80/800); | |
setTranslateY(-e.clientY*10/800); | |
setTranslateY2(-e.clientY*40/800); | |
setTranslateY3(-e.clientY*80/800) | |
}; | |
const MainPage = () => { | |
let [translateX, setTranslateX] = useState(0); | |
let [translateX2, setTranslateX2] = useState(0); | |
let [translateX3, setTranslateX3] = useState(0); | |
let [translateY, setTranslateY] = useState(0); | |
let [translateY2, setTranslateY2] = useState(0); | |
let [translateY3, setTranslateY3] = useState(0); | |
return ( | |
<section className='home-page' onMouseMove={(e) => parallax(setTranslateX, setTranslateX2, setTranslateX3, setTranslateY, setTranslateY2, setTranslateY3,e)}> | |
<div className="home-page__scene scene"> | |
<div className="layer layer-bg" style={{transform: `translate(${translateX}px, ${translateY}px)`}}> | |
</div> | |
<div className="layer layer-up-bg " style={{transform: `translate(${translateX2}px, ${translateY2}px)`}}> | |
</div> | |
<div className="layer layer-up " style={{transform: `translate(${translateX3}px, ${translateY3}px)`}}> | |
</div> | |
</div> | |
<div className="home-page__container"> | |
<div className="home-page__window home-page__header"> | |
<div className="home-page__window-border"> | |
<div className="home-page__small-window"> | |
<h1>SOCIAL NETWORK</h1> | |
<div className="home-page__dignities"> | |
<div className="home-page__dignitie"> | |
<h3>ПРЕКРАСНЫЙ</h3> | |
<h4>ДИЗАИН</h4> | |
</div> | |
<div className="home-page__dignitie"> | |
<h3>ПОЛНАЯ</h3> | |
<h4>КОНФИДИЦИАЛЬНОСТЬ</h4> | |
</div> | |
<div className="home-page__dignitie"> | |
<h3>ЧЕТКОЕ</h3> | |
<h4>ОБНОВЛЕНИЕ БД</h4> | |
</div> | |
</div> | |
<div className='home-page__info-reg additional-text'><p>Если ты зашел сюда впервый раз, то нажимай кнопку регистрации и присоединяйся к нам. Будь в курсе всего нового.</p></div> | |
<div className="home-page__buttons"> | |
<div className="submit-button"><Link to={'/login'}><button>Регистрация</button></Link></div> | |
<div className="submit-button"><Link to={'/login'}><button>Вход</button></Link></div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</section> | |
) | |
}; |
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
//profileContainer | |
class ProfileContainer extends React.Component { | |
componentDidMount() { | |
let id = this.props.match.params.id; | |
if (!id) { | |
id = this.props.id; | |
if (!id) { | |
this.props.history.push('/login'); | |
} | |
} | |
this.props.setProfile(id); | |
this.props.setStatus(id); | |
this.props.setActivePageSite("PROFILE"); | |
this.props.getFollow(id) | |
} | |
componentDidUpdate(prevProps, prevState, snapshot) { | |
if (prevProps.match.params.id !== this.props.match.params.id && !this.props.match.params.id) { | |
this.props.setProfile(this.props.id); | |
this.props.setStatus(this.props.id); | |
} | |
if (prevProps.match.params.id !== this.props.match.params.id && this.props.match.params.id) { | |
this.props.setProfile(this.props.match.params.id); | |
this.props.setStatus(this.props.match.params.id); | |
} | |
if (prevProps.isAuth !== this.props.isAuth) { | |
this.props.history.push('/login') | |
} | |
} | |
render() { | |
return( | |
<> | |
{!this.props.profile ? <Preloader/> : null} | |
<Profile posts={this.props.posts} | |
profile={this.props.profile} | |
status={this.props.status} | |
putStatus={this.props.putStatus} | |
putProfile={this.props.putProfile} | |
setImageProfile={this.props.setImageProfile} | |
addPost={this.props.addPost} | |
isOwner={!this.props.match.params.id} | |
follow={this.props.follow} | |
unFollow={this.props.unFollow} | |
activeUserFollowed={this.props.activeUserFollowed} | |
waitingSubscripe={this.props.waitingSubscripe} | |
/> | |
</> | |
) | |
} | |
} | |
//Profile | |
const Profile = (props) => { | |
if (!props.profile) | |
return <Preloader/>; | |
return ( | |
<div className={'main-bg profile'}> | |
<div className="profile__container container"> | |
<ProfileAboutMe profile={props.profile} | |
status={props.status} | |
putStatus={props.putStatus} | |
putProfile={props.putProfile} | |
setImageProfile={props.setImageProfile} | |
isOwner={props.isOwner} | |
follow={props.follow} | |
unFollow={props.unFollow} | |
activeUserFollowed={props.activeUserFollowed} | |
waitingSubscripe={props.waitingSubscripe} | |
/> | |
<ProfilePosts posts={props.posts} | |
myPhotos={props.profile.photos.small} | |
name={props.profile.fullName} | |
addPost={props.addPost}/> | |
</div> | |
</div> | |
) | |
}; | |
//ProfileAboutMe | |
const ProfileAboutMe = ({profile, status, putStatus, putProfile, setImageProfile, isOwner, follow, unFollow, activeUserFollowed, waitingSubscripe}) => { | |
let [editMode, setEditMode] = useState(false); | |
let [editModeContacts, setEditModeContacts] = useState(false); | |
const onSubmit = (object) => { | |
setEditMode(false); | |
setEditModeContacts(false); | |
putProfile(object); | |
}; | |
const onUpdatePhoto = (file) => { | |
if (file.target.files.length) | |
setImageProfile(file.target.files[0]) | |
}; | |
let contacts = Object.keys(profile.contacts).map(network => <SocialNetworks key={network} network={network} adres={profile.contacts[network]}/>); | |
return ( | |
<div className="profile__about-me"> | |
<div className='profile__header'> | |
<div className="profile__header-bg"><img src={profile.photos.large ? profile.photos.large : "https://gvk78.ru/no-foto.jpg"} alt=""/></div> | |
<div className='profile__user'> | |
<div className='profile__user-avatar'><img src={profile.photos.small ? profile.photos.large : "https://gvk78.ru/no-foto.jpg"} alt=""/></div> | |
{isOwner ? | |
<div className='profile__user-settings' onChange={onUpdatePhoto}> | |
<img src={settings} alt=""/> | |
<input type="file"/> | |
</div> : | |
null} | |
</div> | |
</div> | |
<div className="profile__links-content profile__main-blocks"> | |
<ul> | |
<li><Link to={'/profile'} className='additional-text'>Видео</Link></li> | |
<li><Link to={'/profile'} className='additional-text'>Обо мне</Link></li> | |
<li><p className='profile__user-name'><Link to={'/profile'}>{profile.fullName}</Link></p></li> | |
<li><Link to={'/profile'} className='additional-text'>Фото</Link></li> | |
<li><Link to={'/profile'} className='additional-text'>Друзья</Link></li> | |
</ul> | |
</div> | |
<div className="profile__main-information "> | |
<div className='profile__information-left-side profile__main-blocks'> | |
<p className='title-information main-text profile__margin'>Главная информация</p> | |
{!editMode && | |
<> | |
{isOwner ? <button className="profile__button-edit-profile" onClick={() => setEditMode(true)}><img src={editProfile} alt=""/></button>:null} | |
<div className="profile__lists-about-profile profile__margin"> | |
<div className="profile__list-about-profile"> | |
<p className='main-text'>Имя: </p> | |
<p className='additional-text'>{profile.fullName}</p> | |
</div> | |
<div className="profile__list-about-profile"> | |
<p className='main-text'>Обо мне: </p> | |
<p className='additional-text'>{profile.aboutMe ? profile.aboutMe : 'Отсутствует'}</p> | |
</div> | |
<div className="profile__list-about-profile"> | |
<p className='main-text'>Работа: </p> | |
<p className='additional-text'>{profile.lookingForAJobDescription ? profile.lookingForAJobDescription : "Отсутствует"}</p> | |
</div> | |
<div className="profile__list-about-profile"> | |
<p className='main-text'>Cтатус: </p> | |
<div className="additional-text input-style1 profile__input-style1"><ProfileStatus status={status} putStatus={putStatus}/></div> | |
</div> | |
</div> | |
</>} | |
{editMode && <EditModeProfileData status={status} putStatus={putStatus} initialValues={profile} onSubmit={onSubmit}/>} | |
</div> | |
<div className='profile__information-right-side profile__main-blocks'> | |
<p className='title-information main-text profile__margin'>Социальные сети</p> | |
<div className="profile__margin"> | |
{!editModeContacts && | |
<> | |
{isOwner ? | |
<button className="profile__button-edit-profile" onClick={() => setEditModeContacts(true)}><img src={editProfile} alt=""/></button> | |
:null} | |
{contacts} | |
</> | |
} | |
{editModeContacts && <EditModeProfileContacts contact={profile.contacts} initialValues={profile} onSubmit={onSubmit}/>} | |
</div> | |
</div> | |
</div> | |
</div> | |
) | |
}; | |
//ProfilePosts | |
const ProfilePosts = (props) => { | |
let [comment, changeComment] = useState(0); | |
const onSubmit = (text) => { | |
props.addPost(text.postMessage, props.myPhotos, props.name) /*заглушка фото*/ | |
}; | |
return ( | |
<div> | |
<div className="profile__posts"> | |
{/*{posts}*/} | |
<ProfilePost img={props.posts[comment].img} | |
name={props.posts[comment].name} | |
textPost={props.posts[comment].textPost} | |
changeCommentRight={() => changeComment(comment + 1)} | |
changeCommentLeft={() => changeComment(comment - 1)} | |
numberComments={comment} | |
numberCommentsInArray={props.posts.length} | |
/> | |
</div> | |
<ProfileField myPhotos={props.myPhotos} onSubmit={onSubmit}/> | |
</div> | |
) | |
}; | |
//ProfileField | |
const ProfileField = (props) => { | |
return( | |
<form onSubmit={props.handleSubmit} className='profile__post-form'> | |
<div className="profile__form form"><Field name='postMessage' component={Textarea} placeholder='Введите ваше сообщение'/></div> | |
<div className='profile__submit-button submit-button'><button>Опубликовать</button></div> | |
<div className='profile__sender-post'><img src={props.myPhotos} alt=""/></div>{/*заглушка фото*/} | |
</form> | |
) | |
}; | |
//ProfileStatus | |
const ProfileStatus = ({status, putStatus}) => { | |
let [editMode, setEditMode] = useState(false); | |
let [statusState, setStatusState] = useState(status); | |
useEffect(() => { | |
setStatusState(status) | |
}, [status]); | |
const sendStatus = (e) => { | |
setEditMode(false); | |
putStatus(statusState) | |
}; | |
return( | |
<div> | |
{!editMode && <p onClick={() => setEditMode(true)}>{status ? status : "Отсутсвует"}</p>} | |
{editMode && | |
<input type="text" autoFocus={true} | |
onBlur={sendStatus} | |
value={statusState} | |
onChange={(e) => setStatusState(e.target.value)} | |
/> | |
} | |
</div> | |
) | |
}; | |
//ProfileNetworks | |
const SocialNetworks = ({network, adres}) => { | |
return ( | |
<div className="profile__list-about-profile profile__network"> | |
<div className='main-text'><img src={require("../../../../img/profileImg/" + network + ".png")} alt=""/>{network}:</div> | |
<div className="additional-text"><p>{adres ? adres : "Отсутствует"}</p></div> | |
</div> | |
) | |
}; | |
//EditModeProfileData | |
const EditModeProfileData = (props) => { | |
return( | |
<form onSubmit={props.handleSubmit} className="profile__lists-about-profile profile__margin"> | |
<button className="profile__button-edit-profile"><img src={saveProfile} alt=""/></button> | |
<div className="profile__list-about-profile"> | |
<p className='main-text'>Имя: </p> | |
<div className="additional-text input-style1 profile__input-style1"><Field name='fullName' component={Input} validate={[FieldIsRequared]} placeholder="Введите ваше имя"/></div> | |
</div> | |
<div className="profile__list-about-profile"> | |
<p className='main-text'>Обо мне: </p> | |
<div className="additional-text input-style1 profile__input-style1"><Field name='aboutMe' component={Input} validate={[FieldIsRequared]} placeholder="Введите информацию"/></div> | |
</div> | |
<div className="profile__list-about-profile"> | |
<p className='main-text'>Работа: </p> | |
<div className="additional-text input-style1 profile__input-style1"><Field name='lookingForAJobDescription' component={Input} validate={[FieldIsRequared]} placeholder="Введите информацию"/></div> | |
</div> | |
<div className="profile__list-about-profile"> | |
<p className='main-text'>Cтатус: </p> | |
<div className="additional-text input-style1 profile__input-style1"><ProfileStatus status={props.status} putStatus={props.putStatus}/></div> | |
</div> | |
</form> | |
) | |
}; | |
//EditModeProfileContacts | |
const EditModeProfileContacts = (props) => { | |
return( | |
<form onSubmit={props.handleSubmit} className='list-about-meEdit'> | |
{props.error ? | |
<p className='login__full_error full_error main-text'>{props.error}</p> : null | |
} | |
<button className="profile__button-edit-profile"><img src={saveProfile} alt=""/></button> | |
{Object.keys(props.contact).map(network => { | |
return ( | |
<div key={network} className="profile__list-about-profile profile__network input-style1 profile__input-style1"> | |
<div className='main-text'><img src={require("../../../../img/profileImg/" + network + ".png")} alt=""/>{network}:</div> | |
<div className="additional-text"><Field name={'contacts.' + network} component={Input} placeholder="Введите адрес"/></div> | |
</div>) | |
})} | |
</form> | |
) | |
}; | |
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
//app | |
const MENU_EDIT = "MENU_EDIT"; | |
const IS_START_APP = "app/IS_START_APP"; | |
const THEME_IS_DARK = "app/THEME_IS_DARK"; | |
const initialState = { | |
isMenuOpen: false, | |
isStartApp: false, | |
themeIsDark: false | |
}; | |
const appReducer = (state = initialState, action) => { | |
switch (action.type) { | |
case MENU_EDIT: | |
return { | |
...state, | |
isMenuOpen: action.isMenuOpen | |
}; | |
case IS_START_APP: | |
return { | |
...state, | |
isStartApp: action.isStartApp | |
}; | |
case THEME_IS_DARK: | |
return { | |
...state, | |
themeIsDark: action.themeIsDark | |
}; | |
default: | |
return state; | |
} | |
}; | |
export const editMenu = (isMenuOpen) => ({type: MENU_EDIT, isMenuOpen}); | |
export const startAppSuccess = (isStartApp) => ({type: IS_START_APP, isStartApp}); | |
export const setThemeIsDark = (themeIsDark) => ({type: THEME_IS_DARK, themeIsDark}); | |
export const startApp = () => (dispatch) => { | |
dispatch(getMyData()).then(() => { | |
dispatch(startAppSuccess(true)) | |
}) | |
}; | |
//auth | |
const SET_MY_DATA = "auth/SET_MY_DATA"; | |
const ACTIVE_PAGE_SITE = "auth/ACTIVE_PAGE_SITE"; | |
const TOGGLE_PRELOADER = "auth/TOGGLE_PRELOADER"; | |
const SET_CAPTCHA = "auth/SET_CAPTCHA"; | |
const initialState = { | |
id: null, | |
email: null, | |
login: null, | |
isAuth: false, | |
activePageSite: null, | |
isPreloader: false, | |
captcha: null, | |
authorizationError: false | |
}; | |
const authReducer = (state = initialState, action) => { | |
switch (action.type) { | |
case SET_MY_DATA: | |
return { | |
...state, | |
...action.data, | |
isAuth: action.isAuth | |
}; | |
case ACTIVE_PAGE_SITE: | |
return { | |
...state, | |
activePageSite: action.page | |
}; | |
case TOGGLE_PRELOADER: | |
return { | |
...state, | |
isPreloader: action.isPreloader | |
}; | |
case SET_CAPTCHA: | |
return { | |
...state, | |
captcha: action.captcha | |
}; | |
default: | |
return state; | |
} | |
}; | |
const setMyData = (data, isAuth) => ({type: SET_MY_DATA, data, isAuth}); | |
export const setActivePageSite = (page) => ({type: ACTIVE_PAGE_SITE, page}); | |
export const togglePreloader = (isPreloader) => ({type: TOGGLE_PRELOADER, isPreloader}); | |
export const setCaptcha = (captcha) => ({type: SET_CAPTCHA, captcha}); | |
export const getMyData = () => (dispatch) => { | |
return authAPI.me().then(data => { | |
if (data.resultCode === 0) | |
dispatch(setMyData(data.data, true)); | |
}) | |
}; | |
export const loginMe = (formData) => (dispatch) => { | |
debugger | |
authAPI.login(formData).then(data => { | |
if (data.resultCode === 0) | |
dispatch(getMyData()); | |
else if (data.resultCode === 10) { | |
authAPI.captcha().then(data => { | |
dispatch(setCaptcha(data.url)) | |
}) | |
} | |
else { | |
let message = data.messages.length > 0 ? data.messages[0] : "Неизвестная ошибка"; | |
dispatch(stopSubmit('login', {_error: message})) | |
} | |
}) | |
}; | |
export const logOutMe = () => (dispatch) => { | |
dispatch(togglePreloader(true)); | |
authAPI.logOut().then(data => { | |
dispatch(setMyData({id: null, email: null, login: null}, false)); | |
dispatch(togglePreloader(false)) | |
}) | |
}; | |
//dialogs | |
const SET_MESSAGE = "SET_MESSAGE"; | |
const SEND_MESSAGE = "SEND_MESSAGE"; | |
const TOGGLE_PRELOADER = "dialogs/TOGGLE_PRELOADER"; | |
const SET_ACTIVE_USER = "SET_ACTIVE_USER"; | |
let initialState = { | |
usersMessage: [ | |
{id: 1, name: "Вин Бензин", img: "https://steamuserimages-a.akamaihd.net/ugc/775113851241543716/7335FB32DB2BF8385B916C647F93725B90B5535B/?imw=512&imh=512&ima=fit&impolicy=Letterbox&imcolor=%23000000&letterbox=true"}, | |
{id: 2, name: "Миша Тинькоф", img: "https://avatars.mds.yandex.net/get-pdb/1350656/1551285a-c152-405f-9336-798ec54b07a9/s1200"}, | |
{id: 3, name: "Ник Анистон", img: "https://avatars.mds.yandex.net/get-pdb/1649566/19e74635-4319-4587-89bf-68bbf6c122ae/s1200?webp=false"}, | |
{id: 4, name: "Ликер Иванович", img: "https://steamuserimages-a.akamaihd.net/ugc/775113851241543716/7335FB32DB2BF8385B916C647F93725B90B5535B/?imw=512&imh=512&ima=fit&impolicy=Letterbox&imcolor=%23000000&letterbox=true"}, | |
{id: 5, name: "Игорь Пушкович", img: "https://avatars.mds.yandex.net/get-pdb/1350656/1551285a-c152-405f-9336-798ec54b07a9/s1200"}, | |
{id: 6, name: "Роберт Ап", img: "https://avatars.mds.yandex.net/get-pdb/1649566/19e74635-4319-4587-89bf-68bbf6c122ae/s1200?webp=false"}, | |
{id: 7, name: "Вин Бензин", img: "https://steamuserimages-a.akamaihd.net/ugc/775113851241543716/7335FB32DB2BF8385B916C647F93725B90B5535B/?imw=512&imh=512&ima=fit&impolicy=Letterbox&imcolor=%23000000&letterbox=true"}, | |
{id: 8, name: "Вин Топливо", img: "https://avatars.mds.yandex.net/get-pdb/1350656/1551285a-c152-405f-9336-798ec54b07a9/s1200"}, | |
{id: 9, name: "Миша Тинькоф", img: "https://avatars.mds.yandex.net/get-pdb/1649566/19e74635-4319-4587-89bf-68bbf6c122ae/s1200?webp=false"}, | |
{id: 10, name: "Роберт Ап", img: "https://steamuserimages-a.akamaihd.net/ugc/775113851241543716/7335FB32DB2BF8385B916C647F93725B90B5535B/?imw=512&imh=512&ima=fit&impolicy=Letterbox&imcolor=%23000000&letterbox=true"}, | |
{id: 11, name: "Игорь Пушкович", img: "https://avatars.mds.yandex.net/get-pdb/1649566/19e74635-4319-4587-89bf-68bbf6c122ae/s1200?webp=false"}, | |
], | |
messages: [], | |
activeUser: null, | |
isPreloader: false | |
}; | |
const dialogsReducer = (state = initialState, action) => { | |
switch (action.type) { | |
case SET_MESSAGE: | |
return { | |
...state, | |
messages: action.message | |
}; | |
case SEND_MESSAGE: | |
return { | |
...state, | |
messages: [...state.messages, {id: 7, text: action.text, isYouSend: true}] | |
}; | |
case SET_ACTIVE_USER: | |
return { | |
...state, | |
activeUser: action.id | |
}; | |
case TOGGLE_PRELOADER: | |
return { | |
...state, | |
isPreloader: action.isPreloader | |
}; | |
default: | |
return state | |
} | |
}; | |
const getMessageSuccess = (message) => ({type: SET_MESSAGE, message}); | |
export const sendMessage = (text) => ({type: SEND_MESSAGE, text}); | |
export const setActiveUser = (id) => ({type: SET_ACTIVE_USER, id}); | |
export const togglePreloader = (isPreloader) => ({type: TOGGLE_PRELOADER, isPreloader}); | |
export const getMessage = (id) => (dispatch) => { | |
dispatch(getMessageSuccess([{id: 1, text: "Хэй бро, как твои дела?", sender: id}, | |
{id: 2, text: "Здарова, ты кто?", sender: null}, | |
{id: 3, text: "Я тот кто не ты", sender: id}, | |
{id: 4, text: "Я тоже рад, что ты не я", sender: null}, | |
{id: 5, text: "будь здоров, бро", sender: id}, | |
{id: 6, text: "пока", sender: id}])) | |
}; | |
//friends | |
const GET_MY_FRIENDS = "GET_MY_FRIENDS"; | |
const SET_ACTIVE_PAGE = "friends/SET_ACTIVE_PAGE"; | |
const SET_FOLLOW_UNFOLLOW = "friends/SET_FOLLOW_UNFOLLOW"; | |
const TOGGLE_PRELOADER = "frineds/TOGGLE_PRELOADER"; | |
const initialState = { | |
friends: [], | |
activePage: 1, | |
isPreloader: false | |
}; | |
const friendsReducer = (state = initialState, action) => { | |
switch (action.type) { | |
case GET_MY_FRIENDS: | |
return { | |
...state, | |
friends: action.friends | |
}; | |
case SET_ACTIVE_PAGE: | |
return { | |
...state, | |
activePage: action.activePage | |
}; | |
case SET_FOLLOW_UNFOLLOW: | |
return { | |
...state, | |
friends: sortingUsers(state.friends, action.id, action.follow), | |
}; | |
case TOGGLE_PRELOADER: | |
return { | |
...state, | |
isPreloader: action.isPreloader | |
}; | |
default: | |
return state; | |
} | |
}; | |
export const togglePreloader = (isPreloader) => ({type: TOGGLE_PRELOADER, isPreloader}); | |
const getFriendsSuccess = (friends) => ({type: GET_MY_FRIENDS, friends}); | |
export const setActivePage = (activePage) => ({type: SET_ACTIVE_PAGE, activePage}); | |
const setFollowUnFollowFriends = (follow, id) => ({type: SET_FOLLOW_UNFOLLOW, follow, id}); | |
export const getFriends = (activePage, pageSize, term) => (dispatch) => { | |
dispatch(togglePreloader(true)); | |
friendsAPI.getFriends(activePage, pageSize, term).then(data => { | |
if (data.error !== true) { | |
dispatch(getFriendsSuccess(data.items)); | |
dispatch(setTotalCount(data.totalCount)); | |
dispatch(togglePreloader(false)); | |
} | |
}) | |
}; | |
export const follow = (id) => (dispatch) => { | |
followUnFollow(id, usersAPI.follow.bind(usersAPI), setFollowUnFollowFriends, dispatch, true) | |
}; | |
export const unFollow = (id) => (dispatch) => { | |
followUnFollow(id, usersAPI.unFollow.bind(usersAPI), setFollowUnFollowFriends, dispatch, false) | |
}; | |
//profile | |
const SET_PROFILE = "profilePage/SET_PROFILE"; | |
const SET_STATUS = "profilePage/SET_STATUS"; | |
const ADD_POST = "profilePage/ADD_POST"; | |
const TOGGLE_PRELOADER = "profilePage/TOGGLE_PRELOADER"; | |
let initialState = { | |
posts: [ | |
{id: 1, name: "Elaine Dreyfuss", img:"https://lh3.googleusercontent.com/AS2b24SuncRJJNO2yvHCcJeci3zs8g7QbvlifOmNrppfCzeRRLjdB2YU4bJZur3kBDE", lastTime: "9 hours ago", textPost: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempo incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris consequat."}, | |
{id: 2, name: "Albert Raymond", img:"https://lh3.googleusercontent.com/AS2b24SuncRJJNO2yvHCcJeci3zs8g7QbvlifOmNrppfCzeRRLjdB2YU4bJZur3kBDE",lastTime: "1 hours ago", textPost: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempo incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris consequat."}, | |
{id: 3, name: "Jonh Carry", img:"https://lh3.googleusercontent.com/AS2b24SuncRJJNO2yvHCcJeci3zs8g7QbvlifOmNrppfCzeRRLjdB2YU4bJZur3kBDE",lastTime: "9 day ago", textPost: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempo incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris consequat."}, | |
{id: 4, name: "Денис Лариков",img:"https://lh3.googleusercontent.com/AS2b24SuncRJJNO2yvHCcJeci3zs8g7QbvlifOmNrppfCzeRRLjdB2YU4bJZur3kBDE", lastTime: "9 weeks ago", textPost: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempo incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris consequat."}, | |
{id: 5, name: "Роберт Ванек", img:"https://lh3.googleusercontent.com/AS2b24SuncRJJNO2yvHCcJeci3zs8g7QbvlifOmNrppfCzeRRLjdB2YU4bJZur3kBDE",lastTime: "online", textPost: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempo incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris consequat."}, | |
{id: 6, name: "Елизабет павп", img:"https://lh3.googleusercontent.com/AS2b24SuncRJJNO2yvHCcJeci3zs8g7QbvlifOmNrppfCzeRRLjdB2YU4bJZur3kBDE",lastTime: "deleted", textPost: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempo incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris consequat."}, | |
{id: 7, name: "Робби Марго", img:"https://lh3.googleusercontent.com/AS2b24SuncRJJNO2yvHCcJeci3zs8g7QbvlifOmNrppfCzeRRLjdB2YU4bJZur3kBDE",lastTime: "5 hours ago", textPost: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempo incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris consequat."}, | |
{id: 8, name: "Марго Робби", img:"https://lh3.googleusercontent.com/AS2b24SuncRJJNO2yvHCcJeci3zs8g7QbvlifOmNrppfCzeRRLjdB2YU4bJZur3kBDE",lastTime: "2 hours ago", textPost: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempo incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris consequat."}, | |
{id: 9, name: "Санька Русский", img:"https://lh3.googleusercontent.com/AS2b24SuncRJJNO2yvHCcJeci3zs8g7QbvlifOmNrppfCzeRRLjdB2YU4bJZur3kBDE",lastTime: "6 hours ago", textPost: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempo incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris consequat."} | |
], | |
profile: null, | |
status: null, | |
isPreloader: false | |
}; | |
let profileReducer = (state = initialState, action) => { | |
switch (action.type) { | |
case SET_PROFILE: | |
return { | |
...state, | |
profile: action.profile | |
}; | |
case SET_STATUS: | |
return { | |
...state, | |
status: action.status | |
}; | |
case ADD_POST: | |
return { | |
...state, | |
posts: [...state.posts, {id: 12, name: action.name, img: action.img, lastTime: "9 hours ago", textPost: action.text}] | |
}; | |
case TOGGLE_PRELOADER: | |
return { | |
...state, | |
isPreloader: action.isPreloader | |
}; | |
default: | |
return state; | |
} | |
}; | |
export const togglePreloader = (isPreloader) => ({type: TOGGLE_PRELOADER, isPreloader}); | |
export const setProfileSuccess = (profile) => ({type: SET_PROFILE, profile}); | |
export const setStatusSuccess = (status) => ({type: SET_STATUS, status}); | |
export const addPost = (text, img, name) => ({type: ADD_POST, text, img, name}); | |
export const setProfile = (userId) => async(dispatch) => { | |
dispatch(togglePreloader(true)); | |
profileAPI.getProfile(userId).then(data => { | |
dispatch(setProfileSuccess(data)); | |
dispatch(togglePreloader(false)); | |
}) | |
}; | |
export const setStatus = (userId) => (dispatch) => { | |
dispatch(togglePreloader(true)); | |
profileAPI.getStatus(userId).then(data => { | |
dispatch(setStatusSuccess(data)) | |
dispatch(togglePreloader(false)); | |
}) | |
}; | |
export const putStatus = (newStatus) => (dispatch) => { | |
dispatch(togglePreloader(true)); | |
profileAPI.putStatus(newStatus).then(data => { | |
if (data.resultCode === 0) | |
dispatch(setStatusSuccess(newStatus)); | |
dispatch(togglePreloader(false)); | |
}) | |
}; | |
export const putProfile = (profile) => (dispatch, getState) => { | |
dispatch(togglePreloader(true)); | |
profileAPI.putProfile(profile).then(data => { | |
if (data.resultCode === 0) { | |
dispatch(togglePreloader(false)); | |
dispatch(setProfile(getState().auth.id)) | |
} | |
else { | |
let message = data.messages.length > 0 ? data.messages[0] : "Неизвестная ошибка"; | |
dispatch(stopSubmit('socialNetworks', {_error: message})) | |
} | |
}) | |
}; | |
export const setImageProfile = (img) => (dispatch, getState) => { | |
dispatch(togglePreloader(true)); | |
profileAPI.setImageProfile(img).then(data => { | |
dispatch(setProfile(getState().auth.id)) //////////////////////////заглушка | |
dispatch(togglePreloader(false)); | |
}) | |
}; | |
//users | |
const GET_USERS = "GET_USERS"; | |
const SET_TOTAL_COUNTS = "SET_TOTAL_COUNTS"; | |
const SET_ACTIVE_PAGE = "SET_ACTIVE_PAGE"; | |
const SET_FOLLOW_UNFOLLOW = "SET_FOLLOW_UNFOLLOW"; | |
const SET_ACTIVE_USER_FOLLOWED = "SET_ACTIVE_USER_FOLLOWED"; | |
const ADD_WAITING_SUBSCRIPE = "ADD_WAITING_SUBSCRIPE"; | |
const TOGGLE_PRELOADER = "users/TOGGLE_PRELOADER"; | |
const KEY_TERM_SEARCH = "users/KEY_TERM_SEARCH"; | |
let initialState = { | |
users: [], | |
totalCount: null, | |
activePage: 1, | |
pageSize: 8, | |
activeUserFollowed: false, | |
waitingSubscripe: [], | |
isPreloader: false, | |
termSearch: "" | |
}; | |
const usersReducer = (state=initialState, action) => { | |
switch (action.type) { | |
case GET_USERS: | |
return { | |
...state, | |
users: action.users | |
}; | |
case SET_TOTAL_COUNTS: | |
return { | |
...state, | |
totalCount: action.totalCount | |
}; | |
case SET_ACTIVE_PAGE: | |
return { | |
...state, | |
activePage: action.activePage | |
}; | |
case SET_FOLLOW_UNFOLLOW: | |
return { | |
...state, | |
users: sortingUsers(state.users, action.id, action.follow), | |
activeUserFollowed: action.follow | |
}; | |
case SET_ACTIVE_USER_FOLLOWED: | |
return { | |
...state, | |
activeUserFollowed: action.follow | |
}; | |
case ADD_WAITING_SUBSCRIPE: | |
return { | |
...state, | |
waitingSubscripe: action.add ? [...state.waitingSubscripe, action.userId] : state.waitingSubscripe.filter(number => number !== action.userId) | |
}; | |
case TOGGLE_PRELOADER: | |
return { | |
...state, | |
isPreloader: action.isPreloader | |
}; | |
case KEY_TERM_SEARCH: | |
debugger | |
return { | |
...state, | |
termSearch: action.termSearch | |
}; | |
default: | |
return state; | |
} | |
}; | |
export const togglePreloader = (isPreloader) => ({type: TOGGLE_PRELOADER, isPreloader}); | |
const getUsersSuccess = (users) => ({type: GET_USERS, users}); | |
export const setTotalCount = (totalCount) => ({type: SET_TOTAL_COUNTS, totalCount}); | |
export const setActivePage = (activePage) => ({type: SET_ACTIVE_PAGE, activePage}); | |
const setFollowUnFollow = (follow, id) => ({type: SET_FOLLOW_UNFOLLOW, follow, id}); | |
const setActiveUserFollowed = (follow) => ({type: SET_ACTIVE_USER_FOLLOWED, follow}); | |
export const addWaitingSubscribe = (add, userId) => ({type: ADD_WAITING_SUBSCRIPE, add, userId}); | |
export const setTermSearch = (termSearch) => ({type: KEY_TERM_SEARCH, termSearch}); | |
export const getUsers = (pagesCount, pageSize, term) => (dispatch) => { | |
dispatch(togglePreloader(true)); | |
usersAPI.getUser(pagesCount, pageSize, term).then(data => { | |
dispatch(getUsersSuccess(data.items)); | |
dispatch(setTotalCount(data.totalCount)); | |
dispatch(togglePreloader(false)); | |
}) | |
}; | |
export const followUnFollow = (id, methodApi, methodAction, dispatch, isFollowed) => { | |
dispatch(addWaitingSubscribe(true, id)); | |
methodApi(id).then(data => { | |
if (data.resultCode === 0) { | |
dispatch(methodAction(isFollowed, id)); | |
dispatch(addWaitingSubscribe(false, id)); | |
} | |
}) | |
}; | |
export const follow = (id) => (dispatch) => { | |
followUnFollow(id, usersAPI.follow.bind(usersAPI), setFollowUnFollow, dispatch, true) | |
}; | |
export const unFollow = (id) => (dispatch) => { | |
followUnFollow(id, usersAPI.unFollow.bind(usersAPI), setFollowUnFollow, dispatch, false) | |
}; | |
export const getFollow = (id) => (dispatch) => { | |
usersAPI.getFollow(id).then(data => { | |
dispatch(setActiveUserFollowed(data)) | |
}) | |
}; | |
//redux | |
let reducers = combineReducers({ | |
profilePage: profileReducer, | |
auth: authReducer, | |
dialogsPage: dialogsReducer, | |
usersPage: usersReducer, | |
friendsPage: friendsReducer, | |
appReducer: appReducer, | |
form: formReducer | |
}); |
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
class SettingsContainer extends React.Component { | |
componentDidMount() { | |
this.props.setActivePageSite("SETTINGS") | |
} | |
render() { | |
return( | |
<Settings setThemeIsDark={this.props.setThemeIsDark} themeIsDark={this.props.themeIsDark}/> | |
) | |
} | |
} | |
const Settings = ({setThemeIsDark, themeIsDark}) => { | |
return( | |
<section className={'settings main-bg ' + (themeIsDark ? 'dark-theme' : "white-theme")}> | |
<div className="settings__bg-header"> | |
<div className="settings__header"> | |
<div className="settings__title title"> | |
<h1>Ваши настройки</h1> | |
<h3>Добро пожаловать на страницу настроек, здесь вы можете сделать нашу соц сеть менее ущербной для ваших глаз. Приятного дня!!!</h3> | |
</div> | |
<div className="settings__subtitle"> | |
<div><img src={g} alt=""/></div> | |
</div> | |
</div> | |
</div> | |
<div className="settings__container container"> | |
<div className="settings__main-blocks"> | |
<p className="title-information settings__margin main-text">Изменение темы</p> | |
<div className="settings__themes-buttons settings__margin"> | |
<p className='main-text'>Выберите тему:</p> | |
{themeIsDark ? | |
<> | |
<div className='settings__button white'> | |
<span className='settings__checkpoint settings__big-round'></span> | |
<button className="settings__checkpoint" onClick={() => setThemeIsDark(false)}></button> | |
</div> | |
<div className={"settings__button settings__your-theme dark"}> | |
<button className="settings__checkpoint"><img src={ch} alt=""/></button> | |
</div> | |
</> | |
: | |
<> | |
<div className={"settings__button settings__your-theme white"}> | |
<button className="settings__checkpoint"><img src={ch} alt=""/></button> | |
</div> | |
<div className='settings__button dark'> | |
<span className='settings__checkpoint settings__big-round'></span> | |
<button className="settings__checkpoint" onClick={() => setThemeIsDark(true)}></button> | |
</div> | |
</> | |
} | |
</div> | |
<p className='additional-text settings__margin'>*Сменив тему вы можете получить гораздо больше удовольствия, хотя если вы находитесь в нашей сети, то вы уже в максимальном экстазе</p> | |
</div> | |
<div className="settings__main-blocks"> | |
<p className="title-information settings__margin main-text">Изменение языка</p> | |
<div className="settings__language settings__margin"> | |
<p className='main-text'>Выберите язык:</p> | |
<p>Русский</p> | |
</div> | |
<p className='additional-text settings__margin'>*К сожалению наша социальная сеть не поднялась до мирового уровня, поэтому радуемся нашему поистине могущественному русскому языку</p> | |
</div> | |
</div> | |
</section> | |
) | |
}; |
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
//UsersContainer | |
class UsersContainer extends React.Component { | |
componentDidMount() { | |
this.props.getUsers(this.props.activePage,this.props.pageSize, this.props.termSearch); | |
this.props.setActivePageSite("USERS"); | |
} | |
componentDidUpdate(prevProps, prevState, snapshot) { | |
if (prevProps.activePage !== this.props.activePage) | |
this.props.getUsers(this.props.activePage,this.props.pageSize, this.props.termSearch); | |
if (prevProps.termSearch !== this.props.termSearch) | |
this.props.getUsers(this.props.activePage,this.props.pageSize, this.props.termSearch) | |
} | |
onSubmit = (formData) => { | |
this.props.getUsers(this.props.activePage,this.props.pageSize, formData.term) | |
}; | |
render() { | |
return ( | |
<> | |
{this.props.isPreloader ? <Preloader/> : null} | |
<Users users={this.props.users} | |
totalCount={this.props.totalCount} | |
activePage={this.props.activePage} | |
setActivePage={this.props.setActivePage} | |
pageSize={this.props.pageSize} | |
follow={this.props.follow} | |
unFollow={this.props.unFollow} | |
waitingSubscripe={this.props.waitingSubscripe} | |
termSearch={this.props.termSearch} | |
setTermSearch={this.props.setTermSearch} | |
onSubmit={this.onSubmit} | |
/> | |
</> | |
); | |
} | |
} | |
//Users | |
const Users = (props) => { | |
const users = props.users.map(user => <User name={user.name} status={user.status} img={user.photos.small} | |
id={user.id} follow={props.follow} followed={user.followed} | |
unFollow={props.unFollow} waitingSubscripe={props.waitingSubscripe} page={"users"} | |
key={user.id} | |
/>); | |
return ( | |
<FriendsOrUsers title={"Наши пользователи"} | |
text={"Добро пожаловать на страницу наших пользователей, здесь вы будете видеть смешных,грустных, тупых или прекраснейших пользователей или друзей(как повезет)"} | |
img={mans} totalCount={props.totalCount} activePage={props.activePage} setActivePage={props.setActivePage} | |
pageSize={props.pageSize} countPagesInPortion={window.innerWidth > 960 ? 10 : 5} | |
people={users} page={"users"} | |
termSearch={props.termSearch} | |
setTermSearch={props.setTermSearch} | |
onSubmit={props.onSubmit} | |
/> | |
) | |
}; | |
//User | |
const User = ({img, name, status, id, follow, followed, unFollow, waitingSubscripe, page}) => { | |
return( | |
<div className="users__card"> | |
<div className="users__card-front"> | |
<div className='users__avatar-user'><Link to={'profile/' + id}><img src={img ? img : def} alt=""/></Link></div> | |
<div className="main-text"><p>{name}</p></div> | |
<div className="additional-text"><p>{status ? status : "Статус отсутствует"}</p></div> | |
{followed ? | |
<div className="normal-button users__follow-on-you"> | |
<p>Вы подписаны на него</p> | |
</div> : | |
<div className="users__unfollow-on-you normal-button"> | |
<p>Вы не подписаны на него</p> | |
</div> | |
} | |
</div> | |
<div className={page === "users" ? "users__card-back" : "users__card-back friends__card-back"}> | |
<div className='users__action-on-user'> | |
<div className='users__buttons'> | |
<div className="users__normal-button_first normal-button"><button>Отправить сообщение</button></div> | |
<FollowFunc id={id} component='users' followed={followed} follow={follow} unFollow={unFollow} waitingSubscripe={waitingSubscripe}/> | |
</div> | |
</div> | |
</div> | |
</div> | |
) | |
}; | |
//UsersForm | |
const UsersForm = (props) => { | |
return( | |
<form onSubmit={props.handleSubmit} className='users__search-form'> | |
<Field component={Input} name='term' type="text" placeholders="Имя пользователя"/> | |
<button><img src={loup} alt=""/></button> | |
</form> | |
) | |
}; |
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
//FieldsReact | |
export const Textarea = (props) => { | |
let {input, meta, ...restProps} = props; | |
return <AutoContainer {...props}><textarea {...input} {...restProps}/></AutoContainer> | |
}; | |
export const Input = (props) => { | |
let {input, meta, ...restProps} = props; | |
return <AutoContainer {...props}><input {...input} {...restProps}/></AutoContainer> | |
}; | |
export const InputWithPlaceholder = (props) => { | |
let {input, meta, ...restProps} = props; | |
return <AutoContainerWithPlaceholder {...props}><input {...input} {...restProps}/></AutoContainerWithPlaceholder> | |
}; | |
export const AutoContainer = ({input, meta, ...props}) => { | |
let errors = meta.error && meta.touched; | |
return( | |
<div className={errors ? 'field-error field-normal' : 'field-normal'}> | |
<div>{props.children}</div> | |
{errors ? <div className='field-error__img-error'><img src={error} alt=""/></div> : null} | |
</div> | |
) | |
}; | |
export const AutoContainerWithPlaceholder = ({input, meta, ...props}) => { | |
let errors = meta.error && meta.touched; | |
return( | |
<div className={errors ? 'field-error field-normal' : 'field-normal'}> | |
{props.children} | |
<span className='label'>{props.placeholders}</span> | |
{errors ? <div className='field-error__img-error'><img src={error} alt=""/></div> : null} | |
</div> | |
) | |
}; | |
//Follow | |
const FollowFunc = ({id, component, follow, followed, unFollow, waitingSubscripe}) => { | |
return ( | |
<> | |
{!followed && <div className={'normal-button users__normal-button_second'}> | |
<button onClick={() => follow(id)} disabled={waitingSubscripe.includes(id)}>Подписаться</button> | |
</div>} | |
{followed && <div className={'normal-button users__normal-button_three'}> | |
<button onClick={() => unFollow(id)} disabled={waitingSubscripe.includes(id)}> | |
Отписаться | |
</button> | |
</div>} | |
</> | |
) | |
}; | |
//preloader | |
const Preloader = () => { | |
return( | |
<div className='main-bg'> | |
<div className='preloader'> | |
<div className="preloader__window"> | |
<div className="preloader__line line1"> | |
</div> | |
<div className="preloader__line line2"> | |
</div> | |
<div className="preloader__line line3"> | |
</div> | |
<div className="preloader__line line4"> | |
</div> | |
</div> | |
</div> | |
</div> | |
) | |
}; | |
//padinator | |
const Paginator = ({totalCount, activePage, setActivePage, pageSize, countPagesInPortion}) => { | |
const [portionNumber, setPortionNumber] = useState(1); | |
const allPages = Math.ceil(totalCount/pageSize); | |
const leftBorderPortion = (portionNumber - 1) * countPagesInPortion + 1; | |
const rightBorderPortion = portionNumber * countPagesInPortion; | |
let arrPage = []; | |
for (let i = 1; i <= allPages; i++) | |
arrPage.push(i); | |
return( | |
<div className="paginator"> | |
<div className='paginator__button'>{portionNumber > 1 ? <button onClick={() => setPortionNumber(portionNumber - 1)}>«</button> : null}</div> | |
{arrPage.filter(page => page <= rightBorderPortion && page >= leftBorderPortion).map(page => | |
<div key={page} className={activePage === page ? "paginator__active-page paginator__button" : "paginator__button"}> | |
<button onClick={() => setActivePage(page)}>{page}</button> | |
</div>) | |
} | |
<div className='paginator__button'>{rightBorderPortion < allPages ? <button onClick={() => setPortionNumber(portionNumber + 1)}>»</button> : null}</div> | |
</div> | |
) | |
}; | |
//redirect | |
let mapStateToProps = (state) => { | |
return { | |
isAuth: state.auth.isAuth | |
} | |
}; | |
const withRedirect = (Component) => { | |
let RedirectContainer = (props) => { | |
if (!props.isAuth) | |
return <Redirect to={'login'}/>; | |
return <Component {...props}/> | |
}; | |
return connect(mapStateToProps, {})(RedirectContainer) | |
}; | |
//sort | |
const sortingUsers = (users, id, isFollow) => { | |
return( | |
users.map(user => { | |
if (user.id === id) | |
return {...user, followed: isFollow}; | |
return user | |
}) | |
) | |
}; | |
//validate | |
export const FieldIsRequared = (text) => { | |
if (!text) | |
return "Вы ничего не написали :("; | |
return undefined | |
}; | |
export const FieldLength = (lenght) => (text) => { | |
if (text && text.length <= lenght) | |
return undefined; | |
return "Слишком много символов, больно :(" | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment