Merge pull request #37 from nakazawakan/feature/admin

Feature/admin
このコミットが含まれているのは:
I love Github 2021-10-09 10:27:43 -07:00 committed by GitHub
コミット 7e96af90ff
この署名に対応する既知のキーがデータベースに存在しません
GPGキーID: 4AEE18F83AFDEB23
31個のファイルの変更3925行の追加396行の削除

ファイルの表示

@ -11233,55 +11233,55 @@ input[type=date].hide-calender::-webkit-inner-spin-button, input[type=date].hide
}
.ft-12 {
font-size: 12px !important;
font-size: 12px;
}
.ft-13 {
font-size: 13px !important;
font-size: 13px;
}
.ft-14 {
font-size: 14px !important;
font-size: 14px;
}
.ft-15 {
font-size: 15px !important;
font-size: 15px;
}
.ft-16 {
font-size: 16px !important;
font-size: 16px;
}
.ft-17 {
font-size: 17px !important;
font-size: 17px;
}
.ft-18 {
font-size: 18px !important;
font-size: 18px;
}
.ft-19 {
font-size: 19px !important;
font-size: 19px;
}
.ft-20 {
font-size: 20px !important;
font-size: 20px;
}
.ft-25 {
font-size: 25px !important;
font-size: 25px;
}
.ft-30 {
font-size: 30px !important;
font-size: 30px;
}
.ft-35 {
font-size: 35px !important;
font-size: 35px;
}
.ft-40 {
font-size: 40px !important;
font-size: 40px;
}
@media (max-width: 991.98px) {
@ -11739,6 +11739,70 @@ input[type=date].hide-calender::-webkit-inner-spin-button, input[type=date].hide
}
}
.w-15-px {
width: 15px;
}
.w-20-px {
width: 20px;
}
.w-25-px {
width: 25px;
}
.w-30-px {
width: 30px;
}
.w-35-px {
width: 35px;
}
.w-40-px {
width: 40px;
}
.w-45-px {
width: 45px;
}
.w-50-px {
width: 50px;
}
.h-15-px {
height: 15px;
}
.h-20-px {
height: 20px;
}
.h-25-px {
height: 25px;
}
.h-30-px {
height: 30px;
}
.h-35-px {
height: 35px;
}
.h-40-px {
height: 40px;
}
.h-45-px {
height: 45px;
}
.h-50-px {
height: 50px;
}
.pointer:hover {
cursor: pointer;
}

2639
backend/public/js/app.js vendored

ファイル差分が大きすぎるため省略します 差分を読み込み

ファイルの表示

