Skip to content

Commit 9848553

Browse files
author
maharshi
committed
Create and Update user functionality
1 parent aba6812 commit 9848553

File tree

11 files changed

+659
-64
lines changed

11 files changed

+659
-64
lines changed

app/Http/Controllers/APIController.php

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,23 @@ public function users(Request $request)
3535
return response()->json($response, 201);
3636
}
3737

38-
public function profile()
38+
public function profile(Request $request)
3939
{
4040
try{
4141
$user = JWTAuth::parseToken()->authenticate();
42+
if($request->user_id){ $user = User::find($request->user_id);}
43+
$response = ['success'=> true,'message' => 'user profile !!','data'=> $user];
44+
}catch (Exception $e){
45+
$response = ['success'=> false,'message' => '','data'=> $e->getMessage()];
46+
}
47+
return response()->json($response, 201);
48+
}
49+
50+
public function viewProfile(Request $request)
51+
{
52+
try{
53+
$user = JWTAuth::parseToken()->authenticate();
54+
if($request->user_id){ $user = User::find($request->user_id);}
4255
$response = ['success'=> true,'message' => 'user profile !!','data'=> $user];
4356
}catch (Exception $e){
4457
$response = ['success'=> false,'message' => '','data'=> $e->getMessage()];
@@ -67,7 +80,7 @@ public function updateProfile(Request $request)
6780
try{
6881
$user = JWTAuth::parseToken()->authenticate();
6982
$validator = Validator::make($request->all(), [
70-
'name' => ['required', 'string', 'min:6','max:20'],
83+
'name' => ['required', 'string', 'min:4','max:20'],
7184
'email' => ['required', 'email', Rule::unique('users')->ignore($user->id)],
7285
]);
7386

@@ -108,4 +121,56 @@ public function updateProfile(Request $request)
108121
}
109122
return response()->json($response, 201);
110123
}
124+
125+
public function createUser(Request $request)
126+
{
127+
try{
128+
$validator = Validator::make($request->all(), [
129+
'name' => ['required', 'string', 'min:4','max:20'],
130+
]);
131+
132+
if($request->update_user){
133+
$user = User::find($request->update_user);
134+
$avatar = @$user->avatar;
135+
$validator = Validator::make($request->all(), [
136+
'email' => ['required', 'email', Rule::unique('users')->ignore($user->id)],
137+
]);
138+
}else{
139+
$validator = Validator::make($request->all(), [
140+
'email' => ['required', 'email', 'min:6',Rule::unique('users')],
141+
]);
142+
}
143+
144+
if ($validator->fails()) {
145+
return response()->json([ 'success' => false, 'message' => $validator->errors()->first() ]);
146+
}
147+
148+
if ($request->avatar && !empty($request->avatar)){
149+
$image = $request->avatar;
150+
$avatar = time().'.' . explode('/', explode(':', substr($image, 0, strpos($image, ';')))[1])[1];
151+
Storage::disk('public')->putFileAs('avatar', $image,$avatar);
152+
}
153+
154+
$record = [
155+
'name' => $request->name,
156+
'email' => $request->email,
157+
'password' => \Hash::make($request->email),
158+
'avatar' => @$avatar,
159+
];
160+
161+
if($request->update_user) {
162+
User::where('id',$user->id)->update($record);
163+
$msg = 'User Updated !!';
164+
}else{
165+
User::create($record);
166+
$msg = 'User Created !!';
167+
}
168+
169+
$response = ['success'=> true,'message' => $msg,'data'=> ''];
170+
}catch (Exception $e){
171+
$response = ['success'=> false,'message' => '','data'=> $e->getMessage()];
172+
}
173+
return response()->json($response, 201);
174+
}
175+
111176
}

public/js/app.js

Lines changed: 322 additions & 28 deletions
Large diffs are not rendered by default.

