Client - rename existing front

This commit is contained in:
Sam
2021-09-01 20:08:06 +02:00
parent 6ba3f6d54e
commit 6d1de3c3bb
134 changed files with 0 additions and 0 deletions

View File

@ -1,19 +0,0 @@
import React from 'react'
import { withTranslation } from 'react-i18next'
import { connect } from 'react-redux'
import ProfileDetail from './ProfileDetail'
function CurrentUserProfile({ t, user }) {
return (
<div>
<ProfileDetail editable t={t} user={user} />
</div>
)
}
export default withTranslation()(
connect(state => ({
user: state.user,
}))(CurrentUserProfile)
)

View File

@ -1,125 +0,0 @@
import React from 'react'
import { useTranslation } from 'react-i18next'
import { Helmet } from 'react-helmet'
import { Link } from 'react-router-dom'
import { history } from '../../index'
export default function Form(props) {
const { t } = useTranslation()
const pageTitle = `user:${props.formType
.charAt(0)
.toUpperCase()}${props.formType.slice(1)}`
return (
<div>
<Helmet>
<title>FitTrackee - {t(`user:${props.formType}`)}</title>
</Helmet>
<h1 className="page-title">{t(pageTitle)}</h1>
<div className="container">
<div className="row">
<div className="col-md-3" />
<div className="col-md-6">
<br />
{props.formType === 'register' && !props.isRegistrationAllowed ? (
<div className="card">
<div className="card-body">Registration is disabled.</div>
<div className="card-body">
<button
type="submit"
className="btn btn-secondary btn-lg btn-block"
onClick={() => history.go(-1)}
>
Back
</button>
</div>
</div>
) : (
<>
<form
onSubmit={event =>
props.handleUserFormSubmit(event, props.formType)
}
>
{props.formType === 'register' && (
<div className="form-group">
<input
className="form-control input-lg"
name="username"
placeholder={t('user:Enter a username')}
required
type="text"
value={props.userForm.username}
onChange={props.onHandleFormChange}
/>
</div>
)}
{props.formType !== 'password reset' && (
<div className="form-group">
<input
className="form-control input-lg"
name="email"
placeholder={t('user:Enter an email address')}
required
type="email"
value={props.userForm.email}
onChange={props.onHandleFormChange}
/>
</div>
)}
{props.formType !== 'reset your password' && (
<>
<div className="form-group">
<input
className="form-control input-lg"
name="password"
placeholder={t('user:Enter a password')}
required
type="password"
value={props.userForm.password}
onChange={props.onHandleFormChange}
/>
</div>
{props.formType !== 'login' && (
<div className="form-group">
<input
className="form-control input-lg"
name="password_conf"
placeholder={t(
'user:Enter the password confirmation'
)}
required
type="password"
value={props.userForm.password_conf}
onChange={props.onHandleFormChange}
/>
</div>
)}
</>
)}
<input
type="submit"
className="btn btn-primary btn-lg btn-block"
value={t('Submit')}
/>
</form>
<p className="password-forget">
{props.formType === 'login' && (
<Link
to={{
pathname: '/password-reset/request',
}}
>
{t('user:Forgot password?')}
</Link>
)}
</p>
</>
)}
</div>
<div className="col-md-3" />
</div>
</div>
</div>
)
}

View File

@ -1,43 +0,0 @@
import React from 'react'
import { Trans } from 'react-i18next'
import { connect } from 'react-redux'
import { Link } from 'react-router-dom'
import { logout } from '../../actions/user'
class Logout extends React.Component {
componentDidMount() {
this.props.UserLogout()
}
render() {
return (
<div className="container dashboard">
<div className="row">
<div className="col-2" />
<div className="card col-8">
<div className="card-body">
<div className="text-center">
<Trans i18nKey="user:loggedOut">
You are now logged out. Click <Link to="/login">here</Link> to
log back in.
</Trans>
</div>
</div>
</div>
<div className="col-2" />
</div>
</div>
)
}
}
export default connect(
state => ({
user: state.user,
}),
dispatch => ({
UserLogout: () => {
dispatch(logout())
},
})
)(Logout)

