Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lex profile changes #128

Merged
merged 3 commits into from
Oct 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 44 additions & 1 deletion delta_web/delta/accounts/api.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from rest_framework import generics, permissions
from rest_framework.response import Response
from rest_framework import status
from knox.models import AuthToken
from .serializers import UserSerializer,RegisterSerializer,LoginSerializer
from django.db.utils import IntegrityError

# Register API
class RegisterAPI(generics.GenericAPIView):
Expand Down Expand Up @@ -59,10 +61,51 @@ def post(self,request,*args,**kwargs):
request.user.save()

return Response({
"response":"here"
"message":"Account " + request.user.username + " has successfully been deleted."
})
# deletion api
class UpdateAPI(generics.UpdateAPIView):
permission_classes = [
permissions.IsAuthenticated
]
serializer_class = UserSerializer

def patch(self,request,*args,**kwargs):
# TODO: check email
# PERFORM CHECKS
# update user
strNewUserName = request.data.get("username",None)
strNewEmail = request.data.get("email",None)
strNewFirstName = request.data.get("first_name",None)
strNewLastName = request.data.get("last_name",None)
strNewPassword = request.data.get("password",None)

if(strNewUserName):
try:
request.user.username = strNewUserName
request.user.save()
except Exception as e:
print(e)
return Response(data = {"message":"A user with that username already exists."},status=status.HTTP_500_INTERNAL_SERVER_ERROR)
if(strNewEmail):
try:
request.user.email = strNewEmail
request.user.save()
except Exception as e:
print(e)
return Response(data={"message":"Error with email."},status = status.HTTP_500_INTERNAL_SERVER_ERROR)
if(strNewFirstName) :
request.user.first_name = strNewFirstName
if(strNewLastName):
request.user.last_name = strNewLastName
if(strNewPassword):
request.user.set_password(strNewPassword)
request.user.save()


return Response({
"message":"Your account" + request.user.username + " has successfully been updated."
})

# Get User API
class UserAPI(generics.RetrieveAPIView):
Expand Down
4 changes: 4 additions & 0 deletions delta_web/delta/accounts/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id','username','email','first_name','last_name')
# cant change id
read_only_fields = ['id']



# Register serializer
class RegisterSerializer(serializers.ModelSerializer):
Expand Down
5 changes: 4 additions & 1 deletion delta_web/delta/accounts/urls.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
from django.urls import path, include
from .api import RegisterAPI,LoginAPI,UserAPI,DeleteAPI
from .api import RegisterAPI,LoginAPI,UserAPI,DeleteAPI,UpdateAPI
from knox import views as knox_views

urlpatterns = [
path('api/auth',include('knox.urls')),
path('api/auth/register',RegisterAPI.as_view()),
path('api/auth/login',LoginAPI.as_view()),
path('api/auth/update',UpdateAPI.as_view()),

path('api/auth/user',UserAPI.as_view()),

# delete user
path('api/auth/delete',DeleteAPI.as_view()),
# invalidates the token, so they need to log back in to grab the token
Expand Down
Binary file modified delta_web/delta/data/__pycache__/__init__.cpython-310.pyc
Binary file not shown.
Binary file modified delta_web/delta/data/__pycache__/admin.cpython-310.pyc
Binary file not shown.
Binary file modified delta_web/delta/data/__pycache__/api.cpython-310.pyc
Binary file not shown.
Binary file modified delta_web/delta/data/__pycache__/apps.cpython-310.pyc
Binary file not shown.
Binary file modified delta_web/delta/data/__pycache__/models.cpython-310.pyc
Binary file not shown.
Binary file modified delta_web/delta/data/__pycache__/serializers.cpython-310.pyc
Binary file not shown.
Binary file modified delta_web/delta/data/__pycache__/urls.cpython-310.pyc
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified delta_web/delta/db.sqlite3
Binary file not shown.
Binary file modified delta_web/delta/delta/__pycache__/__init__.cpython-310.pyc
Binary file not shown.
Binary file modified delta_web/delta/delta/__pycache__/settings.cpython-310.pyc
Binary file not shown.
Binary file modified delta_web/delta/delta/__pycache__/wsgi.cpython-310.pyc
Binary file not shown.
Binary file modified delta_web/delta/frontend/__pycache__/__init__.cpython-310.pyc
Binary file not shown.
Binary file modified delta_web/delta/frontend/__pycache__/admin.cpython-310.pyc
Binary file not shown.
Binary file modified delta_web/delta/frontend/__pycache__/apps.cpython-310.pyc
Binary file not shown.
Binary file modified delta_web/delta/frontend/__pycache__/models.cpython-310.pyc
Binary file not shown.
Binary file modified delta_web/delta/frontend/__pycache__/urls.cpython-310.pyc
Binary file not shown.
Binary file modified delta_web/delta/frontend/__pycache__/views.cpython-310.pyc
Binary file not shown.
Binary file not shown.
33 changes: 31 additions & 2 deletions delta_web/delta/frontend/src/actions/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// for requests
import axios from 'axios';

import {returnErrors} from './messages';
import { createMessage,returnErrors } from "./messages";

import {
USER_LOADED,
Expand All @@ -14,7 +14,9 @@ import {
LOGIN_FAIL,
LOGOUT_SUCCESS,
REGISTER_SUCCESS,
REGISTER_FAIL
REGISTER_FAIL,
USER_UPDATE_SUCCESS,
USER_UPDATE_FAIL,
} from './types';

// CHECK TOKEN & LOAD USER
Expand Down Expand Up @@ -135,6 +137,33 @@ export const deleteUser = () => (dispatch,getState) =>{
dispatch(returnErrors(err.response.data,err.response.status))
})
}
// PATCH USER (update fields of user)
//
export const updateUser = ({username, first_name, last_name, password, email}) => (dispatch,getState) => {
// data
const data = JSON.stringify({username, first_name, last_name, email,password});

axios.patch('/api/auth/update',data,tokenConfig(getState))
.then(res =>{
// dispatch message
dispatch(createMessage({updateUser:"User successfully updated."}))
dispatch({
type:USER_UPDATE_SUCCESS,
payload: res.data
});
})
.catch((err)=>{
// dispatch error
// TO DO:
// MODIFY ERROR RETURN IN API
dispatch(returnErrors(err.response.data,err.response.status));
// type of error
dispatch(createMessage({updateUserFail:err.response.data["message"]}))
dispatch({
type:USER_UPDATE_FAIL
})
});
};