resources/js/components/Layout/Menu.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import LoginModule from '../Login/Login';
55
import AdminModule from '../Dashboard/Dashboard';
66
import UserProfile from '../User/Profile';
77
import Users from '../User/UserList/Index';
8-
import UserData from '../User/Form/Index';
8+
import UserForm from '../User/Form/Index';
99
import PrivateRoute from '../RouteConfig/PrivateRoute';
1010
import PublicRoute from '../RouteConfig/PublicRoute';
1111
import LogoutModule from '../Layout/Logout/Index';
@@ -21,7 +21,8 @@ class Menu extends Component{
2121
<PrivateRoute path="/dashboard" component={AdminModule} exact />
2222
<PrivateRoute path="/profile" component={UserProfile} exact />
2323
<PrivateRoute path="/users" component={Users} exact />
24-
<PrivateRoute path="/user/data" component={UserData} exact />
24+
<PrivateRoute path="/user/create" component={UserForm} exact />
25+
<PrivateRoute path="/user/update/:id" component={props => <UserForm userID=":id" {...props} />} />
2526
<PrivateRoute path="/logout" component={LogoutModule} exact />
2627
<Route path="*" component={ErrorPage} />
2728
<Route path="" component={ErrorPage} />

resources/js/components/Layout/SideMenu.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React ,{Component} from 'react';
2-
import logo from '../../../../public/assets/images/favicon.svg'
2+
import logo from '../../../../public/assets/images/favicon.svg';
33
const DashboardIcon = require('react-feather/dist/icons/home').default;
44
const UsersIcon = require('react-feather/dist/icons/users').default;
55
import { NavLink } from "react-router-dom";

resources/js/components/User/Form/Index.js

Lines changed: 163 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,132 @@ import React ,{Component} from 'react';
22
import SideMenu from "../../Layout/SideMenu";
33
import Navigation from "../../Layout/TopNav";
44
import {connect} from "react-redux";
5+
import * as UserAction from "../UserList/Container/UserController";
6+
import {Link} from "react-router-dom";
57

8+
const NotificationIcon = require('react-feather/dist/icons/alert-triangle').default;
69
const UserIcon = require('react-feather/dist/icons/user').default;
710

11+
const validEmailRegex = RegExp(
12+
/^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i
13+
);
14+
const validateForm = errors => {
15+
let valid = true;
16+
Object.values(errors).forEach(val => val.length > 0 && (valid = false));
17+
return valid;
18+
};
19+
820
class Index extends Component{
921
constructor(props) {
1022
super(props);
23+
let userID = '';
24+
if(props.match.params.id){
25+
userID = props.match.params.id;
26+
}
27+
this.onFileChange = this.onFileChange.bind(this);
28+
this.onChange = this.onChange.bind(this);
29+
this.handleSubmit = this.handleSubmit.bind(this);
30+
this.state = {
31+
userID : userID,
32+
username: '',
33+
email: '',
34+
avatar: '',
35+
profile: [],
36+
errors: {
37+
username: '',
38+
email: '',
39+
}
40+
};
41+
}
42+
componentDidMount() {
43+
if(this.state.userID){
44+
this.props.getUserData(this.state.userID);
45+
}
46+
}
47+
48+
componentWillReceiveProps(nextProps) {
49+
this.setState({
50+
userID : nextProps.userID,
51+
username: nextProps.user_name,
52+
email: nextProps.user_email,
53+
avatar: nextProps.user_avatar,
54+
});
55+
}
56+
57+
onFileChange(event) {
58+
this.createImage(event.target.files[0]);
59+
};
60+
61+
createImage(file){
62+
let reader = new FileReader();
63+
reader.onload = (e) => {
64+
this.setState({
65+
profile: e.target.result,
66+
})
67+
}
68+
reader.readAsDataURL(file);
1169
}
12-
render() {
1370

71+
onChange(event){
72+
event.preventDefault();
73+
const { name, value } = event.target;
74+
let errors = this.state.errors;
75+
switch (name) {
76+
case 'username':
77+
errors.username =
78+
value.length < 4
79+
? 'Name must be at least 4 characters long!'
80+
: '';
81+
break;
82+
case 'email':
83+
errors.email =
84+
validEmailRegex.test(value)
85+
? ''
86+
: 'Please enter valid Email!';
87+
break;
88+
default:
89+
break;
90+
}
91+
this.setState({errors, [name]: value});
92+
}
93+
94+
handleSubmit(event) {
95+
event.preventDefault();
96+
const data = {
97+
avatar: this.state.profile,
98+
name: this.state.username,
99+
email: this.state.email,
100+
update_user: this.state.userID,
101+
};
102+
103+
if(validateForm(this.state.errors) && this.state.username !== '' && this.state.email !== '') {
104+
this.props.createUserData(data);
105+
}else{
106+
console.error('Invalid Form');
107+
}
108+
}
109+
110+
componentWillUnmount(){
111+
this.props.resetStateValue();
112+
return true;
113+
}
114+
115+
render() {
116+
let errorMessage = '';
117+
let defaultErrorStatus = '';
118+
const {errors} = this.state;
119+
if(this.props.message){
120+
errorMessage = this.props.message;
121+
defaultErrorStatus = this.props.errorStatus;
122+
}
123+
if(errors.email.length > 0){
124+
errorMessage = errors.email;
125+
defaultErrorStatus = 'alert alert-danger alert-dismissible show fade';
126+
}
127+
if(errors.username.length > 0){
128+
errorMessage = errors.username;
129+
defaultErrorStatus = 'alert alert-danger alert-dismissible show fade';
130+
}
14131
return (
15132
<div className="UserSaveLayout" >
16133
<div id="app">
@@ -19,24 +136,42 @@ class Index extends Component{
19136
<Navigation/>
20137
<div className="main-content container-fluid">
21138
<div className="page-title">
22-
<h4><UserIcon/> Create User</h4>
139+
<h4><UserIcon/> {this.state.userID ? 'Update Profile' : 'Create User'}</h4>
23140
<hr/>
24141
</div>
25142
<section id="basic-horizontal-layouts">
26143
<div className="row match-height">
27144
<div className="col-md-8 col-12">
28145
<div className="card">
146+
{this.state.avatar ?
147+
<div className="card-header bg-primary">
148+
<h4 className="card-title text-white">
149+
<div className="avatar avatar-xl mr-3">
150+
<img src={this.state.avatar} alt={this.state.username}/>
151+
</div>{this.state.username}
152+
</h4>
153+
</div>
154+
: ''}
29155
<div className="card-content">
30156
<div className="card-body">
31-
<form className="form form-horizontal" >
157+
{errorMessage.length > 0 &&
158+
<div className={defaultErrorStatus}>
159+
<NotificationIcon size={15}/> {errorMessage}.
160+
<button type="button" className="close" data-dismiss="alert"
161+
aria-label="Close">
162+
<span aria-hidden="true">×</span>
163+
</button>
164+
</div>
165+
}
166+
<form className="form form-horizontal" onSubmit={this.handleSubmit} encType="multipart/form-data" noValidate>
32167
<div className="form-body">
33168
<div className="row">
34169

35170
<div className="col-md-4">
36171
<label>Avatar</label>
37172
</div>
38173
<div className="col-md-8 form-group">
39-
<input type="file" className="form-control" name="profile" id={'profile'}/>
174+
<input type="file" onChange={this.onFileChange} className="form-control" name="profile" id={'profile'}/>
40175
</div>
41176

42177
<div className="col-md-4">
@@ -45,48 +180,33 @@ class Index extends Component{
45180
<div className="col-md-8 form-group">
46181
<input type="text"
47182
className="form-control" name="username"
48-
placeholder="User Name" />
183+
placeholder="User Name" onChange={this.onChange} autoComplete={'off'} value={this.state.username }/>
49184
</div>
50185
<div className="col-md-4">
51186
<label>Email</label>
52187
</div>
53188
<div className="col-md-8 form-group">
54189
<input type="email"
55190
className="form-control" name="email"
56-
placeholder="User Email" autoComplete={'off'}/>
191+
placeholder="User Email" onChange={this.onChange} autoComplete={'off'} value={this.state.email }/>
57192
</div>
58193
<div className="col-md-12">
59194
<hr/>
60195
</div>
61196

62-
<div className="col-md-4">
63-
<label>New Password</label>
64-
</div>
65-
<div className="col-md-8 form-group">
66-
<input type="password" id="password_confirmation"
67-
className="form-control" name="password_confirmation"
68-
placeholder="Enter new password" onChange={this.onChange} autoComplete={'off'}/>
69-
</div>
70-
71-
<div className="col-md-12">
72-
<hr/>
73-
</div>
74-
75197
<div className="col-sm-12 d-flex justify-content-end">
76-
<button type="submit"
77-
className="btn btn-primary mr-1 mb-1">Create User
198+
<button type="submit" className="btn btn-primary mr-1 mb-1">
199+
{this.state.userID ? 'Update User' : 'Save User'}
78200
</button>
201+
<Link to='/users' className={'float-right btn btn-danger mr-1 mb-1'} >Back</Link>
79202
</div>
80203
</div>
81-
82204
</div>
83205
</form>
84206
</div>
85207
</div>
86208
</div>
87209
</div>
88-
89-
90210
</div>
91211
</section>
92212
</div>
@@ -98,5 +218,23 @@ class Index extends Component{
98218
}
99219
}
100220

101-
export default Index;
221+
const mapStateToProps = state => {
222+
return {
223+
userID : state.UserSection.user_Id,
224+
user_name : state.UserSection.user_name,
225+
user_email : state.UserSection.user_email,
226+
user_avatar : state.UserSection.user_avatar,
227+
errorStatus : state.UserSection.status,
228+
message: state.UserSection.message,
229+
}
230+
};
231+
232+
const mapDispatchToProps = dispatch => {
233+
return {
234+
getUserData: (data) => dispatch(UserAction.getUserData(data)),
235+
createUserData: (data) => dispatch(UserAction.createUser(data)),
236+
resetStateValue: () => dispatch(UserAction.resetStateValue())
237+
};
238+
};
102239

240+
export default connect(mapStateToProps,mapDispatchToProps)(Index);

resources/js/components/User/Profile.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ class Profile extends Component{
5858
switch (name) {
5959
case 'username':
6060
errors.username =
61-
value.length < 4
62-
? 'Name must be at least 4 characters long!'
61+
value.length < 6
62+
? 'Name must be at least 6 characters long!'
6363
: '';
6464
break;
6565
case 'email':

0 commit comments

Comments
 (0)