View File

@ -1,48 +0,0 @@
import React from 'react'
import { Trans, useTranslation } from 'react-i18next'
import { Link } from 'react-router-dom'
import { ReactComponent as Password } from '../../images/password.svg'
import { ReactComponent as MailSend } from '../../images/mail-send.svg'
export default function PasswordReset(props) {
const { t } = useTranslation()
const { action } = props
return (
<div className="container dashboard">
<div className="row">
<div className="col-2" />
<div className="card col-8">
<div className="card-body">
<div className="text-center ">
{action === 'sent' && (
<>
<div className="svg-icon">
<MailSend />
</div>
{t(
// eslint-disable-next-line max-len
"user:Check your email. If your address is in our database, you'll received an email with a link to reset your password."
)}
</>
)}
{action === 'updated' && (
<>
<div className="svg-icon">
<Password />
</div>
<Trans i18nKey="user:updatedPasswordText">
{/* prettier-ignore */}
Your password have been updated. Click
<Link to="/login">here</Link> to log in.
</Trans>
</>
)}
</div>
</div>
</div>
<div className="col-2" />
</div>
</div>
)
}

View File

@ -1,199 +0,0 @@
import { format } from 'date-fns'
import React from 'react'
import { Helmet } from 'react-helmet'
import { withTranslation } from 'react-i18next'
import { connect } from 'react-redux'
import Message from '../Common/Message'
import { deletePicture, uploadPicture } from '../../actions/user'
import { apiUrl, getFileSize } from '../../utils'
import { history } from '../../index'
function ProfileDetail({
appConfig,
displayModal,
editable,
isDeletable,
message,
onDeletePicture,
onUploadPicture,
pathname,
t,
user,
}) {
const createdAt = user.created_at
? format(new Date(user.created_at), 'dd/MM/yyyy HH:mm')
: ''
const birthDate = user.birth_date
? format(new Date(user.birth_date), 'dd/MM/yyyy')
: ''
const fileSizeLimit = getFileSize(appConfig.max_single_file_size)
return (
<div>
<Helmet>
<title>FitTrackee - {t('user:Profile')}</title>
</Helmet>
<Message message={message} t={t} />
<div className="container">
<h1 className="page-title">{t('user:Profile')}</h1>
<div className="row">
<div className="col-md-12">
<div className="card">
<div className="card-header userName">
<strong>{user.username}</strong>
</div>
<div className="card-body">
<div className="row">
<div className="col-md-8">
<p>
{/* eslint-disable-next-line max-len */}
<span className="user-label">
{t('user:Email')}
</span>: {user.email}
</p>
<p>
<span className="user-label">
{t('user:Registration Date')}
</span>
: {createdAt}
</p>
<p>
<span className="user-label">{t('user:First Name')}</span>
: {user.first_name}
</p>
<p>
{/* eslint-disable-next-line max-len */}
<span className="user-label">
{t('user:Last Name')}
</span>: {user.last_name}
</p>
<p>
<span className="user-label">{t('user:Birth Date')}</span>
: {birthDate}
</p>
<p>
{/* eslint-disable-next-line max-len */}
<span className="user-label">
{t('user:Location')}
</span>: {user.location}
</p>
<p>
<span className="user-label">{t('user:Bio')}</span>:{' '}
<span className="user-bio">{user.bio}</span>
</p>
<p>
{/* eslint-disable-next-line max-len */}
<span className="user-label">
{t('user:Language')}
</span>: {user.language}
</p>
<p>
{/* eslint-disable-next-line max-len */}
<span className="user-label">
{t('user:Timezone')}
</span>: {user.timezone}
</p>
<p>
<span className="user-label">
{t('user:First day of week')}
</span>
: {user.weekm ? t('user:Monday') : t('user:Sunday')}
</p>
</div>
<div className="col-md-4">
{user.picture === true && (
<div>
<img
alt="Profile"
src={
`${apiUrl}users/${user.username}/picture` +
`?${Date.now()}`
}
className="img-fluid App-profile-img-small"
/>
{editable && (
<>
<br />
<button
type="submit"
onClick={() => onDeletePicture()}
>
{t('user:Delete picture')}
</button>
<br />
<br />
</>
)}
</div>
)}
{editable && (
<form
encType="multipart/form-data"
onSubmit={event => onUploadPicture(event)}
>
<input
type="file"
name="picture"
accept=".png,.jpg,.gif"
/>
<br />
<button type="submit">{t('user:Send')}</button>
{` (max. size: ${fileSizeLimit})`}
</form>
)}{' '}
</div>
</div>
{editable && (
<button
className="btn btn-primary"
onClick={() => history.push('/profile/edit')}
>
{t('common:Edit')}
</button>
)}
{isDeletable && (
<button
className="btn btn-danger"
onClick={() => displayModal(true)}
>
{t('user:Delete user account')}
</button>
)}
<button
className="btn btn-secondary"
onClick={() =>
pathname === '/profile' ? history.push('/') : history.go(-1)
}
>
{t(
pathname === '/profile'
? 'common:Back to home'
: 'common:Back'
)}
</button>
</div>
</div>
</div>
</div>
</div>
</div>
)
}
export default withTranslation()(
connect(
state => ({
appConfig: state.application.config,
pathname: state.router.location.pathname,
message: state.message,
}),
dispatch => ({
onDeletePicture: () => {
dispatch(deletePicture())
},
onUploadPicture: event => {
dispatch(uploadPicture(event))
},
})
)(ProfileDetail)
)