// Setup config with token - helper function
// arrow func that takes in getState
Expand Down
4 changes: 4 additions & 0 deletions delta_web/delta/frontend/src/actions/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,7 @@ export const LOGOUT_SUCCESS = "LOGOUT_SUCCESS";
// register
export const REGISTER_SUCCESS = "REGISTER_SUCCESS";
export const REGISTER_FAIL = "REGISTER_FAIL";

// update user
export const USER_UPDATE_SUCCESS = "USER_UPDATE_SUCCESS";
export const USER_UPDATE_FAIL = "USER_UPDATE_FAIL";
6 changes: 6 additions & 0 deletions delta_web/delta/frontend/src/components/layout/Alerts.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ export class Alerts extends Component {
if(message.deleteCsvFile){
alert.success(message.deleteCsvFile);
}
if(message.updateUser){
alert.success(message.updateUser);
}
if(message.updateUserFail){
alert.error(message.updateUserFail);
}
if(message.passwordsDoNotMatch){
alert.error(message.passwordsDoNotMatch);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import {Link} from 'react-router-dom';
import {deleteUser} from "../../actions/auth";
import PropTypes from "prop-types";
import {connect} from "react-redux";
import ProfileForm from './ProfileForm';

export class ProfileDetailed extends Component {
static propTypes = {
deleteUser: PropTypes.func.isRequired,
auth:PropTypes.object.isRequired
}

onDelete =() =>{
this.props.deleteUser();
}
Expand All @@ -21,10 +23,7 @@ export class ProfileDetailed extends Component {
</h1>
<div>
<h4>Change your information</h4>
<h4>First Name: {user.first_name}</h4>
<h4>Last Name: {user.last_name}</h4>
<h4>Email: {user.email}</h4>
<h4>Username: {user.username}</h4>
<ProfileForm/>
</div>
<button className="btn btn-danger" onClick={this.onDelete}>
Remove account?
Expand Down
102 changes: 102 additions & 0 deletions delta_web/delta/frontend/src/components/profile/ProfileForm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import React, { Component } from 'react'
import { connect } from 'react-redux';
import PropTypes from 'prop-types'
import {updateUser} from "../../actions/auth"

export class ProfileForm extends Component{
static propTypes = {
auth:PropTypes.object.isRequired,
updateUser:PropTypes.func.isRequired
}

state = {
username: this.props.auth.user.username,
first_name: this.props.auth.user.first_name,
last_name: this.props.auth.user.last_name,
email: this.props.auth.user.email,
password:""
}
onChange = e => this.setState(
{[e.target.name]:e.target.value}
)
onSubmit = e =>{
e.preventDefault();
const data = this.state;
// call function
this.props.updateUser(data);
}

render(){
const {
username,
first_name,
last_name,
email,
password
} = this.state;
const {isAuthenticated, user} = this.props.auth;

return (
<form onSubmit = {this.onSubmit}>
<div>
First Name:
<input
name = "first_name"
value = {this.state.first_name}
onChange={this.onChange}
placeholder={user.first_name}
>
</input>
</div>
<div>
Last Name:
<input
name = "last_name"
value = {this.state.last_name}
onChange = {this.onChange}
placeholder={user.last_name}
>
</input>
</div>
<div>
Email:
<input
name = "email"
value = {this.state.email}
onChange={this.onChange}
placeholder={user.email}
>
</input>
</div>
<div>
Username
<input
name = "username"
value = {this.state.username}
onChange={this.onChange}
placeholder={user.username}
>
</input>
</div>
<div>
Password
<input
name = "password"
value = {this.state.password}
onChange = {this.onChange}
>
</input>
</div>
<button className="btn btn-success">
Update Information
</button>
</form>
)
}
}

const mapStateToProps = state =>({
auth:state.auth
})

export default connect(mapStateToProps,{updateUser})(ProfileForm);
Loading