feat : [FE] UserUpdate API Implement.
This commit is contained in:
@@ -22,4 +22,6 @@ public class UserUpdate {
|
|||||||
private String email;
|
private String email;
|
||||||
private String bio;
|
private String bio;
|
||||||
private String image;
|
private String image;
|
||||||
|
private String password;
|
||||||
|
private String username;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,4 +83,8 @@ public class User implements UserDetails {
|
|||||||
this.bio = userUpdate.getBio();
|
this.bio = userUpdate.getBio();
|
||||||
this.image = userUpdate.getImage();
|
this.image = userUpdate.getImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void changePassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.io.realworld.domain.aggregate.user.entity.User;
|
|||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.data.jpa.repository.Modifying;
|
import org.springframework.data.jpa.repository.Modifying;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@@ -16,4 +17,6 @@ public interface UserRepository extends JpaRepository<User, Long> {
|
|||||||
|
|
||||||
Optional<User> findByUsername(String username);
|
Optional<User> findByUsername(String username);
|
||||||
List<User> findAll();
|
List<User> findAll();
|
||||||
|
|
||||||
|
List<User> findAllByUsername(String username);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,6 +80,16 @@ public class UserServiceImpl implements UserService {
|
|||||||
.findAny().ifPresent(found -> new CustomException(Error.DUPLICATE_EMAIL));
|
.findAny().ifPresent(found -> new CustomException(Error.DUPLICATE_EMAIL));
|
||||||
user.changeEmail(userUpdate.getEmail());
|
user.changeEmail(userUpdate.getEmail());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(userUpdate.getUsername() != null){
|
||||||
|
userRepository.findAllByUsername(userUpdate.getUsername())
|
||||||
|
.stream().filter(found -> !found.getId().equals(userRepository.findById(user.getId())))
|
||||||
|
.findAny().ifPresent(found -> new CustomException(Error.DUPLICATE_EMAIL));
|
||||||
|
user.changeUsername(userUpdate.getUsername());
|
||||||
|
}
|
||||||
|
if(userUpdate.getPassword() != null){
|
||||||
|
user.changePassword(madeHash(userUpdate.getPassword()));
|
||||||
|
}
|
||||||
userUpdate.setId(user.getId());
|
userUpdate.setId(user.getId());
|
||||||
user.update(userUpdate);
|
user.update(userUpdate);
|
||||||
return convertUser(userRepository.save(user));
|
return convertUser(userRepository.save(user));
|
||||||
|
|||||||
@@ -27,6 +27,11 @@ const routes = [
|
|||||||
name: "Article",
|
name: "Article",
|
||||||
component: () => import(/* webpackChunkName "inputTag" */ '@/views/TheArticle.vue')
|
component: () => import(/* webpackChunkName "inputTag" */ '@/views/TheArticle.vue')
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/@:username",
|
||||||
|
name: "Profile",
|
||||||
|
component: () => import(/* webpackChunkName "inputTag" */ '@/views/TheProfile.vue')
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
|
|||||||
99
src/vite-frontend/src/views/TheProfile.vue
Normal file
99
src/vite-frontend/src/views/TheProfile.vue
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<div class="profile-page">
|
||||||
|
|
||||||
|
<div class="user-info">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col-xs-12 col-md-10 offset-md-1">
|
||||||
|
<img src="http://i.imgur.com/Qr71crq.jpg" class="user-img"/>
|
||||||
|
<h4>Eric Simons</h4>
|
||||||
|
<p>
|
||||||
|
Cofounder @GoThinkster, lived in Aol's HQ for a few months, kinda looks like Peeta from the
|
||||||
|
Hunger Games
|
||||||
|
</p>
|
||||||
|
<button class="btn btn-sm btn-outline-secondary action-btn">
|
||||||
|
<i class="ion-plus-round"></i>
|
||||||
|
|
||||||
|
Follow Eric Simons
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col-xs-12 col-md-10 offset-md-1">
|
||||||
|
<div class="articles-toggle">
|
||||||
|
<ul class="nav nav-pills outline-active">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link active" href="">My Articles</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="">Favorited Articles</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="article-preview">
|
||||||
|
<div class="article-meta">
|
||||||
|
<a href=""><img src="http://i.imgur.com/Qr71crq.jpg"/></a>
|
||||||
|
<div class="info">
|
||||||
|
<a href="" class="author">Eric Simons</a>
|
||||||
|
<span class="date">January 20th</span>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-outline-primary btn-sm pull-xs-right">
|
||||||
|
<i class="ion-heart"></i> 29
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<a href="" class="preview-link">
|
||||||
|
<h1>How to build webapps that scale</h1>
|
||||||
|
<p>This is the description for the post.</p>
|
||||||
|
<span>Read more...</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="article-preview">
|
||||||
|
<div class="article-meta">
|
||||||
|
<a href=""><img src="http://i.imgur.com/N4VcUeJ.jpg"/></a>
|
||||||
|
<div class="info">
|
||||||
|
<a href="" class="author">Albert Pai</a>
|
||||||
|
<span class="date">January 20th</span>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-outline-primary btn-sm pull-xs-right">
|
||||||
|
<i class="ion-heart"></i> 32
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<a href="" class="preview-link">
|
||||||
|
<h1>The song you won't ever stop singing. No matter how hard you try.</h1>
|
||||||
|
<p>This is the description for the post.</p>
|
||||||
|
<span>Read more...</span>
|
||||||
|
<ul class="tag-list">
|
||||||
|
<li class="tag-default tag-pill tag-outline">Music</li>
|
||||||
|
<li class="tag-default tag-pill tag-outline">Song</li>
|
||||||
|
</ul>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: "TheProfile.vue"
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -87,7 +87,6 @@ export default {
|
|||||||
router.push("/");
|
router.push("/");
|
||||||
})
|
})
|
||||||
.catch(error =>{
|
.catch(error =>{
|
||||||
console.log(error);
|
|
||||||
const code = error.response.data.errors.code;
|
const code = error.response.data.errors.code;
|
||||||
if(code == "DUPLICATE_EMAIL_USERNAME"){
|
if(code == "DUPLICATE_EMAIL_USERNAME"){
|
||||||
showEmailUsernameError();
|
showEmailUsernameError();
|
||||||
|
|||||||
@@ -10,22 +10,22 @@
|
|||||||
<form>
|
<form>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<fieldset class="form-group">
|
<fieldset class="form-group">
|
||||||
<input class="form-control" type="text" placeholder="URL of profile picture">
|
<input class="form-control" type="text" placeholder="URL of profile picture" v-model="user.image">
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset class="form-group">
|
<fieldset class="form-group">
|
||||||
<input class="form-control form-control-lg" type="text" placeholder="Your Name">
|
<input class="form-control form-control-lg" type="text" placeholder="Your Name" v-model="user.username">
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset class="form-group">
|
<fieldset class="form-group">
|
||||||
<textarea class="form-control form-control-lg" rows="8"
|
<textarea class="form-control form-control-lg" rows="8" placeholder="Short bio about you" v-model="user.bio">
|
||||||
placeholder="Short bio about you"></textarea>
|
</textarea>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset class="form-group">
|
<fieldset class="form-group">
|
||||||
<input class="form-control form-control-lg" type="text" placeholder="Email">
|
<input class="form-control form-control-lg" type="text" placeholder="Email" v-model="user.email">
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset class="form-group">
|
<fieldset class="form-group">
|
||||||
<input class="form-control form-control-lg" type="password" placeholder="Password">
|
<input class="form-control form-control-lg" type="password" placeholder="Password" v-model="password">
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<button class="btn btn-lg btn-primary pull-xs-right">
|
<button @click = "updateUser" class="btn btn-lg btn-primary pull-xs-right">
|
||||||
Update Settings
|
Update Settings
|
||||||
</button>
|
</button>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
@@ -38,8 +38,69 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import axios from "axios";
|
||||||
|
import router from "@/router";
|
||||||
|
import {onMounted, reactive} from "vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "TheSetting"
|
name: "TheSetting",
|
||||||
|
setup() {
|
||||||
|
const url = import.meta.env.VITE_BASE_URL;
|
||||||
|
const token = localStorage.getItem("token");
|
||||||
|
const user = reactive({
|
||||||
|
bio: "",
|
||||||
|
email: "",
|
||||||
|
image: "",
|
||||||
|
username: "",
|
||||||
|
password: "",
|
||||||
|
})
|
||||||
|
const password = "";
|
||||||
|
|
||||||
|
const getUser = (getuser: { bio: string; email: string; username: string; image: string; }) => {
|
||||||
|
user.bio = getuser.bio
|
||||||
|
user.email = getuser.email
|
||||||
|
user.username = getuser.username
|
||||||
|
user.image = user.image
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateUser = () => {
|
||||||
|
console.log(token,user);
|
||||||
|
axios.put(url+'/api/user',{user},{
|
||||||
|
headers:{
|
||||||
|
Authorization : "TOKEN " + token,
|
||||||
|
"Content-Type": `application/json`,
|
||||||
|
}})
|
||||||
|
.then(response => {
|
||||||
|
console.log(response);
|
||||||
|
router.push('/@'+ response.data.user.username);
|
||||||
|
|
||||||
|
})
|
||||||
|
.catch(error =>{
|
||||||
|
const code = error.response.data.errors.code;
|
||||||
|
//TODO 예외처리
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
axios.get(url+'/api/user',{
|
||||||
|
headers:{
|
||||||
|
Authorization : "TOKEN " + token
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
console.log(response)
|
||||||
|
window.localStorage.setItem("token",response.data.user.token);
|
||||||
|
getUser(response.data.user);
|
||||||
|
|
||||||
|
})
|
||||||
|
.catch(error =>{
|
||||||
|
const code = error.response.data.errors.code;
|
||||||
|
//TODO 예외처리
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return {user, password, url, token, getUser, updateUser};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user