View File

@ -1,314 +0,0 @@
import { format } from 'date-fns'
import React from 'react'
import { Helmet } from 'react-helmet'
import { withTranslation } from 'react-i18next'
import { connect } from 'react-redux'
import TimezonePicker from 'react-timezone'
import Message from '../Common/Message'
import { deleteUser, handleProfileFormSubmit } from '../../actions/user'
import { history } from '../../index'
import { languages } from '../NavBar/LanguageDropdown'
import CustomModal from '../Common/CustomModal'
import CustomTextArea from '../Common/CustomTextArea'
class ProfileEdit extends React.Component {
constructor(props, context) {
super(props, context)
this.state = {
formData: {},
displayModal: false,
}
}
componentDidMount() {
this.initForm()
}
componentDidUpdate(prevProps) {
if (prevProps.user !== this.props.user) {
this.initForm()
}
}
initForm() {
const { user } = this.props
const formData = {}
Object.keys(user).map(k =>
user[k] === null
? (formData[k] = '')
: k === 'birth_date'
? (formData[k] = format(new Date(user[k]), 'yyyy-MM-dd'))
: (formData[k] = user[k])
)
this.setState({ formData })
}
handleFormChange(e) {
const { formData } = this.state
if (e.target.name === 'weekm') {
formData.weekm = e.target.value === 'Monday'
} else {
formData[e.target.name] = e.target.value
}
this.setState(formData)
}
displayModal(value) {
this.setState(prevState => ({
...prevState,
displayModal: value,
}))
}
render() {
const { message, onDeleteUser, onHandleProfileFormSubmit, t, user } =
this.props
const { displayModal, formData } = this.state
return (
<div>
<Helmet>
<title>FitTrackee - {t('user:Profile Edition')}</title>
</Helmet>
{formData.isAuthenticated && (
<div className="container">
{displayModal && (
<CustomModal
title={t('common:Confirmation')}
text={t(
'user:Are you sure you want to delete your account? ' +
'All data will be deleted, this cannot be undone.'
)}
confirm={() => {
onDeleteUser(user.username)
this.displayModal(false)
}}
close={() => this.displayModal(false)}
/>
)}
<h1 className="page-title">{t('user:Profile Edition')}</h1>
<div className="row">
<div className="col-md-2" />
<div className="col-md-8">
<div className="card">
<div className="card-header">{user.username}</div>
<div className="card-body">
<div className="row">
<div className="col-md-12">
<form
onSubmit={event => {
event.preventDefault()
onHandleProfileFormSubmit(formData)
}}
>
<div className="form-group">
<label>
{t('user:Email')}:
<input
name="email"
className="form-control input-lg"
type="text"
value={formData.email}
readOnly
/>
</label>
</div>
<div className="form-group">
<label>
{t('user:Registration Date')}:
<input
name="createdAt"
className="form-control input-lg"
type="text"
value={formData.created_at}
disabled
/>
</label>
</div>
<div className="form-group">
<label>
{t('user:Password')}:
<input
name="password"
className="form-control input-lg"
type="password"
onChange={e => this.handleFormChange(e)}
/>
</label>
</div>
<div className="form-group">
<label>
{t('user:Password Confirmation')}:
<input
name="password_conf"
className="form-control input-lg"
type="password"
onChange={e => this.handleFormChange(e)}
/>
</label>
</div>
<hr />
<div className="form-group">
<label>
{t('user:First Name')}:
<input
name="first_name"
className="form-control input-lg"
type="text"
value={formData.first_name}
onChange={e => this.handleFormChange(e)}
/>
</label>
</div>
<div className="form-group">
<label>
{t('user:Last Name')}:
<input
name="last_name"
className="form-control input-lg"
type="text"
value={formData.last_name}
onChange={e => this.handleFormChange(e)}
/>
</label>
</div>
<div className="form-group">
<label>
{t('user:Birth Date')}
<input
name="birth_date"
className="form-control input-lg"
type="date"
value={formData.birth_date}
onChange={e => this.handleFormChange(e)}
/>
</label>
</div>
<div className="form-group">
<label>
{t('user:Location')}:
<input
name="location"
className="form-control input-lg"
type="text"
value={formData.location}
onChange={e => this.handleFormChange(e)}
/>
</label>
</div>
<div className="form-group">
<label>
{t('user:Bio')}:
<CustomTextArea
charLimit={200}
name="bio"
defaultValue={formData.bio}
onTextChange={e => this.handleFormChange(e)}
/>
</label>
</div>
<div className="form-group">
<label>
{t('user:Language')}:
<select
name="language"
className="form-control input-lg"
value={formData.language}
onChange={e => this.handleFormChange(e)}
>
{languages.map(lang => (
<option value={lang.name} key={lang.name}>
{lang.name}
</option>
))}
</select>
</label>
</div>
<div className="form-group">
<label>
{t('user:Timezone')}:
<TimezonePicker
className="form-control timezone-custom"
onChange={tz => {
const e = {
target: {
name: 'timezone',
value: tz ? tz : 'Europe/Paris',
},
}
this.handleFormChange(e)
}}
value={formData.timezone}
/>
</label>
</div>
<div className="form-group">
<label>
{t('user:First day of week')}:
<select
name="weekm"
className="form-control input-lg"
value={formData.weekm ? 'Monday' : 'Sunday'}
onChange={e => this.handleFormChange(e)}
>
<option value="Sunday">
{t('user:Sunday')}
</option>
<option value="Monday">
{t('user:Monday')}
</option>
</select>
</label>
</div>
<button type="submit" className="btn btn-primary">
{t('common:Submit')}
</button>
<button
className="btn btn-danger"
onClick={event => {
event.preventDefault()
this.displayModal(true)
}}
>
{t('user:Delete my account')}
</button>
<button
type="submit"
className="btn btn-secondary"
onClick={() => history.push('/profile')}
>
{t('common:Cancel')}
</button>
</form>
<Message message={message} t={t} />
</div>
</div>
</div>
</div>
</div>
<div className="col-md-2" />
</div>
</div>
)}
</div>
)
}
}
export default withTranslation()(
connect(
state => ({
location: state.router.location,
message: state.message,
user: state.user,
}),
dispatch => ({
onDeleteUser: username => {
dispatch(deleteUser(username))
},
onHandleProfileFormSubmit: formData => {
dispatch(handleProfileFormSubmit(formData))
},
})
)(ProfileEdit)
)

