feat : [FE] UserUpdate API Implement.
This commit is contained in:
@@ -22,4 +22,6 @@ public class UserUpdate {
|
||||
private String email;
|
||||
private String bio;
|
||||
private String image;
|
||||
private String password;
|
||||
private String username;
|
||||
}
|
||||
|
||||
@@ -83,4 +83,8 @@ public class User implements UserDetails {
|
||||
this.bio = userUpdate.getBio();
|
||||
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.Modifying;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -16,4 +17,6 @@ public interface UserRepository extends JpaRepository<User, Long> {
|
||||
|
||||
Optional<User> findByUsername(String username);
|
||||
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));
|
||||
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());
|
||||
user.update(userUpdate);
|
||||
return convertUser(userRepository.save(user));
|
||||
|
||||
@@ -27,6 +27,11 @@ const routes = [
|
||||
name: "Article",
|
||||
component: () => import(/* webpackChunkName "inputTag" */ '@/views/TheArticle.vue')
|
||||
},
|
||||
{
|
||||
path: "/@:username",
|
||||
name: "Profile",
|
||||
component: () => import(/* webpackChunkName "inputTag" */ '@/views/TheProfile.vue')
|
||||
}
|
||||
];
|
||||
|
||||
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("/");
|
||||
})
|
||||
.catch(error =>{
|
||||
console.log(error);
|
||||
const code = error.response.data.errors.code;
|
||||
if(code == "DUPLICATE_EMAIL_USERNAME"){
|
||||
showEmailUsernameError();
|
||||
|
||||
@@ -10,22 +10,22 @@
|
||||
<form>
|
||||
<fieldset>
|
||||
<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 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 class="form-group">
|
||||
<textarea class="form-control form-control-lg" rows="8"
|
||||
placeholder="Short bio about you"></textarea>
|
||||
<textarea class="form-control form-control-lg" rows="8" placeholder="Short bio about you" v-model="user.bio">
|
||||
</textarea>
|
||||
</fieldset>
|
||||
<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 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>
|
||||
<button class="btn btn-lg btn-primary pull-xs-right">
|
||||
<button @click = "updateUser" class="btn btn-lg btn-primary pull-xs-right">
|
||||
Update Settings
|
||||
</button>
|
||||
</fieldset>
|
||||
@@ -38,8 +38,69 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import axios from "axios";
|
||||
import router from "@/router";
|
||||
import {onMounted, reactive} from "vue";
|
||||
|
||||
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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user