p_accountのプロフィール、プロフィール編集、パスワード編集、退会確認、退会完了を完了

このコミットが含まれているのは:
トランギャー 2021-10-08 11:07:58 +07:00
コミット 829bca2ee9
6個のファイルの変更294行の追加79行の削除

ファイルの表示

@ -54,7 +54,7 @@ class FathersController extends Controller {
}
public function detail ($father_id) {
$father_select = ['id', 'email', 'company', 'image', 'tel'];
$father_select = ['id', 'email', 'company', 'image', 'tel', 'profile'];
// 親詳細の取得に成功
if ($result = Father::select($father_select)->where('id', $father_id)->orderBy('created_at', 'desc')->get()->toArray()) {

ファイルの表示

@ -1,6 +1,80 @@
import React, { useEffect, useState } from 'react';
import Notification from '../../component/notification';
import ModalAlert from '../../component/modal_alert';
const ProfileEdit = () => {
const [father, setFather] = useState(null);
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [email, setEmail] = useState('');
const [tel, setTel] = useState('');
const [profile, setProfile] = useState('');
const fatherId = document.getElementById('father_id').value;
const [showAlert, setShowAlert] = useState(false);
const [messageAlert, setMessageAlert] = useState(null);
const [textColor, setTextColor] = useState(null);
const [errors, setErrors] = useState({
firstName:'',
lastName:'',
email:'',
tel:'',
profile:''
})
useEffect(() => {
axios.get(`/api/fathers/detail/${fatherId}`).then((response) => {
if(response.data.status_code==200) {
console.log(response.data.params[0]);
setFather(response.data.params[0]);
setEmail(response.data.params[0]?.email);
setTel(response.data.params[0]?.tel);
setProfile(response.data.params[0]?.profile);
} else if(response.data.status_code==400){
//TODO
}
});
}, []);
async function handleClick() {
setErrors({
firstName:'',
lastName:'',
email: email ? '' : 'error',
tel: tel ? '' : 'error',
profile:''
});
if(email && tel) {
try {
const formdata = new FormData();
formdata.append('father_id', fatherId);
formdata.append('first_name', firstName);
formdata.append('last_name', lastName);
formdata.append('email', email);
formdata.append('tel', tel);
formdata.append('profile', profile);
axios.put(`/api/fathers/updateProfile/${fatherId}`, formdata)
.then(response => {
if(response.data.status_code == 200){
setMessageAlert(response.data.success_messages);
setTextColor("black");
} else {
setMessageAlert(response.data.success_messages);
}
setShowAlert(true);
});
} catch (error) {
console.log('error', error);
}
}
}
async function handleCloseAlert() {
setShowAlert(false);
};
return (
<div className="l-content">
<div className="l-content-w560">
@ -8,15 +82,7 @@ const ProfileEdit = () => {
<div className="l-content__ttl__left">
<h2>プロフィール編集</h2>
</div>
<div className="p-notification">
<div className="p-notification-icon">
<div className="p-notification-icon-wrap">
<div className="count">1</div>
<div className="p-notification-icon-bg"></div>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22.742 19.855" className="icon svg-icon svg-fill svg-y50" ><g fill="none" stroke="#080808" strokeLinecap="round" strokeLinejoin="round" strokeWidth="1.5" data-name="Icon feather-alert-triangle" transform="translate(0.777 0.75)"><path d="M11.188,5.322,2.6,19.659A2.028,2.028,0,0,0,4.334,22.7H21.51a2.028,2.028,0,0,0,1.734-3.042L14.656,5.322a2.028,2.028,0,0,0-3.468,0Z" data-name="パス 3" transform="translate(-2.328 -4.346)"/><path d="M18,13.5v6.91" data-name="パス 4" transform="translate(-7.406 -8.547)"/><path d="M18,25.5h0" data-name="パス 5" transform="translate(-7.406 -11.2)"/></g></svg>
</div>
</div>
</div>
<Notification />
</div>
<div className="l-content-wrap">
@ -27,26 +93,37 @@ const ProfileEdit = () => {
<form action="" className="edit-form">
<div className="edit-set">
<label className="control-label" htmlFor="nameSei"></label>
<input type="text" name="nameSei" value="" className="input-default input-nameSei input-h60 input-w480" id="nameSei" />
<input type="text" name="nameSei" value={ lastName } onChange={e=>setLastName(e.target.value)}
className={`input-default input-nameSei input-h60 input-w480 ${ errors['firstName'] != '' && "validation_error"}`} id="nameSei" />
</div>
<div className="edit-set">
<label className="control-label" htmlFor="nameMei"></label>
<input type="text" name="nameMei" value="" className="input-default input-nameMei input-h60 input-w480" id="nameMei" />
<input type="text" name="nameMei" value={ firstName } onChange={e=>setFirstName(e.target.value)}
className={`input-default input-nameMei input-h60 input-w480 ${ errors['lastName'] != '' && "validation_error"}`} id="nameMei" />
</div>
<div className="edit-set">
<label className="control-label" htmlFor="mail">メールアドレス</label>
<input type="email" name="mail" value="" className="input-default input-mail input-h60 input-w480" id="mail" />
<input type="email" name="mail" value={ email } onChange={e=>setEmail(e.target.value)}
className={`input-default input-mail input-h60 input-w480 ${ errors['email'] != '' && "validation_error"}`} id="mail" />
</div>
<div className="edit-set">
<label className="control-label" htmlFor="tel">電話番号</label>
<input type="tel" name="tel" value="" className="input-default input-tel input-h60 input-w480" id="tel" />
<input type="tel" name="tel" value={ tel } onChange={e=>setTel(e.target.value)}
className={`input-default input-tel input-h60 input-w480 ${ errors['tel'] != '' && "validation_error"}`} id="tel" />
</div>
<div className="edit-set">
<label className="control-label" htmlFor="profile_textarea">プロフィール</label>
<textarea name="data[UserProfile][description]" rows="8" className="textarea-default" id="profile_textarea"></textarea>
<textarea name="profile" value={ profile } onChange={e=>setProfile(e.target.value)} rows="8"
className={`textarea-default ${ errors['profile'] != '' && "validation_error"}`} id="profile_textarea" />
</div>
<button type="button" className="btn-edit btn-default btn-h70 btn-r14 btn-yellow">プロフィール更新</button>
<button
type="button"
onClick={e => {
e.preventDefault();
handleClick();
}}
className="btn-edit btn-default btn-h70 btn-r14 btn-yellow">プロフィール更新</button>
</form>
</div>
@ -54,6 +131,12 @@ const ProfileEdit = () => {
</div>
</div>
</div>
<ModalAlert
show={showAlert}
message={messageAlert}
textColor={textColor}
handleClose={handleCloseAlert}
/>
</div>
)
}

ファイルの表示

@ -1,15 +1,24 @@
import React, { useEffect, useState } from 'react';
import Notification from '../../component/notification';
import ModalAlert from '../../component/modal_alert';
import axios from 'axios';
import { useHistory } from 'react-router-dom'
const Profile = () => {
const [child, setChild] = useState(null);
const [father, setFather] = useState(null);
const history = useHistory();
const fatherId = document.getElementById('father_id').value;
const [image, setImage] = useState(null);
const [showAlert, setShowAlert] = useState(false);
const [messageAlert, setMessageAlert] = useState(null);
const [textColor, setTextColor] = useState(null);
useEffect(() => {
axios.get('/api/children/detail/1', {params: { father_id: 1 }}).then((response) => {
axios.get(`/api/fathers/detail/${fatherId}`).then((response) => {
if(response.data.status_code==200){
console.log(response.data.params[0]);
setChild(response.data.params[0]);
//console.log(response.data.params[0]);
setFather(response.data.params[0]);
setImage(response.data.params[0]?.image);
} else if(response.data.status_code==400){
//TODO
}
@ -17,7 +26,40 @@ const Profile = () => {
});
}, []);
if (!child) return null;
if (!father) return null;
const handleImageChange = (e) => {
e.preventDefault();
let reader = new FileReader();
let _file = e.target.files[0];
reader.readAsDataURL(_file);
reader.onloadend = () => {
setImage(reader.result);
};
//upload image
try {
const formdata = new FormData();
formdata.append('father_id', fatherId);
formdata.append('image', _file);
axios.put("/api/fathers/updateImage", formdata)
.then(response => {
if(response.data.status_code == 200){
setMessageAlert(response.data.success_messages);
setTextColor("black");
} else {
setMessageAlert(response.data.success_messages);
}
setShowAlert(true);
});
} catch (error) {
console.log('error', error);
}
};
async function handleCloseAlert() {
setShowAlert(false);
};
return (
<div className="l-content">
@ -26,20 +68,7 @@ const Profile = () => {
<div className="l-content__ttl__left">
<h2>プロフィール</h2>
</div>
<div className="p-notification">
<div className="p-notification-icon">
<div className="p-notification-icon-wrap">
<div className="count">1</div>
<div className="p-notification-icon-bg"></div>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22.742 19.855" className="icon svg-icon svg-fill svg-y50" >
<g fill="none" stroke="#080808" strokeLinecap="round" strokeLinejoin="round" strokeWidth="1.5" data-name="Icon feather-alert-triangle" transform="translate(0.777 0.75)">
<path d="M11.188,5.322,2.6,19.659A2.028,2.028,0,0,0,4.334,22.7H21.51a2.028,2.028,0,0,0,1.734-3.042L14.656,5.322a2.028,2.028,0,0,0-3.468,0Z" data-name="パス 3" transform="translate(-2.328 -4.346)"/>
<path d="M18,13.5v6.91" data-name="パス 4" transform="translate(-7.406 -8.547)"/><path d="M18,25.5h0" data-name="パス 5" transform="translate(-7.406 -11.2)"/>
</g>
</svg>
</div>
</div>
</div>
<Notification />
</div>
<div className="l-content-wrap">
@ -48,32 +77,35 @@ const Profile = () => {
<div className="profile-content">
<div className="profile-thumb">
{/* <label> */}
<input id="profile-file" type="file" className="profile-thumb-img" />
<img src={ child.image } id="profile-file-preview" className="profile-thumb__image" alt="" />
{/* <input id="profile-file" type="file" className="profile-thumb-img" onChange={(e) => handleImageChange(e)} /> */}
<img src={ image } id="profile-file-preview" className="profile-thumb__image" alt="" />
{/* </label> */}
<div className="profile-camera">
<label className="btn-default btn-camera btn-shadow">
<input id="profile-file" type="file" className="profile-thumb-img" />
<input id="profile-file" type="file" className="profile-thumb-img" accept=".png, .jpg, .jpeg" onChange={(e) => handleImageChange(e)} />
<i className="icon icon-camera"></i>
</label>
</div>
</div>
<p className="profile-name">{ child.last_name } { child.first_name }</p>
<p className="profile-name">{ father.last_name } { father.first_name }</p>
<div className="profile-info">
<div className="profile-info__item">
<p className="profile-info__icon">
<img src="../assets/img/icon/mail.svg" alt="メール" />
<img src="/assets/img/icon/mail.svg" alt="メール" />
</p>
<p className="txt">{ child.email }</p>
<p className="txt">{ father.email }</p>
</div>
<div className="profile-info__item">
<p className="profile-info__icon">
<img src="../assets/img/icon/phone.svg" alt="電話" />
<img src="/assets/img/icon/phone.svg" alt="電話" />
</p>
<p className="txt">{ child.tel }</p>
<p className="txt">{ father.tel }</p>
</div>
<div className="profile-info__item">
<p className="txt">{ child.company }</p>
<p className="profile-info__icon">
<img src="/assets/img/icon/building.svg" alt="会社名"/>
</p>
<p className="txt">{ father.company }</p>
</div>
</div>
<div className="p-profile-btn">
@ -107,11 +139,21 @@ const Profile = () => {
</div>
<div className="p-profile-txtLink">
<button type="button" className="a-icon txt-link">ログアウト</button>
<a href="/login/p-account">
<button type="button" className="a-icon txt-link">ログアウト</button>
</a>
</div>
<div className="p-profile-txtLink">
<button type="button" className="a-icon txt-link">退会する</button>
<button
onClick={e => {
e.preventDefault();
history.push({
pathname: '/p-account/profile/withdrawal',
state: {}
});
}}
type="button" className="a-icon txt-link">退会する</button>
</div>
</div>
@ -119,6 +161,12 @@ const Profile = () => {
</div>
</div>
</div>
<ModalAlert
show={showAlert}
message={messageAlert}
textColor={textColor}
handleClose={handleCloseAlert}
/>
</div>
)
}

ファイルの表示

@ -1,6 +1,51 @@
import React, { useEffect, useState } from 'react';
import Notification from '../../component/notification';
import ModalAlert from '../../component/modal_alert';
const ProfilePasswordEdit = () => {
const [newPassword, setNewPassword] = useState('');
const [confirmPassword, setConfirmPassword] = useState('');
const fatherId = document.getElementById('father_id').value;
const [showAlert, setShowAlert] = useState(false);
const [messageAlert, setMessageAlert] = useState(null);
const [textColor, setTextColor] = useState(null);
const [errors, setErrors] = useState({
confirmPassword:'',
newPassword:'',
})
async function handleClick() {
setErrors({
confirmPassword: confirmPassword ? '' : 'error',
newPassword: newPassword ? '' : 'error',
});
if(confirmPassword && newPassword) {
try {
const formdata = new FormData();
formdata.append('father_id', fatherId);
formdata.append('password', newPassword);
formdata.append('password_confirmation', confirmPassword);
axios.put(`/api/fathers/updatePassword/${fatherId}`, formdata)
.then(response => {
if(response.data.status_code == 200){
setMessageAlert(response.data.success_messages);
setTextColor("black");
} else {
setMessageAlert(response.data.success_messages);
}
setShowAlert(true);
});
} catch (error) {
console.log('error', error);
}
}
}
async function handleCloseAlert() {
setShowAlert(false);
};
return (
<div className="l-content">
<div className="l-content-w560">
@ -8,15 +53,7 @@ const ProfilePasswordEdit = () => {
<div className="l-content__ttl__left">
<h2>パスワード編集</h2>
</div>
<div className="p-notification">
<div className="p-notification-icon">
<div className="p-notification-icon-wrap">
<div className="count">1</div>
<div className="p-notification-icon-bg"></div>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22.742 19.855" className="icon svg-icon svg-fill svg-y50" ><g fill="none" stroke="#080808" strokeLinecap="round" strokeLinejoin="round" strokeWidth="1.5" data-name="Icon feather-alert-triangle" transform="translate(0.777 0.75)"><path d="M11.188,5.322,2.6,19.659A2.028,2.028,0,0,0,4.334,22.7H21.51a2.028,2.028,0,0,0,1.734-3.042L14.656,5.322a2.028,2.028,0,0,0-3.468,0Z" data-name="パス 3" transform="translate(-2.328 -4.346)"/><path d="M18,13.5v6.91" data-name="パス 4" transform="translate(-7.406 -8.547)"/><path d="M18,25.5h0" data-name="パス 5" transform="translate(-7.406 -11.2)"/></g></svg>
</div>
</div>
</div>
<Notification />
</div>
<div className="l-content-wrap">
@ -27,14 +64,22 @@ const ProfilePasswordEdit = () => {
<form action="" className="edit-form">
<div className="edit-set">
<label className="control-label" htmlFor="new_password">パスワード</label>
<input type="text" name="new_password" value="" className="input-default input-new-password input-h60 input-w480" id="new_password" />
<input type="password" name="new_password" value={ newPassword } onChange={e=>setNewPassword(e.target.value)}
className={`input-default input-new-password input-h60 input-w480 ${ errors['newPassword'] != '' && "validation_error"}`} id="new_password" />
</div>
<div className="edit-set">
<label className="control-label" htmlFor="confirm_password">確認用 新しいパスワード</label>
<input type="text" name="confirm_password" value="" className="input-default input-confirm-password input-h60 input-w480" id="confirm_password" />
<input type="password" name="confirm_password" value={ confirmPassword } onChange={e=>setConfirmPassword(e.target.value)}
className={`input-default input-confirm-password input-h60 input-w480 ${ errors['newPassword'] != '' && "validation_error"}`} id="confirm_password" />
</div>
<button type="button" className="btn-edit btn-default btn-h70 btn-r14 btn-yellow">パスワード更新</button>
<button
type="button"
onClick={e => {
e.preventDefault();
handleClick();
}}
className="btn-edit btn-default btn-h70 btn-r14 btn-yellow">パスワード更新</button>
</form>
</div>
@ -42,6 +87,12 @@ const ProfilePasswordEdit = () => {
</section>
</div>
</div>
<ModalAlert
show={showAlert}
message={messageAlert}
textColor={textColor}
handleClose={handleCloseAlert}
/>
</div>
)
}

ファイルの表示

@ -1,6 +1,46 @@
import React, { useEffect, useState } from 'react';
import Notification from '../../component/notification';
import { useHistory } from 'react-router-dom'
const ProfileWithdrawal = () => {
const history = useHistory();
const fatherId = document.getElementById('father_id').value;
async function handleClick() {
try {
axios.delete(`/api/fathers/delete/${fatherId}`)
.then(response => {
if(response.data.status_code == 200) {
axios.delete(`/api/email-activations/deleteRelationFather/${fatherId}`)
.then(response => {
if(response.data.status_code == 200) {
} else {
}
});
axios.delete(`/api/father-relations/deleteRelationFather/${fatherId}`)
.then(response => {
if(response.data.status_code == 200){
} else {
}
});
axios.delete(`/api/meetings/deleteRelationFather/${fatherId}`)
.then(response => {
if(response.data.status_code == 200){
} else {
}
});
}
});
history.push({
pathname: '/p-account/profile/withdrawal/complete',
state: {}
});
} catch (error) {
console.log('error', error);
}
}
return (
<div className="l-content">
<div className="l-content-w560">
@ -8,15 +48,7 @@ const ProfileWithdrawal = () => {
<div className="l-content__ttl__left">
<h2>退会確認</h2>
</div>
<div className="p-notification">
<div className="p-notification-icon">
<div className="p-notification-icon-wrap">
<div className="count">1</div>
<div className="p-notification-icon-bg"></div>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22.742 19.855" className="icon svg-icon svg-fill svg-y50" ><g fill="none" stroke="#080808" strokeLinecap="round" strokeLinejoin="round" strokeWidth="1.5" data-name="Icon feather-alert-triangle" transform="translate(0.777 0.75)"><path d="M11.188,5.322,2.6,19.659A2.028,2.028,0,0,0,4.334,22.7H21.51a2.028,2.028,0,0,0,1.734-3.042L14.656,5.322a2.028,2.028,0,0,0-3.468,0Z" data-name="パス 3" transform="translate(-2.328 -4.346)"/><path d="M18,13.5v6.91" data-name="パス 4" transform="translate(-7.406 -8.547)"/><path d="M18,25.5h0" data-name="パス 5" transform="translate(-7.406 -11.2)"/></g></svg>
</div>
</div>
</div>
<Notification />
</div>
<div className="l-content-wrap">
@ -29,7 +61,13 @@ const ProfileWithdrawal = () => {
<p>本当に退会してもよろしいでしょうか</p>
</div>
<button type="button" className="btn-edit btn-default btn-h70 btn-r14 btn-yellow">退会する</button>
<button
onClick={e => {
e.preventDefault();
handleClick();
}}
type="button" className="btn-edit btn-default btn-h70 btn-r14 btn-yellow">退会する</button>
</form>
</div>

ファイルの表示

@ -1,4 +1,5 @@
import React, { useEffect, useState } from 'react';
import Notification from '../../component/notification';
const ProfileWithdrawalComplete = () => {
return (
@ -8,15 +9,7 @@ const ProfileWithdrawalComplete = () => {
<div className="l-content__ttl__left">
<h2>退会完了</h2>
</div>
<div className="p-notification">
<div className="p-notification-icon">
<div className="p-notification-icon-wrap">
<div className="count">1</div>
<div className="p-notification-icon-bg"></div>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22.742 19.855" className="icon svg-icon svg-fill svg-y50" ><g fill="none" stroke="#080808" strokeLinecap="round" strokeLinejoin="round" strokeWidth="1.5" data-name="Icon feather-alert-triangle" transform="translate(0.777 0.75)"><path d="M11.188,5.322,2.6,19.659A2.028,2.028,0,0,0,4.334,22.7H21.51a2.028,2.028,0,0,0,1.734-3.042L14.656,5.322a2.028,2.028,0,0,0-3.468,0Z" data-name="パス 3" transform="translate(-2.328 -4.346)"/><path d="M18,13.5v6.91" data-name="パス 4" transform="translate(-7.406 -8.547)"/><path d="M18,25.5h0" data-name="パス 5" transform="translate(-7.406 -11.2)"/></g></svg>
</div>
</div>
</div>
<Notification />
</div>
<div className="l-content-wrap">
@ -29,7 +22,9 @@ const ProfileWithdrawalComplete = () => {
</div>
<div className="edit-txtLink">
<button type="button" className="a-icon txt-link">トップページへ戻る</button>
<a href="/p-account">
<button type="button" className="a-icon txt-link">トップページへ戻る</button>
</a>
</div>
</div>