View File

@ -1,99 +0,0 @@
import React from 'react'
import { withTranslation } from 'react-i18next'
import { connect } from 'react-redux'
import { Redirect } from 'react-router-dom'
import Form from './Form'
import Message from '../Common/Message'
import { handleUserFormSubmit } from '../../actions/user'
import { isLoggedIn } from '../../utils'
class UserForm extends React.Component {
constructor(props, context) {
super(props, context)
this.state = {
formData: {
username: '',
email: '',
password: '',
password_conf: '',
},
}
}
componentDidUpdate(prevProps) {
if (prevProps.location.pathname !== this.props.location.pathname) {
this.emptyForm()
}
}
emptyForm() {
const { formData } = this.state
Object.keys(formData).map(k => (formData[k] = ''))
this.setState(formData)
}
onHandleFormChange(e) {
const { formData } = this.state
formData[e.target.name] = e.target.value
this.setState(formData)
}
render() {
const {
formType,
isRegistrationAllowed,
message,
messages,
onHandleUserFormSubmit,
t,
} = this.props
const { formData } = this.state
const { token } = this.props.location.query
return (
<div>
{isLoggedIn() || (formType === 'password reset' && !token) ? (
<Redirect to="/" />
) : (
<div>
<Message message={message} messages={messages} t={t} />
<Form
isRegistrationAllowed={isRegistrationAllowed}
formType={formType}
userForm={formData}
onHandleFormChange={event => this.onHandleFormChange(event)}
handleUserFormSubmit={event => {
event.preventDefault()
if (formType === 'password reset') {
formData.token = token
}
onHandleUserFormSubmit(formData, formType)
}}
/>
</div>
)}
</div>
)
}
}
export default withTranslation()(
connect(
state => ({
isRegistrationAllowed: state.application.config.is_registration_enabled,
location: state.router.location,
message: state.message,
messages: state.messages,
}),
dispatch => ({
onHandleUserFormSubmit: (formData, formType) => {
formType =
formType === 'password reset'
? 'password/update'
: formType === 'reset your password'
? 'password/reset-request'
: formType
dispatch(handleUserFormSubmit(formData, formType))
},
})
)(UserForm)
)