@ -5,6 +5,17 @@ import { BrowserRouter, Route, Switch } from 'react-router-dom';
import Meeting from './meeting';
import MeetingDetail from './meeting/detail';
import Child from './child';
import ChildDetail from './child/detail';
import ChildEdit from './child/edit';
import ChildPasswordEdit from './child/password_edit';
import Parent from './parent';
import ParentDetail from './parent/detail';
import ParentEdit from './parent/edit';
import ParentPasswordEdit from './parent/password_edit';
import ParentRegister from './parent/register';
import Side from './side';
export default class AdminApp extends Component {
@ -15,16 +26,18 @@ export default class AdminApp extends Component {
<Switch>
<Route exact path='/admin/meeting' component={Meeting} />
<Route exact path='/admin/meeting/detail/:meeting_id' component={MeetingDetail} />
{/* <Route exact path='/admin/meeting/edit/:meeting_id' component={} />
<Route exact path='/admin/parent' component={} />
<Route exact path='/admin/parent/detail/:father_id' component={} />
<Route exact path='/admin/parent/edit/:father_id' component={} />
<Route exact path='/admin/parent/edit/password/:father_id' component={} />
<Route exact path='/admin/parent/register' component={} />
<Route exact path='/admin/child' component={} />
<Route exact path='/admin/child/detail/:child_id' component={} />
<Route exact path='/admin/child/edit/:child_id' component={} />
<Route exact path='/admin/child/edit/password/:father_id' component={} /> */}
{/* <Route exact path='/admin/meeting/edit/:meeting_id' component={} /> */}
<Route exact path='/admin/child' component={Child} />
<Route exact path='/admin/child/detail/:child_id' component={ChildDetail} />
<Route exact path='/admin/child/edit/:child_id' component={ChildEdit} />
<Route exact path='/admin/child/edit/password/:father_id' component={ChildPasswordEdit} />
<Route exact path='/admin/parent' component={Parent} />
<Route exact path='/admin/parent/detail/:father_id' component={ParentDetail} />
<Route exact path='/admin/parent/edit/:father_id' component={ParentEdit} />
<Route exact path='/admin/parent/edit/password/:father_id' component={ParentPasswordEdit} />
<Route exact path='/admin/parent/register' component={ParentRegister} />
</Switch>
<Side />
</BrowserRouter>

165
backend/resources/js/admin/child/detail.jsx ノーマルファイル
ファイルの表示

@ -0,0 +1,165 @@
import React, { useEffect, useState } from 'react';
import { useHistory } from 'react-router-dom';
import IconButton from "@material-ui/core/IconButton";
import axios from 'axios';
import Notification from '../../component/notification';
const ChildDetail = () => {
const [image, setImage] = useState('/assets/img/avatar/avatar-sample03@2x.png');
const history = useHistory();
const child = {
id: 1,
name: '田中 達也',
username:'chankan',
tel:'08012927104',
email:'chankan07@gmail.com',
company:'株式会社ZOTMAN',
image:'/assets/img/avatar/avatar-sample03@2x.png'
}
useEffect(
() => {
const formdata = new FormData();
let child_id = 1;
// axios.get('/api/meetings/listOfNonApprovalOfChild', {child_id: child_id})
// .then(response => {
// if(response.data.status_code==200){
// // window.location.href = '/register/c-account/complete';
// }
// else if(response.data.status_code==400){
// // window.location.href = '/register/c-account/error';
// }
// else if(response.data.status_code==500){
// // window.location.href = '/unknown-error';
// }
// })
// .catch(err=>console.log(err))
},[]
);
const handleImageChange = (e) => {
e.preventDefault();
let reader = new FileReader();
let _file = e.target.files[0];
reader.readAsDataURL(_file);
reader.onloadend = () => {
setImage(reader.result);
};
};
return (
<div className="l-content">
<div className="l-content-w560">
<div className="l-content__ttl">
<div className="l-content__ttl__left">
<h2>子詳細</h2>
</div>
<Notification/>
</div>
<div className="l-content-wrap">
<section className="profile-container">
<div className="profile-wrap">
<div className="profile-content">
<div>
<input type="file" id="avatar" name="avatar" className="d-none" accept=".png, .jpg, .jpeg" onChange={(e) => handleImageChange(e)}/>
<div className="avatar-wrapper">
<label htmlFor="avatar" className='avatar-label'>
<IconButton color="primary" aria-label="upload picture" component="span" className="bg-color-2 shadow-sm w-40-px h-40-px">
<img src="/assets/img/icon/camera.svg" width="20" height="20"/>
</IconButton>
</label>
{
image &&
<img src={image} alt="" width ="100%" height="100%" style={{borderRadius:'50%'}}/>
}
</div>
</div>
<p className="profile-name ft-xs-14">{child.name}</p>
<div className="profile-info ft-xs-14">
<div className="profile-info__item">
<p className="profile-info__icon">
<img src="/assets/img/icon/mail.svg" alt="メール"/>
</p>
<p className="txt">{child.username}</p>
</div>
<div className="profile-info__item">
<a href={`mailto:${child.email}`}>
<p className="profile-info__icon">
<img src="/assets/img/icon/mail.svg" alt="メール"/>
</p>
<p className="txt">{child.email}</p>
</a>
</div>
<div className="profile-info__item">
<a href={`tel:${parent.tel}`}>
<p className="profile-info__icon">
<img src="/assets/img/icon/phone.svg" alt="電話" />
</p>
<p className="txt">{child.tel}</p>
</a>
</div>
<div className="profile-info__item">
<p className="profile-info__icon">
<img src="/assets/img/icon/building.svg" alt="会社名"/>
</p>
<p className="txt">{child.company}</p>
</div>
</div>
<div className="p-profile-btn">
<a className="btn-default btn-yellow btn-profile btn-r8 btn-h52 h-xs-45-px"
onClick={e => {
e.preventDefault();
history.push({
pathname: `/admin/child/edit/${child.id}`,
state: {}
});
}}
>
<span className="ft-18 ft-xs-14">プロフィールを変更する</span>
</a>
</div>
<div className="p-profile-btn">
<a className="btn-default btn-yellow btn-password btn-r8 btn-h52 h-xs-45-px"
onClick={e => {
e.preventDefault();
history.push({
pathname: `/admin/child/edit/password/${child.id}`,
state: {}
});
}}
>
<span className="ft-18 ft-xs-14">パスワードを変更する</span>
</a>
</div>
<div className="p-profile-txtLink">
<a href="">
<span className="ft-xs-14">削除する</span>
</a>
</div>
</div>
</div>
</section>
</div>
</div>
</div>
)
}
export default ChildDetail;

209
backend/resources/js/admin/child/edit.jsx ノーマルファイル
ファイルの表示

@ -0,0 +1,209 @@
import React, { useEffect, useState } from 'react';
import { useHistory } from 'react-router-dom';
import axios from 'axios';
import { LoadingButton } from '@material-ui/lab';
import Notification from '../../component/notification';
import Alert from '../../component/alert';
const ChildEdit = () => {
const history = useHistory();
const [first_name, setFirstName] = useState('');
const [last_name, setLastName] = useState('');
const [identify, setIdentify] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [company, setCompany] = useState('');
const [image, setImage] = useState('');
const [errors, setErrors] = useState({
first_name:'',
last_name:'',
identify:'',
email:'',
password:'',
image:'',
company:''
})
const [err_msg, setErrMsg] = useState({status:'', msg:''})
const [submitStatus, setSubmitStatus] = useState('')
const validateForm = () => {
let errors = {};
let formIsValid = true;
if (email.length == 0) { formIsValid = false; errors["email"] = 'Required'; }
else {
//regular expression for email validation
var pattern = new RegExp(/^(("[\w-\s]+")|([\w-]+(?:\.[\w-]+)*)|("[\w-\s]+")([\w-]+(?:\.[\w-]+)*))(@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i);
if (!pattern.test(email)) {
formIsValid = false;
errors["email"] = 'Required';
}
else {
errors['email'] = '';
}
}
if(!image){ formIsValid = false; errors['image'] = 'Required'; }
else errors['image'] = '';
if(first_name.length == 0){ formIsValid = false; errors['first_name'] = 'Required'; }
else errors['first_name'] = '';
if(identify.length == 0){ formIsValid = false; errors['identify'] = 'Required'; }
else errors['identify'] = '';
if(last_name.length == 0){ formIsValid = false; errors['last_name'] = 'Required'; }
else errors['last_name'] = '';
if(password.length < 8){ formIsValid = false; errors['password'] = 'Required'; }
else errors['password'] = '';
if(company.length == 0){ formIsValid = false; errors['company'] = 'Required'; }
else errors['company'] = '';
setErrors(errors);
return formIsValid;
}
const handleSubmit = (e) => {
e.preventDefault();
setErrMsg({status:'', msg:''});
if(!validateForm()) return;
const formdata = new FormData();
formdata.append('first_name', first_name);
formdata.append('last_name', last_name);
formdata.append('identify', identify);
formdata.append('email', email);
formdata.append('password', password);
formdata.append('company', company);
formdata.append('image', image);
// axios.post('/api/children/updateProfile/{identify}', formdata)
// .then(response => {
// if(response.data.status_code==200){
// setSubmitStatus('success);
// }
// else if(response.data.status_code==400){
// setSubmitStatus('failed);
// }
// })
// .catch(err=>console.log(err))
}
return (
<div className="l-content">
<div className="l-content-w560">
<div className="l-content__ttl">
<div className="l-content__ttl__left">
<h2>プロフィール編集</h2>
</div>
<Notification/>
</div>
<div className="l-content-wrap">
<section className="profile-container">
<div className="profile-wrap">
<div className="mx-5">
<form onSubmit={handleSubmit} noValidate>
<div className="edit-set">
<label htmlFor="identify" className="control-label ft-12"> ID </label>
<input type="text" name="identify" id="identify" className={`input-default input-nameSei ${ errors['identify'].length != 0 && "is-invalid c-input__target" }`} value={identify} onChange={e=>setIdentify(e.target.value)}/>
{
errors['identify'].length != 0 &&
<span className="l-alert__text--error ft-16 ft-md-14">
{errors['identify']}
</span>
}
</div>
<div className="edit-set">
<label htmlFor="first_name" className="control-label ft-12"> </label>
<input type="text" name="first_name" id="first_name" className={`input-default input-nameSei ${ errors['first_name'].length != 0 && "is-invalid c-input__target" }`} value={first_name} onChange={e=>setFirstName(e.target.value)}/>
{
errors['first_name'].length != 0 &&
<span className="l-alert__text--error ft-16 ft-md-14">
{errors['first_name']}
</span>
}
</div>
<div className="edit-set">
<label htmlFor="last_name" className="control-label ft-12"> </label>
<input type="text" name="last_name" id="last_name" className={`input-default input-nameSei ${ errors['last_name'].length != 0 && "is-invalid c-input__target" }`} value={last_name} onChange={e=>setLastName(e.target.value)}/>
{
errors['last_name'].length != 0 &&
<span className="l-alert__text--error ft-16 ft-md-14">
{errors['last_name']}
</span>
}
</div>
<div className="edit-set">
<label htmlFor="email" className="control-label ft-12"> メールアドレス </label>
<input type="email" name="email" id="email" className = {`input-default input-nameSei ${ errors['email'].length != 0 && "is-invalid c-input__target" }`} value={email} onChange={e=>setEmail(e.target.value)}/>
{
errors['email'].length != 0 &&
<span className="l-alert__text--error ft-16 ft-md-14">
{errors['email']}
</span>
}
</div>
<div className="edit-set">
<label htmlFor="password" className="control-label ft-12"> 電話番号 </label>
<input type="password" name="password" id="password" className = {`input-default input-nameSei ${ errors['password'].length != 0 && "is-invalid c-input__target" }`} value={password} onChange={e=>setPassword(e.target.value)}/>
{
errors['password'].length != 0 &&
<span className="l-alert__text--error ft-16 ft-md-14">
{errors['password']}
</span>
}
</div>
<div className="edit-set">
<label htmlFor="company" className="control-label ft-12"> 所屈している会社名を記載 </label>
<input type="text" name="company" id="company" className = {`input-default input-nameSei ${ errors['company'].length != 0 && "is-invalid c-input__target" }`} value={company} onChange={e=>setCompany(e.target.value)}/>
{
errors['company'].length != 0 &&
<span className="l-alert__text--error ft-16 ft-md-14">
{errors['company']}
</span>
}
</div>
<div className="mt-5">
<LoadingButton type="submit" fullWidth className="p-3 rounded-15 font-weight-bold text-black bg-color-2">
<span className="ft-16">プロフィールを更新</span>
</LoadingButton>
</div>
{
submitStatus == 'success' && <Alert type="success">Submit Success!</Alert>
}
{
submitStatus == 'failed' && <Alert type="fail">Submit Failed!</Alert>
}
</form>
</div>
</div>
</section>
</div>
</div>
</div>
)
}
export default ChildEdit;

107
backend/resources/js/admin/child/index.jsx ノーマルファイル
ファイルの表示

@ -0,0 +1,107 @@
import React, { useEffect, useState } from 'react';
import { CircularProgress } from '@material-ui/core';
import Notification from '../../component/notification';
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import axios from 'axios';
import { useHistory } from 'react-router-dom';
const Child = () => {
const [children, setChildren ] = useState(null);
const [loading, setLoading] = useState(true);
const history = useHistory();
const state = history.location.state
useEffect(() => {
// axios.get('/api/children/listOfFather', {params: { father_id: 1 }}).then((response) => {
// if(response.data.status_code==200){
// console.log(response.data.params);
// setChildren(response.data.params);
// } else if(response.data.status_code==400){
// //TODO
// }
// setLoading(false);
// if(state?.message) {
// toast.success(state?.message, {
// position: "top-center",
// autoClose: 5000,
// className:"bg-success",
// hideProgressBar: true,
// closeOnClick: true,
// pauseOnHover: true,
// draggable: false,
// progress: undefined,
// style:{ color: '#ffffff', opacity: 0.95}
// });
// }
// });
/////////////////////////////////////
var obj = [
{id:1, last_name:'山口', first_name:'太一', image:'/assets/img/avatar/avatar-sample03@2x.png', tel:'09041540763'},
{id:2, last_name:'山口', first_name:'太一', image:'/assets/img/avatar/avatar-sample03@2x.png', tel:'09041540763'},
{id:3, last_name:'山口', first_name:'太一', image:'/assets/img/avatar/avatar-sample03@2x.png', tel:'09041540763'},
{id:4, last_name:'山口', first_name:'太一', image:'/assets/img/avatar/avatar-sample03@2x.png', tel:'09041540763'},
{id:5, last_name:'山口', first_name:'太一', image:'/assets/img/avatar/avatar-sample03@2x.png', tel:'09041540763'}
];
setLoading(false);
setChildren(obj);
////////////////////////////////////
}, []);
return (
<div className="l-content">
<ToastContainer />
<div className="l-content__ttl">
<div className="l-content__ttl__left">
<h2>子一覧</h2>
</div>
<Notification />
</div>
<div className="l-content-wrap">
<section className="search-container">
<div className="meeting-head">
<form action="" className="meeting-form">
<label className="control-label" htmlFor="keyword">キーワード</label>
<input type="search" name="keyword" className="input-default input-keyword input-w380" id="keyword" />
<i className="icon icon-search"></i>
</form>
</div>
<div className="search-wrap">
<div className="search-content">
{ !loading ? children?.map((child, index) => {
return (
<div className="search-item">
<a onClick={e => {
e.preventDefault();
history.push({
pathname: `/admin/child/detail/${child.id}`,
state: { child_id : child.id }
});
}} >
<div className="user-wrap">
<div className="user-avatar">
<img alt="name" className="avatar-img" src={ child.image } />
</div>
<div className="user-info">
<p className="user-name mb-1 font-weight-bold">{ child.last_name } { child.first_name }</p>
<p className="user-tel">{ child.tel }</p>
</div>
</div>
</a>
</div>
);
}) : <div style={{position: "relative", left: "50%"}}><CircularProgress /></div>}
</div>
</div>
</section>
</div>
</div>
)
}
export default Child;

ファイルの表示

@ -0,0 +1,134 @@
import React, { useEffect, useState } from 'react';
import { useHistory } from 'react-router-dom';
import { LoadingButton } from '@material-ui/lab';
import axios from 'axios';
import Notification from '../../component/notification';
import Alert from '../../component/alert';
const ChildPasswordEdit = () => {
const history = useHistory();
const [pwd, setPwd] = useState('');
const [confirm_pwd, setConfirmPwd] = useState('');
const [errors, setErrors] = useState({pwd:'', confirm_pwd:''})
const [err_msg, setErrMsg] = useState({status:'', msg:''})
const [submitStatus, setSubmitStatus] = useState('')
const validateForm = () => {
let errors = {};
let formIsValid = true;
if(pwd.length == 0){ formIsValid = false; errors['pwd'] = 'Required'; }
else errors['pwd'] = '';
if(confirm_pwd.length == 0){ formIsValid = false; errors['confirm_pwd'] = 'Required'; }
else errors['confirm_pwd'] = '';
setErrors(errors);
return formIsValid;
}
const handleSubmit = (e) => {
e.preventDefault();
setErrMsg({status:'', msg:''});
if(!validateForm()) return;
const formdata = new FormData();
formdata.append('first_name', first_name);
formdata.append('last_name', last_name);
formdata.append('email', email);
formdata.append('password', password);
formdata.append('company', company);
formdata.append('image', image);
// axios.post('/api/children/profile/edit/password/{child_id}', formdata)
// .then(response => {
// if(response.data.status_code==200){
// setSubmitStatus('success);
// }
// else if(response.data.status_code==400){
// setSubmitStatus('failed);
// }
// })
// .catch(err=>console.log(err))
}
return (
<div className="l-content">
<div className="l-content-w560">
<div className="l-content__ttl">
<div className="l-content__ttl__left">
<h2>パスワード編集</h2>
</div>
<Notification/>
</div>
<div className="l-content-wrap">
<section className="profile-container">
<div className="profile-wrap">
<div className="mx-5">
<form onSubmit={handleSubmit} noValidate>
<div className="edit-set">
<label htmlFor="pwd" className="control-label ft-14 ft-md-12">
新しいパスワード
</label>
<input type="password" name="pwd" id="pwd" className={`input-default ${ errors['pwd'].length != 0 && "is-invalid c-input__target" }`}
value={pwd} onChange={e=>setPwd(e.target.value)} autoFocus/>
{
errors['pwd'].length != 0 &&
<span className="l-alert__text--error ft-16 ft-md-14">
{errors['pwd']}
</span>
}
</div>
<div className="edit-set">
<label htmlFor="confirm_pwd" className="control-label ft-14 ft-md-12">
確認用新しいパスワード
</label>
<input type="password" name="confirm_pwd" id="confirm_pwd" className={`input-default ${ errors['confirm_pwd'].length != 0 && "is-invalid c-input__target" }`}
value={confirm_pwd} onChange={e=>setConfirmPwd(e.target.value)}/>
{
errors['confirm_pwd'].length != 0 &&
<span className="l-alert__text--error ft-16 ft-md-14">
{errors['confirm_pwd']}
</span>
}
</div>
<div className="mt-5">
<LoadingButton type="submit" fullWidth className="p-3 rounded-15 font-weight-bold text-black bg-color-2">
<span className="ft-16">パスワードを更新</span>
</LoadingButton>
</div>
{
submitStatus == 'success' && <Alert type="success">Submit Success!</Alert>
}
{
submitStatus == 'fail' && <Alert type="fail">Submit Failed!</Alert>
}
</form>
</div>
</div>
</section>
</div>
</div>
</div>
)
}
export default ChildPasswordEdit;

ファイルの表示

@ -1,9 +1,11 @@
import React, { useEffect, useState } from 'react';
import { useHistory } from 'react-router-dom'
import moment from 'moment';
import axios from 'axios';
import ModalConfirm from '../../component/modal_confirm';
import ModalAlert from '../../component/modal_alert';
import { useHistory } from 'react-router-dom'
import Notification from '../../component/notification';
const MeetingDetail = (props) => {
const history = useHistory();
@ -13,7 +15,8 @@ const MeetingDetail = (props) => {
const [typeAlert, setTypeAlert] = useState(null);
const [meeting, setMeeting] = useState(null);
useEffect(() => {
axios.get(`/api/meetings/detail/${props.match.params?.id}`, {params: { father_id: 1 }}).then((response) => {
axios.get(`/api/meetings/detail/${props.match.params?.meeting_id}`, {params: { father_id: 1 }}).then((response) => {
if(response.data.status_code==200){
console.log(response.data.params[0]);
setMeeting(response.data.params[0]);
@ -34,7 +37,7 @@ const MeetingDetail = (props) => {
async function handleAccept() {
try {
axios.delete(`/api/meetings/delete/${props.match.params?.id}`)
axios.delete(`/api/meetings/delete/${props.match.params?.meeting_id}`)
.then(response => {
if(response.data.status_code == 200){
axios.delete(`/api/meeting-images/deleteRelationMeeting/${props.match.params?.id}`)
@ -69,15 +72,7 @@ const MeetingDetail = (props) => {
<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">
@ -109,26 +104,6 @@ const MeetingDetail = (props) => {
<img alt="name" className="avatar-img" src="../../../assets/img/avatar/avatar-sample03@2x.png" />
</div>
</li>
<li className="meeting-member__item" role="listitem">
<div className="avatar">
<img alt="name" className="avatar-img" src="../../../assets/img/avatar/avatar-sample01@2x.png" />
</div>
</li>
<li className="meeting-member__item" role="listitem">
<div className="avatar">
<img alt="name" className="avatar-img" src="../../../assets/img/avatar/avatar-sample02@2x.png" />
</div>
</li>
<li className="meeting-member__item" role="listitem">
<div className="avatar">
<img alt="name" className="avatar-img" src="../../../assets/img/avatar/avatar-sample03@2x.png" />
</div>
</li>
<li className="meeting-member__item" role="listitem">
<div className="avatar">
<img alt="name" className="avatar-img" src="../../../assets/img/avatar/avatar-sample01@2x.png" />
</div>
</li>
</ul>
<div className="meeting-member__read">
@ -139,15 +114,15 @@ const MeetingDetail = (props) => {
</div>
<h3 className="meeting-ttl">{ meeting.title }</h3>
<time dateTime="2021-07-30" className="meeting-time">
<span className="meeting-date">{ moment(meeting.updated_at).format('YYYY/MM/DD HH:mm') || '' }</span>
<span className="meeting-date">{ moment(meeting.updated_at).format('YYYY/MM/DD') || '' }</span>
</time>
<ul className="p-article-btn-list">
<li className="p-article-btn__item">
<li className="p-article__pdf__btn">
<a
onClick={e => {
e.preventDefault();
history.push({
pathname: `/p-account/meeting/edit/${props.match.params?.id}`,
pathname: `/admin/meeting/edit/${props.match.params?.meeting_id}`,
state: {}
});
}}
@ -155,15 +130,9 @@ const MeetingDetail = (props) => {
編集
</a>
</li>
<li className="p-article-btn__item">
<li className="p-article__pdf__btn mr-0">
<a onClick={showModal} className="btn-default btn-yellow btn-pdf btn-r8 btn-h48">削除</a>
</li>
<li className="p-article-btn__item">
<a href="" className="btn-default btn-yellow btn-pdf btn-r8 btn-h48">複製</a>
</li>
<li className="p-article-btn__item">
<a href="" className="btn-default btn-yellow btn-pdf btn-r8 btn-h48">再通知</a>
</li>
</ul>
<div className="p-article__context">
@ -195,7 +164,7 @@ const MeetingDetail = (props) => {
<span>PDFを確認する</span>
</a>
</div>
<button type="button" aria-label="お気に入り" data-tooltip="お気に入り" aria-pressed="false" className="icon a-icon like-icon icon-star icon-star-wrap a-icon-size_medium"></button>
<button type="button" aria-label="お気に入り" data-tooltip="お気に入り" aria-pressed="false" className="icon a-icon like-icon icon-star icon-star-wrap a-icon-size_medium" style={{border:'1px solid #f0de00'}}></button>
</div>
<p className="p-article__txt">{ meeting.text }</p>

ファイルの表示

@ -52,19 +52,19 @@ const Meeting = () => {
<div className="l-content-wrap">
<div className="meeting-tab-container">
<div className="meeting-tab-wrap">
<div className="meeting-head">
<form action="" className="meeting-form">
<label className="control-label" htmlFor="keyword">キーワード</label>
<input type="search" name="keyword" className="input-default input-keyword input-w380" id="keyword" value={keyword} onChange={e=> setKeyword(e.target.value)}/>
<i className="icon icon-search"></i>
</form>
</div>
<div className="meeting-head">
<form action="" className="meeting-form">
<label className="control-label" htmlFor="keyword">キーワード</label>
<input type="search" name="keyword" className="input-default input-keyword input-w380" id="keyword" value={keyword} onChange={e=> setKeyword(e.target.value)}/>
<i className="icon icon-search"></i>
</form>
</div>
<div className="meeting-content">
<div className={ `meeting-content-wrap ${!finish ? "is-active" : ""}` } id="item01">
{ !loading ? inCompleteOfFather?.map((item, i) => {
{ !loading ? inCompleteOfFather?.map((item, index) => {
return (
<div className="meeting-item" key={i}>
<div className="meeting-item" key={index}>
<a
className="meeting-link"
onClick={e => {
@ -110,7 +110,7 @@ const Meeting = () => {
</a>
</div>
);
}) : <div style={{position: 'fixed', left: 'calc( 50% - 20px)', top:'45%'}}> <CircularProgress /></div> }
}) : <div style={{position: "relative", left: "calc( 50% - 20px)", top:'30px'}}><CircularProgress /></div>}
</div>
</div>

157
backend/resources/js/admin/parent/detail.jsx ノーマルファイル
ファイルの表示

@ -0,0 +1,157 @@
import React, { useEffect, useState } from 'react';
import { useHistory } from 'react-router-dom';
import IconButton from "@material-ui/core/IconButton";
import axios from 'axios';
import Notification from '../../component/notification';
const ParentDetail = () => {
const [image, setImage] = useState('/assets/img/avatar/avatar-sample03@2x.png');
const history = useHistory();
const parent = {
id: 1,
last_name:'田中',
first_name:'達也',
username:'chankan',
tel:'08012927104',
email:'chankan07@gmail.com',
company:'ああああああああああああああああああああああああああああああああああああああああああああああああああああああああ',
image:'/assets/img/avatar/avatar-sample03@2x.png'
}
useEffect(
() => {
const formdata = new FormData();
let child_id = 1;
// axios.get('/api/meetings/listOfNonApprovalOfChild', {child_id: child_id})
// .then(response => {
// if(response.data.status_code==200){
// // window.location.href = '/register/c-account/complete';
// }
// else if(response.data.status_code==400){
// // window.location.href = '/register/c-account/error';
// }
// else if(response.data.status_code==500){
// // window.location.href = '/unknown-error';
// }
// })
// .catch(err=>console.log(err))
},[]
);
const handleImageChange = (e) => {
e.preventDefault();
let reader = new FileReader();
let _file = e.target.files[0];
reader.readAsDataURL(_file);
reader.onloadend = () => {
setImage(reader.result);
};
};
return (
<div className="l-content">
<div className="l-content-w560">
<div className="l-content__ttl">
<div className="l-content__ttl__left">
<h2>親詳細</h2>
</div>
<Notification/>
</div>
<div className="l-content-wrap">
<section className="profile-container">
<div className="profile-wrap">
<div className="profile-content">
<div>
<input type="file" id="avatar" name="avatar" className="d-none" accept=".png, .jpg, .jpeg" onChange={(e) => handleImageChange(e)}/>
<div className="avatar-wrapper">
<label htmlFor="avatar" className='avatar-label'>
<IconButton color="primary" aria-label="upload picture" component="span" className="bg-color-2 shadow-sm w-40-px h-40-px">
<img src="/assets/img/icon/camera.svg" width="20" height="20"/>
</IconButton>
</label>
{
image &&
<img src={image} alt="" width ="100%" height="100%" style={{borderRadius:'50%'}}/>
}
</div>
</div>
<p className="profile-name">{ parent.last_name } { parent.first_name }</p>
<div className="profile-info">
<div className="profile-info__item">
<a href={`mailto:${parent.email}`}>
<p className="profile-info__icon">
<img src="/assets/img/icon/mail.svg" alt="メール"/>
</p>
<p className="txt">{parent.email}</p>
</a>
</div>
<div className="profile-info__item">
<a href={`tel:${parent.tel}`}>
<p className="profile-info__icon">
<img src="/assets/img/icon/phone.svg" alt="電話" />
</p>
<p className="txt">{parent.tel}</p>
</a>
</div>
<div className="profile-info__item">
<p className="txt">{ parent.company }</p>
</div>
</div>
<div className="p-profile-btn">
<a className="btn-default btn-yellow btn-profile btn-r8 btn-h52 h-xs-45-px"
onClick={e => {
e.preventDefault();
history.push({
pathname: `/admin/parent/edit/${parent.id}`,
state: {}
});
}}
>
<span className="ft-18 ft-xs-14">プロフィールを変更する</span>
</a>
</div>
<div className="p-profile-btn">
<a className="btn-default btn-yellow btn-password btn-r8 btn-h52 h-xs-45-px"
onClick={e => {
e.preventDefault();
history.push({
pathname: `/admin/parent/edit/password/${parent.id}`,
state: {}
});
}}
>
<span className="ft-18 ft-xs-14">パスワードを変更する</span>
</a>
</div>
<div className="p-profile-txtLink">
<a href="">
<span className="ft-xs-14">削除する</span>
</a>
</div>
</div>
</div>
</section>
</div>
</div>
</div>
)
}
export default ParentDetail;

171
backend/resources/js/admin/parent/edit.jsx ノーマルファイル
ファイルの表示

@ -0,0 +1,171 @@
import React, { useEffect, useState } from 'react';
import { useHistory } from 'react-router-dom';
import axios from 'axios';
import { LoadingButton } from '@material-ui/lab';
import Notification from '../../component/notification';
import Alert from '../../component/alert';
const ParentEdit = () => {
const history = useHistory();
const [company, setCompany] = useState('');
const [email, setEmail] = useState('');
const [tel, setTel] = useState('');
const [text, setText] = useState('');
const [_422errors, set422Errors] = useState({
company:'',
email:'',
tel:'',
text:'',
})
const [_400error, set400Error] = useState('')
const [submitStatus, setSubmitStatus] = useState('')
const validateForm = () => {
let errors = {};
let formIsValid = true;
if (email.length == 0) { formIsValid = false; errors["email"] = 'Required'; }
else {
//regular expression for email validation
var pattern = new RegExp(/^(("[\w-\s]+")|([\w-]+(?:\.[\w-]+)*)|("[\w-\s]+")([\w-]+(?:\.[\w-]+)*))(@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i);
if (!pattern.test(email)) {
formIsValid = false;
errors["email"] = 'Required';
}
else {
errors['email'] = '';
}
}
if(!company){ formIsValid = false; errors['company'] = 'Required'; }
else errors['company'] = '';
if(!tel){ formIsValid = false; errors['tel'] = 'Required'; }
else errors['tel'] = '';
if(!text){ formIsValid = false; errors['text'] = 'Required'; }
else errors['text'] = '';
set422Errors(errors);
return formIsValid;
}
const handleSubmit = (e) => {
e.preventDefault();
if(!validateForm()) return;
const formdata = new FormData();
formdata.append('company', company);
formdata.append('email', email);
formdata.append('tel', tel);
formdata.append('text', text);
// axios.post('/', formdata)
// .then(response => {
// if(response.data.status_code==200){
// setSubmitStatus('success);
// }
// else if(response.data.status_code==400){
// setSubmitStatus('failed);
// }
// })
// .catch(err=>console.log(err))
}
return (
<div className="l-content">
<div className="l-content-w560">
<div className="l-content__ttl">
<div className="l-content__ttl__left">
<h2>プロフィール編集</h2>
</div>
<Notification/>
</div>
<div className="l-content-wrap">
<section className="profile-container">
<div className="profile-wrap">
<div className="mx-5">
<form onSubmit={handleSubmit} noValidate>
<div className="edit-set">
<label htmlFor="company" className="control-label ft-12"> 会社名</label>
<input type="text" name="company" id="company" className = {`input-default input-nameSei ${ _422errors['company'].length != 0 && "is-invalid c-input__target" }`} value={company} onChange={e=>setCompany(e.target.value)}/>
{
_422errors['company'].length != 0 &&
<span className="l-alert__text--error ft-16 ft-md-14">
{_422errors['company']}
</span>
}
</div>
<div className="edit-set">
<label htmlFor="email" className="control-label ft-12"> メールアドレス </label>
<input type="email" name="email" id="email" className = {`input-default input-nameSei ${ _422errors['email'].length != 0 && "is-invalid c-input__target" }`} value={email} onChange={e=>setEmail(e.target.value)}/>
{
_422errors['email'].length != 0 &&
<span className="l-alert__text--error ft-16 ft-md-14">
{_422errors['email']}
</span>
}
</div>
<div className="edit-set">
<label htmlFor="tel" className="control-label ft-12"> 電話番号 </label>
<input type="text" name="tel" id="tel" className = {`input-default input-nameSei ${ _422errors['tel'].length != 0 && "is-invalid c-input__target" }`} value={tel} onChange={e=>setTel(e.target.value)}/>
{
_422errors['tel'].length != 0 &&
<span className="l-alert__text--error ft-16 ft-md-14">
{_422errors['tel']}
</span>
}
</div>
<div className="edit-set">
<label htmlFor="profile" className="control-label ft-12"> プロフィール </label>
<textarea name="profile" id="profile" style={{height:'200px'}} className = {`input-default input-nameSei ${ _422errors['text'].length != 0 && "is-invalid c-input__target" }`} value={text} onChange={e=>setText(e.target.value)}/>
{
_422errors['text'].length != 0 &&
<span className="l-alert__text--error ft-16 ft-md-14">
{_422errors['text']}
</span>
}
</div>
<div className="mt-5">
<LoadingButton type="submit" fullWidth className="p-3 rounded-15 ft-15 font-weight-bold text-black bg-color-2">
<span className="ft-16">プロフィールを更新</span>
</LoadingButton>
</div>
{
submitStatus == 'success' && <Alert type="success">Submit Success!</Alert>
}
{
submitStatus == 'failed' && <Alert type="fail">Submit Failed!</Alert>
}
</form>
</div>
</div>
</section>
</div>
</div>
</div>
)
}
export default ParentEdit;

107
backend/resources/js/admin/parent/index.jsx ノーマルファイル
ファイルの表示

@ -0,0 +1,107 @@
import React, { useEffect, useState } from 'react';
import { CircularProgress } from '@material-ui/core';
import Notification from '../../component/notification';
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import axios from 'axios';
import { useHistory } from 'react-router-dom';
const Parent = () => {
const [parent, setParent ] = useState(null);
const [loading, setLoading] = useState(true);
const history = useHistory();
const state = history.location.state
useEffect(() => {
// axios.get('/api/children/listOfFather', {params: { father_id: 1 }}).then((response) => {
// if(response.data.status_code==200){
// console.log(response.data.params);
// setParent(response.data.params);
// } else if(response.data.status_code==400){
// //TODO
// }
// setLoading(false);
// if(state?.message) {
// toast.success(state?.message, {
// position: "top-center",
// autoClose: 5000,
// className:"bg-success",
// hideProgressBar: true,
// closeOnClick: true,
// pauseOnHover: true,
// draggable: false,
// progress: undefined,
// style:{ color: '#ffffff', opacity: 0.95}
// });
// }
// });
/////////////////////////////////////
var obj = [
{id:1, last_name:'山口', first_name:'太一', image:'/assets/img/avatar/avatar-sample03@2x.png', email:'mailaddress@info.com'},
{id:2, last_name:'山口', first_name:'太一', image:'/assets/img/avatar/avatar-sample03@2x.png', email:'mailaddress@info.com'},
{id:3, last_name:'山口', first_name:'太一', image:'/assets/img/avatar/avatar-sample03@2x.png', email:'mailaddress@info.com'},
{id:4, last_name:'山口', first_name:'太一', image:'/assets/img/avatar/avatar-sample03@2x.png', email:'mailaddress@info.com'},
{id:5, last_name:'山口', first_name:'太一', image:'/assets/img/avatar/avatar-sample03@2x.png', email:'mailaddress@info.com'}
];
setLoading(false);
setParent(obj);
////////////////////////////////////
}, []);
return (
<div className="l-content">
<ToastContainer />
<div className="l-content__ttl">
<div className="l-content__ttl__left">
<h2>親一覧</h2>
</div>
<Notification />
</div>
<div className="l-content-wrap">
<section className="search-container">
<div className="meeting-head">
<form action="" className="meeting-form">
<label className="control-label" htmlFor="keyword">キーワード</label>
<input type="search" name="keyword" className="input-default input-keyword input-w380" id="keyword" />
<i className="icon icon-search"></i>
</form>
</div>
<div className="search-wrap">
<div className="search-content">
{ !loading ? parent?.map((parent, index) => {
return (
<div className="search-item">
<a onClick={e => {
e.preventDefault();
history.push({
pathname: `/admin/parent/detail/${parent.id}`,
state: { parent_id : parent.id }
});
}} >
<div className="user-wrap">
<div className="user-avatar">
<img alt="name" className="avatar-img" src={ parent.image } />
</div>
<div className="user-info">
<p className="user-name mb-1 font-weight-bold">{ parent.last_name } { parent.first_name }</p>
<p className="user-tel">{ parent.email }</p>
</div>
</div>
</a>
</div>
);
}) : <div style={{position: "relative", left: "50%"}}><CircularProgress /></div>}
</div>
</div>
</section>
</div>
</div>
)
}
export default Parent;

ファイルの表示

@ -0,0 +1,129 @@
import React, { useEffect, useState } from 'react';
import { useHistory } from 'react-router-dom';
import { LoadingButton } from '@material-ui/lab';
import axios from 'axios';
import Notification from '../../component/notification';
import Alert from '../../component/alert';
const ParentPasswordEdit = () => {
const history = useHistory();
const [pwd, setPwd] = useState('');
const [confirm_pwd, setConfirmPwd] = useState('');
const [_422errors, set422Errors] = useState({pwd:'', confirm_pwd:''})
const [_400error, set400Error] = useState({status:'', msg:''})
const [submitStatus, setSubmitStatus] = useState('')
const validateForm = () => {
let errors = {};
let formIsValid = true;
if(pwd.length == 0){ formIsValid = false; errors['pwd'] = 'Required'; }
else errors['pwd'] = '';
if(confirm_pwd.length == 0){ formIsValid = false; errors['confirm_pwd'] = 'Required'; }
else errors['confirm_pwd'] = '';
set422Errors(errors);
return formIsValid;
}
const handleSubmit = (e) => {
e.preventDefault();
set400Error({status:'', msg:''});
if(!validateForm()) return;
const formdata = new FormData();
// formdata.append('first_name', first_name);
// axios.post('/', formdata)
// .then(response => {
// if(response.data.status_code==200){
// setSubmitStatus('success);
// }
// else if(response.data.status_code==400){
// setSubmitStatus('failed);
// }
// })
// .catch(err=>console.log(err))
}
return (
<div className="l-content">
<div className="l-content-w560">
<div className="l-content__ttl">
<div className="l-content__ttl__left">
<h2>パスワード編集</h2>
</div>
<Notification/>
</div>
<div className="l-content-wrap">
<section className="profile-container">
<div className="profile-wrap">
<div className="mx-5">
<form onSubmit={handleSubmit} noValidate>
<div className="edit-set">
<label htmlFor="pwd" className="control-label ft-14 ft-md-12">
新しいパスワード
</label>
<input type="password" name="pwd" id="pwd" className={`input-default ${ _422errors['pwd'].length != 0 && "is-invalid c-input__target" }`}
value={pwd} onChange={e=>setPwd(e.target.value)} autoFocus/>
{
_422errors['pwd'].length != 0 &&
<span className="l-alert__text--error ft-16 ft-md-14">
{_422errors['pwd']}
</span>
}
</div>
<div className="edit-set">
<label htmlFor="confirm_pwd" className="control-label ft-14 ft-md-12">
確認用新しいパスワード
</label>
<input type="password" name="confirm_pwd" id="confirm_pwd" className={`input-default ${ _422errors['confirm_pwd'].length != 0 && "is-invalid c-input__target" }`}
value={confirm_pwd} onChange={e=>setConfirmPwd(e.target.value)}/>
{
_422errors['confirm_pwd'].length != 0 &&
<span className="l-alert__text--error ft-16 ft-md-14">
{_422errors['confirm_pwd']}
</span>
}
</div>
<div className="mt-5">
<LoadingButton type="submit" fullWidth className="p-3 rounded-15 font-weight-bold text-black bg-color-2">
<span className="ft-16">パスワードを更新</span>
</LoadingButton>
</div>
{
submitStatus == 'success' && <Alert type="success">Submit Success!</Alert>
}
{
submitStatus == 'fail' && <Alert type="fail">Submit Failed!</Alert>
}
</form>
</div>
</div>
</section>
</div>
</div>
</div>
)
}
export default ParentPasswordEdit;

118
backend/resources/js/admin/parent/register.jsx ノーマルファイル
ファイルの表示

@ -0,0 +1,118 @@
import React, { useEffect, useState } from 'react';
import { useHistory } from 'react-router-dom';
import { LoadingButton } from '@material-ui/lab';
import axios from 'axios';
import Notification from '../../component/notification';
import Alert from '../../component/alert';
const ParentRegister = () => {
const history = useHistory();
const [email, setEmail] = useState('');
const [_422errors, set422Errors] = useState({email:''})
const [_400error, set400Error] = useState({status:'', msg:''})
const [submitStatus, setSubmitStatus] = useState('')
const validateForm = () => {
let errors = {};
let formIsValid = true;
if (email.length == 0) { formIsValid = false; errors["email"] = 'Required'; }
else {
//regular expression for email validation
var pattern = new RegExp(/^(("[\w-\s]+")|([\w-]+(?:\.[\w-]+)*)|("[\w-\s]+")([\w-]+(?:\.[\w-]+)*))(@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i);
if (!pattern.test(email)) {
formIsValid = false;
errors["email"] = 'Required';
}
else {
errors['email'] = '';
}
}
set422Errors(errors);
return formIsValid;
}
const handleSubmit = (e) => {
e.preventDefault();
set400Error({status:'', msg:''});
if(!validateForm()) return;
const formdata = new FormData();
// formdata.append('email', email);
// axios.post('/', formdata)
// .then(response => {
// if(response.data.status_code==200){
// setSubmitStatus('success);
// }
// else if(response.data.status_code==400){
// setSubmitStatus('failed);
// }
// })
// .catch(err=>console.log(err))
}
return (
<div className="l-content">
<div className="l-content-w560">
<div className="l-content__ttl">
<div className="l-content__ttl__left">
<h2>親追加</h2>
</div>
<Notification/>
</div>
<div className="l-content-wrap">
<section className="profile-container">
<div className="profile-wrap">
<div className="mx-5">
<form onSubmit={handleSubmit} noValidate>
<div className="edit-set">
<label htmlFor="email" className="control-label ft-12"> メールアドレス </label>
<input type="email" name="email" id="email" className = {`input-default input-nameSei ${ _422errors['email'].length != 0 && "is-invalid c-input__target" }`} value={email} onChange={e=>setEmail(e.target.value)}/>
{
_422errors['email'].length != 0 &&
<span className="l-alert__text--error ft-16 ft-md-14">
{_422errors['email']}
</span>
}
</div>
<div className="mt-5">
<LoadingButton type="submit" fullWidth className="p-3 rounded-15 font-weight-bold text-black bg-color-2">
<span className="ft-16">親追加</span>
</LoadingButton>
</div>
{
submitStatus == 'success' && <Alert type="success">Submit Success!</Alert>
}
{
submitStatus == 'fail' && <Alert type="fail">Submit Failed!</Alert>
}
</form>
</div>
</div>
</section>
</div>
</div>
</div>
)
}
export default ParentRegister;

ファイルの表示

@ -12,7 +12,7 @@ export default function Side() {
<nav className="mypage-nav">
<ul className="mypage-nav-list">
<li
className={`mypage-nav-list__item -meeting ${(selected == 'meeting' || (selected == '' && document.getElementById('admin_router').value == 'meeting')) && "nav-active"}`}
className={`mypage-nav-list__item ${(selected == 'meeting' || (selected == '' && document.getElementById('admin_router').value == 'meeting')) && "nav-active"}`}
onClick={e => {
e.preventDefault();
setSelected('meeting');
@ -23,10 +23,10 @@ export default function Side() {
</Link>
</li>
<li className={`mypage-nav-list__item -childinfo ${ (selected == 'child' || (selected == '' && document.getElementById('admin_router').value == 'child')) && "nav-active"}`}
<li className={`mypage-nav-list__item ${ (selected == 'child' || (selected == '' && document.getElementById('admin_router').value == 'child')) && "nav-active"}`}
onClick={e => {
e.preventDefault();
setSelected('parent');
setSelected('child');
}}>
<Link className='mypage-nav-list__link' to='/admin/child'>
<i className="icon parents"></i>
@ -34,7 +34,7 @@ export default function Side() {
</Link>
</li>
<li className={`mypage-nav-list__item -parentinfo ${ (selected == 'parent' || (selected == '' && document.getElementById('admin_router').value == 'parent')) && "nav-active"}`}
<li className={`mypage-nav-list__item ${ (selected == 'parent' || (selected == '' && document.getElementById('admin_router').value == 'parent')) && "nav-active"}`}
onClick={e => {
e.preventDefault();
setSelected('parent');

ファイルの表示

@ -87,16 +87,20 @@ const ProfileDetail = () => {
<p className="profile-name ft-xs-14">{profile.name}</p>
<div className="profile-info ft-xs-14">
<div className="profile-info__item">
<p className="profile-info__icon">
<img src="/assets/img/icon/mail.svg" alt="メール"/>
</p>
<p className="txt">{profile.email}</p>
<a href={`mailto:${profile.email}`}>
<p className="profile-info__icon">
<img src="/assets/img/icon/mail.svg" alt="メール"/>
</p>
<p className="txt">{profile.email}</p>
</a>
</div>
<div className="profile-info__item">
<p className="profile-info__icon">
<img src="/assets/img/icon/phone.svg" alt="電話"/>
</p>
<p className="txt">{profile.tel}</p>
<a href={`tel:${profile.tel}`}>
<p className="profile-info__icon">
<img src="/assets/img/icon/phone.svg" alt="電話" />
</p>
<p className="txt">{profile.tel}</p>
</a>
</div>
<div className="profile-info__item">
<p className="profile-info__icon">

ファイルの表示

@ -15,7 +15,7 @@ const ProfileEdit = () => {
const [last_name, setLastName] = useState('');
const [identify, setIdentify] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [tel, setTel] = useState('');
const [company, setCompany] = useState('');
const [image, setImage] = useState('');
@ -24,7 +24,7 @@ const ProfileEdit = () => {
last_name:'',
identify:'',
email:'',
password:'',
tel:'',
image:'',
company:''
})
@ -62,8 +62,8 @@ const ProfileEdit = () => {
if(last_name.length == 0){ formIsValid = false; errors['last_name'] = 'Required'; }
else errors['last_name'] = '';
if(password.length < 8){ formIsValid = false; errors['password'] = 'Required'; }
else errors['password'] = '';
if(tel.length == 0){ formIsValid = false; errors['tel'] = 'Required'; }
else errors['tel'] = '';
if(company.length == 0){ formIsValid = false; errors['company'] = 'Required'; }
else errors['company'] = '';
@ -84,7 +84,7 @@ const ProfileEdit = () => {
formdata.append('last_name', last_name);
formdata.append('identify', identify);
formdata.append('email', email);
formdata.append('password', password);
formdata.append('tel', tel);
formdata.append('company', company);
formdata.append('image', image);
// axios.post('/api/children/updateProfile/{identify}', formdata)
@ -162,19 +162,19 @@ const ProfileEdit = () => {
</div>
<div className="edit-set">
<label htmlFor="password" className="control-label ft-12"> 電話番号 </label>
<input type="password" name="password" id="password" className = {`input-default input-nameSei ${ errors['password'].length != 0 && "is-invalid c-input__target" }`} value={password} onChange={e=>setPassword(e.target.value)}/>
<label htmlFor="tel" className="control-label ft-12"> 電話番号 </label>
<input type="text" name="tel" id="tel" className = {`input-default input-nameSei ${ errors['tel'].length != 0 && "is-invalid c-input__target" }`} value={tel} onChange={e=>setTel(e.target.value)}/>
{
errors['password'].length != 0 &&
errors['tel'].length != 0 &&
<span className="l-alert__text--error ft-16 ft-md-14">
{errors['password']}
{errors['tel']}
</span>
}
</div>
<div className="edit-set">
<label htmlFor="company" className="control-label ft-12"> 会社名下請けの場合のみ </label>
<input type="text" name="company" id="company" className = {`input-default input-nameSei input-h60 input-w480 ${ errors['company'].length != 0 && "is-invalid c-input__target" }`} value={company} onChange={e=>setCompany(e.target.value)}/>
<input type="text" name="company" id="company" className = {`input-default input-nameSei ${ errors['company'].length != 0 && "is-invalid c-input__target" }`} value={company} onChange={e=>setCompany(e.target.value)}/>
{
errors['company'].length != 0 &&
<span className="l-alert__text--error ft-16 ft-md-14">

ファイルの表示

@ -95,16 +95,20 @@ const Profile = () => {
<p className="txt">{profile.username}</p>
</div>
<div className="profile-info__item">
<p className="profile-info__icon">
<img src="/assets/img/icon/mail.svg" alt="メール"/>
</p>
<p className="txt">{profile.email}</p>
<a href={`mailto:${profile.email}`}>
<p className="profile-info__icon">
<img src="/assets/img/icon/mail.svg" alt="メール"/>
</p>
<p className="txt">{profile.email}</p>
</a>
</div>
<div className="profile-info__item">
<p className="profile-info__icon">
<img src="/assets/img/icon/phone.svg" alt="電話"/>
</p>
<p className="txt">{profile.tel}</p>
<a href={`tel:${profile.tel}`}>
<p className="profile-info__icon">
<img src="/assets/img/icon/phone.svg" alt="電話" />
</p>
<p className="txt">{profile.tel}</p>
</a>
</div>
<div className="profile-info__item">
<p className="profile-info__icon">

ファイルの表示

@ -13,6 +13,7 @@ const MeetingDetail = (props) => {
const [typeAlert, setTypeAlert] = useState(null);
const [meeting, setMeeting] = useState(null);
useEffect(() => {
console.log(props.match.params?.id)
axios.get(`/api/meetings/detail/${props.match.params?.id}`, {params: { father_id: 1 }}).then((response) => {
if(response.data.status_code==200){
console.log(response.data.params[0]);

ファイルの表示

@ -1,18 +1,18 @@
.ft-12{ font-size: 12px !important; }
.ft-13{ font-size: 13px !important; }
.ft-14{ font-size: 14px !important; }
.ft-15{ font-size: 15px !important; }
.ft-16{ font-size: 16px !important; }
.ft-17{ font-size: 17px !important; }
.ft-18{ font-size: 18px !important; }
.ft-19{ font-size: 19px !important; }
.ft-20{ font-size: 20px !important; }
.ft-25{ font-size: 25px !important; }
.ft-30{ font-size: 30px !important; }
.ft-35{ font-size: 35px !important; }
.ft-40{ font-size: 40px !important; }
.ft-12{ font-size: 12px; }
.ft-13{ font-size: 13px; }
.ft-14{ font-size: 14px; }
.ft-15{ font-size: 15px; }
.ft-16{ font-size: 16px; }
.ft-17{ font-size: 17px; }
.ft-18{ font-size: 18px; }
.ft-19{ font-size: 19px; }
.ft-20{ font-size: 20px; }
.ft-25{ font-size: 25px; }
.ft-30{ font-size: 30px; }
.ft-35{ font-size: 35px; }
.ft-40{ font-size: 40px; }
.ft-md-12{ @include media-breakpoint-down(md){ font-size: 12px !important; } }

ファイルの表示

@ -80,3 +80,21 @@
.w-xs-40-px{ @include media-breakpoint-down(xs){ width: 40px !important; } }
.w-xs-45-px{ @include media-breakpoint-down(xs){ width: 45px !important; } }
.w-xs-50-px{ @include media-breakpoint-down(xs){ width: 50px !important; } }
.w-15-px{ width: 15px; }
.w-20-px{ width: 20px; }
.w-25-px{ width: 25px; }
.w-30-px{ width: 30px; }
.w-35-px{ width: 35px; }
.w-40-px{ width: 40px; }
.w-45-px{ width: 45px; }
.w-50-px{ width: 50px; }
.h-15-px{ height: 15px; }
.h-20-px{ height: 20px; }
.h-25-px{ height: 25px; }
.h-30-px{ height: 30px; }
.h-35-px{ height: 35px; }
.h-40-px{ height: 40px; }
.h-45-px{ height: 45px; }
.h-50-px{ height: 50px; }

ファイルの表示

@ -0,0 +1,8 @@
@extends('admin.layout')
@section('title', '子詳細')
@section('content')
<div id="admin-app"></div>
<input type="hidden" id="admin_router" value="child" />
@endsection

ファイルの表示

@ -0,0 +1,8 @@
@extends('admin.layout')
@section('title', 'プロフィール編集')
@section('content')
<div id="admin-app"></div>
<input type="hidden" id="admin_router" value="child" />
@endsection

ファイルの表示

@ -0,0 +1,8 @@
@extends('admin.layout')
@section('title', 'パスワード編集')
@section('content')
<div id="admin-app"></div>
<input type="hidden" id="admin_router" value="child" />
@endsection

ファイルの表示

@ -0,0 +1,8 @@
@extends('admin.layout')
@section('title', '子一覧')
@section('content')
<div id="admin-app"></div>
<input type="hidden" id="admin_router" value="child" />
@endsection

ファイルの表示

@ -1,6 +1,6 @@
@extends('admin.layout')
@section('title', 'ミーティング一覧')
@section('title', 'ミーティング詳細')
@section('content')
<div id="admin-app"></div>

ファイルの表示

@ -0,0 +1,8 @@
@extends('admin.layout')
@section('title', '親詳細')
@section('content')
<div id="admin-app"></div>
<input type="hidden" id="admin_router" value="parent" />
@endsection

ファイルの表示

@ -0,0 +1,8 @@
@extends('admin.layout')
@section('title', 'プロフィール編集')
@section('content')
<div id="admin-app"></div>
<input type="hidden" id="admin_router" value="parent" />
@endsection

ファイルの表示

@ -0,0 +1,8 @@
@extends('admin.layout')
@section('title', 'パスワード編集')
@section('content')
<div id="admin-app"></div>
<input type="hidden" id="admin_router" value="parent" />
@endsection

ファイルの表示

@ -0,0 +1,8 @@
@extends('admin.layout')
@section('title', '親一覧')
@section('content')
<div id="admin-app"></div>
<input type="hidden" id="admin_router" value="parent" />
@endsection

ファイルの表示

@ -0,0 +1,8 @@
@extends('admin.layout')
@section('title', '親追加')
@section('content')
<div id="admin-app"></div>
<input type="hidden" id="admin_router" value="parent" />
@endsection