API & Client: add timezone to user - #11
This commit is contained in:
parent
793ef22c59
commit
fe91040370
@ -49,6 +49,7 @@ def user_1_full():
|
||||
user.last_name = 'Doe'
|
||||
user.bio = 'just a random guy'
|
||||
user.location = 'somewhere'
|
||||
user.timezone = 'America/New_York'
|
||||
user.birth_date = datetime.datetime.strptime('01/01/1980', '%d/%m/%Y')
|
||||
db.session.add(user)
|
||||
db.session.commit()
|
||||
|
@ -397,6 +397,7 @@ def test_user_profile_minimal(app, user_1):
|
||||
assert data['data']['email'] == 'test@test.com'
|
||||
assert data['data']['created_at']
|
||||
assert not data['data']['admin']
|
||||
assert data['data']['timezone'] is None
|
||||
assert data['data']['nb_activities'] == 0
|
||||
assert data['data']['nb_sports'] == 0
|
||||
assert data['data']['total_distance'] == 0
|
||||
@ -434,6 +435,7 @@ def test_user_profile_full(app, user_1_full):
|
||||
assert data['data']['birth_date']
|
||||
assert data['data']['bio'] == 'just a random guy'
|
||||
assert data['data']['location'] == 'somewhere'
|
||||
assert data['data']['timezone'] == 'America/New_York'
|
||||
assert data['data']['nb_activities'] == 0
|
||||
assert data['data']['nb_sports'] == 0
|
||||
assert data['data']['total_distance'] == 0
|
||||
@ -469,6 +471,7 @@ def test_user_profile_with_activities(
|
||||
assert data['data']['email'] == 'test@test.com'
|
||||
assert data['data']['created_at']
|
||||
assert not data['data']['admin']
|
||||
assert data['data']['timezone'] is None
|
||||
assert data['data']['nb_activities'] == 2
|
||||
assert data['data']['nb_sports'] == 2
|
||||
assert data['data']['total_distance'] == 22
|
||||
@ -507,7 +510,8 @@ def test_user_profile_valid_update(app, user_1):
|
||||
bio='just a random guy',
|
||||
birth_date='1980-01-01',
|
||||
password='87654321',
|
||||
password_conf='87654321'
|
||||
password_conf='87654321',
|
||||
timezone='America/New_York'
|
||||
)),
|
||||
headers=dict(
|
||||
Authorization='Bearer ' + json.loads(
|
||||
@ -627,7 +631,8 @@ def test_user_profile_invalid_password(app, user_1):
|
||||
bio='just a random guy',
|
||||
birth_date='1980-01-01',
|
||||
password='87654321',
|
||||
password_conf='876543210'
|
||||
password_conf='876543210',
|
||||
timezone='America/New_York'
|
||||
)),
|
||||
headers=dict(
|
||||
Authorization='Bearer ' + json.loads(
|
||||
@ -661,6 +666,7 @@ def test_user_profile_missing_password_conf(app, user_1):
|
||||
bio='just a random guy',
|
||||
birth_date='1980-01-01',
|
||||
password='87654321',
|
||||
timezone='America/New_York'
|
||||
)),
|
||||
headers=dict(
|
||||
Authorization='Bearer ' + json.loads(
|
||||
|
@ -32,6 +32,7 @@ def test_single_user(app, user_1):
|
||||
assert data['data']['birth_date'] is None
|
||||
assert data['data']['bio'] is None
|
||||
assert data['data']['location'] is None
|
||||
assert data['data']['timezone'] is None
|
||||
assert data['data']['nb_activities'] == 0
|
||||
assert data['data']['nb_sports'] == 0
|
||||
assert data['data']['total_distance'] == 0
|
||||
@ -60,6 +61,7 @@ def test_single_user_with_activities(
|
||||
assert data['data']['birth_date'] is None
|
||||
assert data['data']['bio'] is None
|
||||
assert data['data']['location'] is None
|
||||
assert data['data']['timezone'] is None
|
||||
assert data['data']['nb_activities'] == 2
|
||||
assert data['data']['nb_sports'] == 2
|
||||
assert data['data']['total_distance'] == 22
|
||||
@ -105,10 +107,12 @@ def test_users_list(app, user_1, user_2):
|
||||
assert 'toto' in data['data']['users'][1]['username']
|
||||
assert 'test@test.com' in data['data']['users'][0]['email']
|
||||
assert 'toto@toto.com' in data['data']['users'][1]['email']
|
||||
assert data['data']['users'][0]['timezone'] is None
|
||||
assert data['data']['users'][0]['nb_activities'] == 0
|
||||
assert data['data']['users'][0]['nb_sports'] == 0
|
||||
assert data['data']['users'][0]['total_distance'] == 0
|
||||
assert data['data']['users'][0]['total_duration'] == '0:00:00'
|
||||
assert data['data']['users'][1]['timezone'] is None
|
||||
assert data['data']['users'][1]['nb_activities'] == 0
|
||||
assert data['data']['users'][1]['nb_sports'] == 0
|
||||
assert data['data']['users'][1]['total_distance'] == 0
|
||||
|
@ -12,6 +12,7 @@ def test_user_model(app, user_1):
|
||||
assert serialized_user['location'] is None
|
||||
assert serialized_user['birth_date'] is None
|
||||
assert serialized_user['picture'] is False
|
||||
assert serialized_user['timezone'] is None
|
||||
assert serialized_user['nb_activities'] == 0
|
||||
assert serialized_user['nb_sports'] == 0
|
||||
assert serialized_user['total_distance'] == 0
|
||||
|
@ -185,6 +185,7 @@ def edit_user(user_id):
|
||||
location = post_data.get('location')
|
||||
password = post_data.get('password')
|
||||
password_conf = post_data.get('password_conf')
|
||||
timezone = post_data.get('timezone')
|
||||
|
||||
if password is not None and password != '':
|
||||
if password_conf != password:
|
||||
@ -211,6 +212,7 @@ def edit_user(user_id):
|
||||
)
|
||||
if password is not None and password != '':
|
||||
user.password = password
|
||||
user.timezone = timezone
|
||||
db.session.commit()
|
||||
|
||||
response_object = {
|
||||
|
@ -22,6 +22,7 @@ class User(db.Model):
|
||||
location = db.Column(db.String(80), nullable=True)
|
||||
bio = db.Column(db.String(200), nullable=True)
|
||||
picture = db.Column(db.String(255), nullable=True)
|
||||
timezone = db.Column(db.String(50), nullable=True)
|
||||
activities = db.relationship('Activity',
|
||||
lazy=True,
|
||||
backref=db.backref('users', lazy='joined'))
|
||||
@ -111,6 +112,7 @@ class User(db.Model):
|
||||
'location': self.location,
|
||||
'birth_date': self.birth_date,
|
||||
'picture': self.picture is not None,
|
||||
'timezone': self.timezone,
|
||||
'nb_activities': nb_activity,
|
||||
'nb_sports': len(sports),
|
||||
'total_distance': float(total[0]) if total[0] else 0,
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""empty message
|
||||
"""add static map url to 'Activity' table
|
||||
|
||||
Revision ID: 5a42db64e872
|
||||
Revises: 92adde6ac0d0
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""empty message
|
||||
"""add static map id to 'Activity' table
|
||||
|
||||
Revision ID: 9f8c9c37da44
|
||||
Revises: 5a42db64e872
|
||||
|
28
fittrackee_api/migrations/versions/e82e5e9447de_.py
Normal file
28
fittrackee_api/migrations/versions/e82e5e9447de_.py
Normal file
@ -0,0 +1,28 @@
|
||||
"""add 'timezone' to 'User' table
|
||||
|
||||
Revision ID: e82e5e9447de
|
||||
Revises: 9f8c9c37da44
|
||||
Create Date: 2018-06-08 16:01:52.684935
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'e82e5e9447de'
|
||||
down_revision = '9f8c9c37da44'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('users', sa.Column('timezone', sa.String(length=50), nullable=True))
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column('users', 'timezone')
|
||||
# ### end Alembic commands ###
|
@ -26,6 +26,7 @@ def init_data():
|
||||
email='admin@example.com',
|
||||
password='mpwoadmin')
|
||||
admin.admin = True
|
||||
admin.timezone = 'Europe/Paris'
|
||||
db.session.add(admin)
|
||||
sport = Sport(label='Cycling (Sport)')
|
||||
sport.img = '/img/sports/cycling-sport.png'
|
||||
|
@ -208,6 +208,15 @@ input, textarea {
|
||||
max-width: 45px;
|
||||
max-height: 45px;
|
||||
}
|
||||
|
||||
.timezone-picker {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.timezone-picker-textfield {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.unlink {
|
||||
color: black;
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ function Profile ({ message, onDeletePicture, onUploadPicture, user }) {
|
||||
<p>Birth Date: {user.birthDate}</p>
|
||||
<p>Location: {user.location}</p>
|
||||
<p>Bio: {user.bio}</p>
|
||||
<p>Time zone: {user.timezone}</p>
|
||||
</div>
|
||||
<div className="col-md-4">
|
||||
{ user.picture === true && (
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React from 'react'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import { connect } from 'react-redux'
|
||||
import TimezonePicker from 'react-timezone'
|
||||
|
||||
import {
|
||||
initProfileForm,
|
||||
@ -151,6 +152,27 @@ class ProfileEdit extends React.Component {
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label>
|
||||
Timezone:
|
||||
<TimezonePicker
|
||||
className="form-control"
|
||||
onChange={tz => {
|
||||
const e = { target:
|
||||
{
|
||||
name: 'timezone',
|
||||
value: tz ? tz : 'Europe/Paris'
|
||||
}
|
||||
}
|
||||
onHandleFormChange(e)
|
||||
}}
|
||||
value={formProfile.timezone
|
||||
? formProfile.timezone
|
||||
: 'Europe/Paris'
|
||||
}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<input
|
||||
type="submit"
|
||||
className="btn btn-primary btn-lg btn-block"
|
||||
|
@ -53,6 +53,7 @@ export default class FitTrackeeApi {
|
||||
birth_date: form.birthDate,
|
||||
password: form.password,
|
||||
password_conf: form.passwordConf,
|
||||
timezone: form.timezone,
|
||||
},
|
||||
type: 'application/json',
|
||||
}
|
||||
|
@ -87,6 +87,7 @@ const formProfile = (state = initial.formProfile, action) => {
|
||||
birthDate: action.user.birthDate,
|
||||
location: action.user.location,
|
||||
bio: action.user.bio,
|
||||
timezone: action.user.timezone,
|
||||
},
|
||||
}
|
||||
case 'PROFILE_SUCCESS':
|
||||
@ -185,6 +186,9 @@ const user = (state = initial.user, action) => {
|
||||
picture: action.message.data.picture === true
|
||||
? action.message.data.picture
|
||||
: false,
|
||||
timezone: action.message.data.timezone
|
||||
? action.message.data.timezone
|
||||
: '',
|
||||
nbActivities: action.message.data.nb_activities,
|
||||
nbSports: action.message.data.nb_sports,
|
||||
totalDistance: action.message.data.total_distance,
|
||||
|
@ -17,6 +17,7 @@
|
||||
"react-router-dom": "^4.2.2",
|
||||
"react-router-redux": "^5.0.0-alpha.9",
|
||||
"react-scripts": "1.1.4",
|
||||
"react-timezone": "^1.0.5",
|
||||
"recharts": "^1.0.0-beta.10",
|
||||
"redux": "4.0.0",
|
||||
"redux-thunk": "^2.2.0"
|
||||
|
11
yarn.lock
11
yarn.lock
@ -1874,6 +1874,10 @@ classnames@2.2.5:
|
||||
version "2.2.5"
|
||||
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.5.tgz#fb3801d453467649ef3603c7d61a02bd129bde6d"
|
||||
|
||||
classnames@^2.2.5:
|
||||
version "2.2.6"
|
||||
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
|
||||
|
||||
clean-css@4.1.x:
|
||||
version "4.1.11"
|
||||
resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.1.11.tgz#2ecdf145aba38f54740f26cefd0ff3e03e125d6a"
|
||||
@ -7267,6 +7271,13 @@ react-smooth@1.0.0:
|
||||
raf "^3.2.0"
|
||||
react-transition-group "^2.2.1"
|
||||
|
||||
react-timezone@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/react-timezone/-/react-timezone-1.0.5.tgz#74ba4c9b2235ad8de3bb1303b66f70e6889337e8"
|
||||
dependencies:
|
||||
classnames "^2.2.5"
|
||||
prop-types "^15.6.0"
|
||||
|
||||
react-transition-group@^2.2.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.3.1.tgz#31d611b33e143a5e0f2d94c348e026a0f3b474b6"
|
||||
|
Loading…
Reference in New Issue
Block a user