View File

@ -1,86 +0,0 @@
import React from 'react'
import { withTranslation } from 'react-i18next'
import { connect } from 'react-redux'
import CustomModal from '../Common/CustomModal'
import ProfileDetail from './ProfileDetail'
import { getOrUpdateData } from '../../actions'
import { deleteUser } from '../../actions/user'
class UserProfile extends React.Component {
constructor(props, context) {
super(props, context)
this.state = {
displayModal: false,
}
}
componentDidMount() {
this.props.loadUser(this.props.match.params.userName)
}
componentDidUpdate(prevProps) {
if (prevProps.match.params.userName !== this.props.match.params.userName) {
this.props.loadUser(this.props.match.params.userName)
}
}
displayModal(value) {
this.setState(prevState => ({
...prevState,
displayModal: value,
}))
}
render() {
const { t, currentUser, onDeleteUser, users } = this.props
const { displayModal } = this.state
const [user] = users
const editable = user ? currentUser.username === user.username : false
return (
<div>
{displayModal && (
<CustomModal
title={t('common:Confirmation')}
text={t(
'user:Are you sure you want to delete this account? ' +
'All data will be deleted, this cannot be undone.'
)}
confirm={() => {
onDeleteUser(user.username)
this.displayModal(false)
}}
close={() => this.displayModal(false)}
/>
)}
{user && (
<ProfileDetail
editable={editable}
isDeletable={currentUser.admin && !editable}
onDeleteUser={onDeleteUser}
displayModal={e => this.displayModal(e)}
t={t}
user={user}
/>
)}
</div>
)
}
}
export default withTranslation()(
connect(
state => ({
currentUser: state.user,
users: state.users.data,
}),
dispatch => ({
onDeleteUser: username => {
dispatch(deleteUser(username, true))
},
loadUser: userName => {
dispatch(getOrUpdateData('getData', 'users', { username: userName }))
},
})
)(UserProfile)
)