-
Notifications
You must be signed in to change notification settings - Fork 5
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 #141 from DemocraciaEnRed/dev2.0
Ready for 2.0.0
- Loading branch information
Showing
109 changed files
with
15,104 additions
and
625 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,76 @@ | ||
import React from 'react' | ||
import styled from 'styled-components' | ||
|
||
|
||
const StyledAdminDrawer = styled.div` | ||
margin-left:auto; | ||
margin-right:auto; | ||
margin-top:2.5rem; | ||
margin-bottom:2.5rem; | ||
padding-right: 15px; | ||
border-right: 1px solid #dae1e7; | ||
@media (max-width: 700px) { | ||
width:100%; | ||
border-right: none; | ||
margin-bottom:1.5rem; | ||
} | ||
` | ||
|
||
const DrawerList = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
` | ||
|
||
const DrawerItem = styled.div` | ||
cursor:pointer; | ||
background: white; | ||
border: none; | ||
font-size: 1.6rem; | ||
text-align: left; | ||
padding: 15px; | ||
color: #454246 | ||
&:not(:last-child) { | ||
border-bottom: solid 1px #dae1e7; | ||
} | ||
` | ||
|
||
const buttons = [ | ||
{ | ||
"key":1, | ||
'name': 'Etiquetas', | ||
'value': 'tags' | ||
}, | ||
{ | ||
"key":2, | ||
'name':'Proyectos', | ||
'value':'projects' | ||
}, | ||
{ | ||
"key":3, | ||
'name':'Usuarios', | ||
'value':'users' | ||
} | ||
|
||
] | ||
|
||
const AdminDrawer = (props) => ( | ||
<StyledAdminDrawer id='admin-drawer'> | ||
<DrawerList> | ||
{buttons.map((button,idx) =><DrawerItem | ||
key={button.key} | ||
onClick={() => props.changeSection(button.value)}> | ||
|
||
{button.name} | ||
</DrawerItem>)} | ||
|
||
</DrawerList> | ||
|
||
</StyledAdminDrawer> | ||
) | ||
|
||
AdminDrawer.propTypes = { | ||
} | ||
|
||
export default AdminDrawer |
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,315 @@ | ||
import React, { Component } from 'react' | ||
import styled from 'styled-components' | ||
import FileBase64 from 'react-file-base64' | ||
import Jimp from 'jimp' | ||
import jump from 'jump.js' | ||
import ProfileForm from '../../elements/profile-form/component' | ||
import ProfileAvatar from '../../elements/profile-avatar/component' | ||
import ProfileName from '../../elements/profile-name/component' | ||
import ProfileLabel from '../../elements/profile-label/component' | ||
import ProfileInput from '../../elements/profile-input/component' | ||
import ProfileSelect from '../../elements/profile-select/component' | ||
import ProfileButtonWrapper from '../../elements/profile-button-wrapper/component' | ||
import ProfileTags from '../../elements/profile-tags/component' | ||
import Alert from '../../elements/alert/component' | ||
import SubmitInput from '../../elements/submit-input/component' | ||
import WithDocumentTagsContext from '../../components/document-tags-context/component' | ||
import { withRouter } from 'next/router' | ||
|
||
import getConfig from 'next/config' | ||
|
||
const { publicRuntimeConfig: { | ||
API_URL, | ||
} } = getConfig() | ||
|
||
const TagsNotificationCheckboxDiv = styled.div` | ||
width: 350px; | ||
display: flex; | ||
line-height: 15px; | ||
margin-top: 3px; | ||
font-size:13px; | ||
& > input { | ||
margin-right: 7px; | ||
margin-bottom: auto; | ||
} | ||
` | ||
|
||
const ButtonLink = styled.button` | ||
background-color: #5c97bc; | ||
font-size: 1.2rem; | ||
border-style: none; | ||
color: var(--white); | ||
font-family: var(--bold); | ||
padding: 0.7em 1.8em; | ||
background-color: #5c97bc; | ||
font-size: 1.4rem; | ||
margin: 1em 0 0; | ||
` | ||
|
||
const InputErrorSpan = styled.span` | ||
color: red; | ||
font-size: 1.2rem; | ||
` | ||
|
||
const genderOptions = [ | ||
{ 'name': '', 'value': '' }, | ||
{ 'name': 'Masculino', 'value': 'Masculino' }, | ||
{ 'name': 'Femenino', 'value': 'Femenino' }, | ||
{ 'name': 'Otro', 'value': 'Otro' }, | ||
{ 'name': 'Prefiero no especificar', 'value': 'Prefiero no especificar' } | ||
] | ||
|
||
class UserEdit extends Component { | ||
state = { | ||
avatar: null, | ||
user: null, | ||
occupation: "", | ||
gender: "", | ||
party: "", | ||
birthday: "", | ||
province: "", | ||
editMode: true, | ||
files: [], | ||
allTags: [], | ||
tags: [], | ||
tagsMaxReached: false, | ||
tagsNotification: "", | ||
isLoading: true, | ||
status: "pending", | ||
}; | ||
|
||
async componentWillMount() { | ||
this.setState({ allTags: await this.props.fetchDocumentTags() }); | ||
} | ||
|
||
componentDidMount() { | ||
this.fetchUser(); | ||
} | ||
|
||
fetchUser() { | ||
fetch(`${API_URL}/api/v1/users/${this.props.router.query.user}`) | ||
.then((resp) => resp.json()) | ||
.then((user) => | ||
this.setState({ | ||
user: user, | ||
occupation: user.fields.occupation || "", | ||
gender: user.fields.gender || "", | ||
party: user.fields.party || "", | ||
birthday: user.fields.birthday || "", | ||
province: user.fields.province || "", | ||
tags: user.fields.tags || [], | ||
tagsNotification: user.fields.tagsNotification || "", | ||
isLoading: true, | ||
}) | ||
) | ||
.catch((err) => console.error(err)); | ||
} | ||
|
||
// Callback~ | ||
getFiles = async (files) => { | ||
Jimp.read(Buffer.from(files.base64.split("base64,")[1], "base64")) | ||
.then(async (image) => { | ||
let optimizedImage = await image | ||
.cover(150, 150) | ||
.quality(90) | ||
.getBase64Async(Jimp.MIME_JPEG); | ||
this.setState({ avatar: optimizedImage }); | ||
}) | ||
.catch((err) => { | ||
console.error(err); | ||
}); | ||
this.setState({ files: files }); | ||
}; | ||
|
||
handleChange = (e) => { | ||
const target = e.target; | ||
const value = target.value; | ||
const name = target.name; | ||
this.setState({ | ||
[name]: value, | ||
}); | ||
}; | ||
|
||
handleTagClick = (tag) => { | ||
if (this.state.tagsMaxReached) this.setState({ tagsMaxReached: false }); | ||
|
||
const clickedTagId = tag._id; | ||
if (this.state.tags.includes(clickedTagId)) | ||
this.setState((prevState) => ({ | ||
tags: prevState.tags.filter((tagId) => tagId != clickedTagId), | ||
})); | ||
else { | ||
if (this.state.tags.length == 6) this.setState({ tagsMaxReached: true }); | ||
else | ||
this.setState((prevState) => ({ | ||
tags: prevState.tags.concat(clickedTagId), | ||
})); | ||
} | ||
}; | ||
|
||
handleSubmit = async (e) => { | ||
e.preventDefault(); | ||
const newData = { | ||
fields: { | ||
occupation: this.state.occupation || "", | ||
gender: this.state.gender || "", | ||
birthday: this.state.birthday || "", | ||
province: this.state.province || "", | ||
party: this.state.party || "", | ||
tags: this.state.tags || "", | ||
tagsNotification: this.state.tagsNotification || "", | ||
}, | ||
}; | ||
if (this.state.avatar) { | ||
newData.avatar = this.state.avatar; | ||
} | ||
await ( | ||
await fetch(`${API_URL}/api/v1/users/${this.state.user._id}`, { | ||
method: "PUT", | ||
headers: { | ||
"Content-Type": "application/json", | ||
Authorization: "Bearer " + this.props.token, | ||
}, | ||
body: JSON.stringify(newData), | ||
}).then((res) => { | ||
this.setState({ status: res.status === 200 ? "success" : "error" }); | ||
return res; | ||
}) | ||
).json(); | ||
jump(-1000); | ||
}; | ||
|
||
toggleTagsCheckboxChange = () => { | ||
this.setState(({ tagsNotification }) => ({ | ||
tagsNotification: !tagsNotification, | ||
})); | ||
}; | ||
|
||
dismissAlert = () => { | ||
this.setState({ | ||
status: "pending", | ||
}); | ||
}; | ||
|
||
render() { | ||
const { user, isLoading, status } = this.state; | ||
if (user) { | ||
return ( | ||
<> | ||
<ProfileForm onSubmit={this.handleSubmit}> | ||
<ProfileAvatar id={user.id} date={user.updatedAt} /> | ||
<ProfileName>{`${user.surnames}, ${user.names}`}</ProfileName> | ||
{/* <ProfileMail mail={user.arrayData.join(' - ')} /> */} | ||
|
||
{isLoading ? <p>...</p> : null} | ||
{this.state.editMode ? ( | ||
<div> | ||
<ProfileLabel htmlFor="avatar"> | ||
Imagen de perfil | ||
<FileBase64 | ||
multiple={false} | ||
onDone={this.getFiles} | ||
style={{ marginTop: "10px" }} | ||
/> | ||
</ProfileLabel> | ||
<ProfileLabel htmlFor="birthday"> | ||
Fecha de Nacimiento | ||
<ProfileInput | ||
type="text" | ||
name="birthday" | ||
value={this.state.birthday} | ||
onChange={this.handleChange} | ||
readOnly={false} | ||
disabled={false} | ||
placeholder="30/02/1900" | ||
/> | ||
</ProfileLabel> | ||
<ProfileLabel htmlFor="gender"> | ||
Género | ||
<ProfileSelect | ||
name="gender" | ||
value={this.state.gender} | ||
options={genderOptions} | ||
onChange={this.handleChange} | ||
/> | ||
</ProfileLabel> | ||
<ProfileLabel htmlFor="province"> | ||
Provincia / Localidad | ||
<ProfileInput | ||
type="text" | ||
name="province" | ||
value={this.state.province} | ||
readOnly={false} | ||
disabled={false} | ||
onChange={this.handleChange} | ||
/> | ||
</ProfileLabel> | ||
<ProfileLabel htmlFor="occupation"> | ||
Ocupación | ||
<ProfileInput | ||
type="text" | ||
name="occupation" | ||
value={this.state.occupation} | ||
readOnly={false} | ||
disabled={false} | ||
onChange={this.handleChange} | ||
/> | ||
</ProfileLabel> | ||
<ProfileLabel htmlFor="party"> | ||
Bloque | ||
<ProfileInput | ||
type="text" | ||
name="party" | ||
value={this.state.party} | ||
readOnly={false} | ||
disabled={false} | ||
onChange={this.handleChange} | ||
/> | ||
</ProfileLabel> | ||
|
||
<ProfileLabel htmlFor="tags"> | ||
Etiquetas de interés | ||
<TagsNotificationCheckboxDiv> | ||
<input | ||
type="checkbox" | ||
name="tagsNotification" | ||
checked={this.state.tagsNotification} | ||
onChange={this.toggleTagsCheckboxChange} | ||
/> | ||
Deseo recibir notificaciones de futuros proyectos asociados | ||
a mis etiquetas de interés | ||
</TagsNotificationCheckboxDiv> | ||
{this.state.tagsMaxReached && ( | ||
<InputErrorSpan> | ||
Se pueden elegir hasta 6 etiquetas de interés | ||
</InputErrorSpan> | ||
)} | ||
<ProfileTags | ||
name="tags" | ||
allTags={this.state.allTags} | ||
tags={this.state.tags} | ||
onTagClick={this.handleTagClick} | ||
/> | ||
</ProfileLabel> | ||
<ProfileButtonWrapper> | ||
<SubmitInput type="submit" value="Guardar cambios" /> | ||
</ProfileButtonWrapper> | ||
</div> | ||
) : null} | ||
</ProfileForm> | ||
{(status === "success" || status === "error") && ( | ||
<Alert status={status} dismissAlert={this.dismissAlert}> | ||
{status === "success" | ||
? "Los cambios que ha realizado en el perfil fueron guardados con éxito." | ||
: "Los cambios que ha tratado de guardar no han podido ser procesados. Le aconsejamos que lo intente nuevamente."} | ||
</Alert> | ||
)} | ||
</> | ||
); | ||
} else { | ||
return <div></div>; | ||
} | ||
} | ||
} | ||
|
||
export default WithDocumentTagsContext(withRouter(UserEdit)) |
Oops, something went wrong.