p_accountでは ミーティングの完了画面

このコミットが含まれているのは:
トランギャー 2021-10-10 21:08:06 +07:00
コミット bf82b758e8
9個のファイルの変更585行の追加165行の削除

ファイルの表示

@ -150,7 +150,7 @@ class MeetingsController extends Controller {
}
$result = [];
$meeting_select = ['id', 'father_id', 'title', 'text', 'memo', 'updated_at'];
$meeting_select = ['id', 'father_id', 'title', 'text', 'memo', 'updated_at', 'is_favorite'];
$meeting_approvals_select = ['child_id', 'approval_at'];
$child_select = ['image'];
@ -159,6 +159,7 @@ class MeetingsController extends Controller {
foreach ($list as $i => $l) {
$result[] = $l;
$result[$i]['approvals'] = MeetingApprovals::select($meeting_approvals_select)->whereNotNull('approval_at')->where('meeting_id', $l['id'])->orderBy('updated_at', 'desc')->get();
$result[$i]['total'] = MeetingApprovals::where('meeting_id', $l['id'])->count();
if (count($result[$i]['approvals']) == 0) {
unset($result[$i]);
continue;
@ -182,7 +183,7 @@ class MeetingsController extends Controller {
}
$result = [];
$meeting_select = ['id', 'father_id', 'title', 'text', 'memo', 'updated_at'];
$meeting_select = ['id', 'father_id', 'title', 'text', 'memo', 'updated_at', 'is_favorite'];
$meeting_approvals_select = ['child_id', 'approval_at'];
$child_select = ['image'];
@ -191,6 +192,7 @@ class MeetingsController extends Controller {
foreach ($list as $i => $l) {
$result[] = $l;
$result[$i]['approvals'] = MeetingApprovals::select($meeting_approvals_select)->whereNull('approval_at')->where('meeting_id', $l['id'])->orderBy('updated_at', 'desc')->get();
$result[$i]['total'] = MeetingApprovals::where('meeting_id', $l['id'])->count();
if (count($result[$i]['approvals']) > 1) {
unset($result[$i]);
continue;
@ -380,7 +382,7 @@ class MeetingsController extends Controller {
}
$result = [];
$meeting_select = ['id', 'father_id', 'title', 'text', 'memo', 'pdf', 'updated_at'];
$meeting_select = ['id', 'father_id', 'title', 'text', 'memo', 'pdf', 'updated_at', 'is_favorite'];
$meeting_images_select = ['image'];
$meeting_approvals_select = ['approval_at', 'child_id'];
$child_select = ['image'];

長すぎる行があるためファイル差分は表示されません

29
backend/resources/js/component/modal_memo.jsx ノーマルファイル
ファイルの表示

@ -0,0 +1,29 @@
import React, { useEffect, useState } from 'react';
import { makeStyles } from '@material-ui/styles';
const useStyles = makeStyles(theme => ({
show: {
display: 'block',
},
hide: {
display: 'none',
},
}));
export default function ModalMemo({ show, title, content, handleClose }){
const classes = useStyles();
return (
<div className={`modal-area modal-pd ${show ? classes.show : classes.hide}`}>
<div className="modal-bg"></div>
<div className="modal-wrap">
<h4 className="modal-ttl">{title}</h4>
<br/>
<p className="modal-ttl">{content}</p>
<p className="modal-close-btn">
<img onClick={handleClose} src="/assets/img/icon/plus02.svg" alt="閉じるボタン" width="18" height="18" />
</p>
</div>
</div>
)
}

ファイルの表示

@ -0,0 +1,151 @@
import React, { useEffect, useState } from 'react';
import axios from 'axios';
import { makeStyles } from '@material-ui/styles';
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
const useStyles = makeStyles(theme => ({
show: {
display: 'block',
},
hide: {
display: 'none',
},
}));
export default function ModalSettingNotify({show, meetingId}){
const classes = useStyles();
const [unapprovel, setUnapprovel ] = useState(null);
const [approvel, setApprovel ] = useState(null);
const [isApprovel, setIsApprovel ] = useState(false);
useEffect(() => {
axios.get(`/api/children/listOfMeetingNotifyApprovel/${meetingId}`, {params: { meeting_id: meetingId }}).then((response) => {
if(response.data.status_code==200){
console.log(response.data.params);
setApprovel(response.data.params);
} else if(response.data.status_code==400){
//TODO
}
});
}, []);
useEffect(() => {
axios.get(`/api/children/listOfMeetingNotifyUnapprovel/${meetingId}`, {params: { meeting_id: meetingId }}).then((response) => {
if(response.data.status_code==200){
console.log(response.data.params);
setUnapprovel(response.data.params);
} else if(response.data.status_code==400){
//TODO
}
});
}, []);
async function settingNotify(meetingId) {
// const formdata = new FormData();
// formdata.append('meeting_id', meetingId);
// axios.post('/api/meetings/registerFavorite', formdata).then((response) => {})
console.log(meetingId);
toast.success("SMSの送信に成功しました", {
position: "top-center",
autoClose: 5000,
className:"bg-success",
hideProgressBar: true,
closeOnClick: true,
pauseOnHover: true,
draggable: false,
progress: undefined,
style:{ color: '#ffffff', opacity: 0.95}
});
};
return (
<div className={`modal-area modal-up65 ${show ? classes.show : classes.hide}`} >
<div className="modal-bg"></div>
<div className="modal-box">
<ToastContainer />
<div className="modal-wrap">
<div className="modal-tab-area">
<div onClick={e => {setIsApprovel(false); }} className={`modal-tab-label ${isApprovel ? "" : "is-active"}`}><span>未承知</span></div>
<div onClick={e => {setIsApprovel(true); }} className={`modal-tab-label ${!isApprovel ? "" : "is-active"}`}><span>承知済み</span></div>
</div>
<div className="modal-content-area">
<div className={ `modal-content ${!isApprovel ? "is-active" : ""}` } style={{border:"none"}} id="item01">
{ unapprovel?.map((item, index) => {
return (
<div className="modal-content-item">
<div className="user-wrap">
<a href={`/c-account/profile/detail/${item.id}`} >
<div className="user-avatar">
<img alt="name" className="avatar-img" src={item.image} />
</div>
<p className="user-name">{item.last_name} {item.first_name}</p>
</a>
</div>
<div className="p-notification-btn">
<a onClick={e => settingNotify(item.id)} className="btn-default btn-yellow btn-notification btn-r3 btn-h30 btn-w100p btn-fz14">
<span>通知</span>
</a>
</div>
</div>
)
})}
<div className="modal-content-item">
<div className="user-wrap">
<a href={`/c-account/profile/detail/1`} >
<div className="user-avatar">
<img alt="name" className="avatar-img" src="../../../assets/img/avatar/avatar-sample03@2x.png" />
</div>
<p className="user-name">Data test 1</p>
</a>
</div>
<div className="p-notification-btn">
<a onClick={e => settingNotify(1)} className="btn-default btn-yellow btn-notification btn-r3 btn-h30 btn-w100p btn-fz14">
<span>通知</span>
</a>
</div>
</div>
</div>
<div className={ `modal-content ${isApprovel ? "is-active" : ""}` } style={{border:"none"}} id="item02">
{ approvel?.map((item, index) => {
return (
<div className="modal-content-item">
<div className="user-wrap">
<a href={`/c-account/profile/detail/${item.id}`} >
<div className="user-avatar">
<img alt="name" className="avatar-img" src={item.image} />
</div>
<p className="user-name">{item.last_name} {item.first_name}</p>
</a>
</div>
<div className="p-notification-btn">
<a onClick={e => settingNotify(item.id)} className="btn-default btn-yellow btn-notification btn-r3 btn-h30 btn-w100p btn-fz14">
<span>通知</span>
</a>
</div>
</div>
)
})}
<div className="modal-content-item">
<div className="user-wrap">
<a href={`/c-account/profile/detail/2`} >
<div className="user-avatar">
<img alt="name" className="avatar-img" src="../../../assets/img/avatar/avatar-sample03@2x.png" />
</div>
<p className="user-name">Data test 2</p>
</a>
</div>
<div className="p-notification-btn">
<a onClick={e => settingNotify(2)} className="btn-default btn-yellow btn-notification btn-r3 btn-h30 btn-w100p btn-fz14">
<span>通知</span>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
)
}

ファイルの表示

@ -1,6 +1,106 @@
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 MeetingAdd = () => {
const [textColor, setTextColor] = useState(null);
const [showAlert, setShowAlert] = useState(false);
const [messageAlert, setMessageAlert] = useState(null);
const fatherId = document.getElementById('father_id').value;
const [images, setImages] = useState([]);
const [pdf, setPdf] = useState(null);
const [title, setTitle] = useState(null);
const [memo, setMemo] = useState(null);
const [text, setText] = useState(null);
const history = useHistory();
const [errors, setErrors] = useState({
title:'',
memo:'',
text:'',
pdf:'',
images:''
})
async function handleClick() {
setErrors({
title:'',
memo:'',
text:'',
pdf:'',
images:''
});
try {
const formdata = new FormData();
formdata.append('father_id', fatherId);
formdata.append('title', title);
formdata.append('memo', memo);
formdata.append('text', text);
formdata.append('pdf', pdf);
formdata.append('images', images);
axios.post('/api/meetings/register', formdata)
.then(response => {
if(response.data.status_code==200){
history.push({
pathname: "/p-account/meetings/detail/1",
state: {message : "ミーティングを作成しました!"}
});
} else {
setMessageAlert('error');
setShowAlert(true);
}
});
} catch (error) {
console.log('error', error);
}
}
const handleImageChange = (e) => {
e.preventDefault();
let reader = new FileReader();
let _file = e.target.files[0];
reader.readAsDataURL(_file);
reader.onloadend = () => {
setImages([...images, 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);
// }
};
const handlePdfChange = (e) => {
e.preventDefault();
let reader = new FileReader();
let _file = e.target.files[0];
reader.readAsDataURL(_file);
reader.onloadend = () => {
setPdf(reader.result);
};
};
async function handleCloseAlert() {
setShowAlert(false);
};
return (
<div className="l-content">
<div className="l-content-w560">
@ -8,15 +108,7 @@ const MeetingAdd = () => {
<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" stroke-linecap="round" stroke-linejoin="round" stroke-width="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,50 +119,55 @@ const MeetingAdd = () => {
<div className="p-article__context">
<form action="" className="edit-form">
<div className="edit-set">
<label className="control-label" for="title">タイトル</label>
<input type="text" name="title" value="" className="input-default input-title input-h60 input-w480" id="title" />
<label className="control-label" htmlFor="title">タイトル</label>
<input type="text" name="title" value={ title } onChange={e=>setTitle(e.target.value)} className="input-default input-title input-h60 input-w480" id="title" />
</div>
<div className="edit-set">
<label className="control-label" for="meeting_textarea">本文</label>
<textarea name="data[MeetingContent][description]" rows="8" className="textarea-default" id="meeting_textarea"></textarea>
<label className="control-label" htmlFor="meeting_textarea">本文</label>
<textarea value={ text } onChange={e=>setText(e.target.value)} rows="8" className="textarea-default" id="meeting_textarea" />
</div>
<div className="edit-set">
<label className="control-label" htmlFor="meeting_textarea">メモ</label>
<textarea value={ memo } onChange={e=>setMemo(e.target.value)} rows="8" className="textarea-default" id="meeting_textarea" />
</div>
<div className="edit-set edit-set-mt15">
<label className="edit-set-file-label" for="file_pdf">
<label className="edit-set-file-label" htmlFor="file_pdf">
PDFアップロード
<input type="file" name="file_pdf" accept=".pdf" id="file_pdf" />
<input type="file" name="file_pdf" accept=".pdf" id="file_pdf" onChange={(e) => handlePdfChange(e)} />
</label>
</div>
<div className="edit-set edit-set-mt15">
<label className="edit-set-file-label" for="file_image">
<label className="edit-set-file-label" htmlFor="file_image">
画像アップロード
<input type="file" name="file_image" accept=".png, .jpg, .jpeg" id="file_image" />
<input type="file" name="file_image" accept=".png, .jpg, .jpeg" id="file_image" onChange={(e) => handleImageChange(e)} />
</label>
</div>
<div className="p-file-image">
<figure></figure>
<figure></figure>
<figure></figure>
<figure></figure>
<figure></figure>
<figure></figure>
<figure></figure>
<figure></figure>
<figure></figure>
<figure></figure>
{ images?.length > 0 && images.map((url,inx) => {
return (
<figure className="image-upload"><img src={url} alt="" /></figure>
);
})}
</div>
<div className="edit-set edit-set-send">
<label for="allmember_send">
<label htmlFor="allmember_send">
<input className="boolean optional" type="checkbox" name="allmember_send" id="allmember_send" />全員に送信</label>
</div>
<div className="edit-set-mt5 edit-set-send">
<label for="pickup_send">
<label htmlFor="pickup_send">
<input className="boolean optional" type="checkbox" name="pickup_send" id="pickup_send" />選んで送信</label>
</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>
</div>
@ -79,6 +176,12 @@ const MeetingAdd = () => {
</div>
</div>
</div>
<ModalAlert
show={showAlert}
message={messageAlert}
textColor={textColor}
handleClose={handleCloseAlert}
/>
</div>
)
}

ファイルの表示

@ -1,25 +1,50 @@
import React, { useEffect, useState } from 'react';
import moment from 'moment';
import axios from 'axios';
import ModalSettingNotify from '../../component/modal_setting_notify';
import { ToastContainer, toast } from 'react-toastify';
import ModalMemo from '../../component/modal_memo';
import ModalConfirm from '../../component/modal_confirm';
import ModalAlert from '../../component/modal_alert';
import Notification from '../../component/notification';
import { useHistory } from 'react-router-dom'
const MeetingDetail = (props) => {
const history = useHistory();
const [show, setShow] = useState(false);
const [showArea, setShowArea] = useState(false);
const [showMemo, setShowMemo] = useState(false);
const [showNotify, setShowNotify] = useState(false);
const [showAlert, setShowAlert] = useState(false);
const [messageAlert, setMessageAlert] = useState(null);
const [typeAlert, setTypeAlert] = useState(null);
const [meeting, setMeeting] = useState(null);
const [picture, setPicture] = useState(null);
const state = history.location.state
useEffect(() => {
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]);
setMeeting(response.data.params[0]);
setPicture(response.data.params[0]?.meeting_image[0]?.image);
} else if(response.data.status_code==400){
//TODO
}
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}
});
}
});
}, []);
@ -55,29 +80,71 @@ const MeetingDetail = (props) => {
console.log('error', error);
}
};
async function showModalMemo() {
setShowMemo(true);
};
async function showModalArea() {
setShowArea(true);
};
async function showModalNotify() {
setShowNotify(true);
};
async function handleCloseNotify() {
setShowNotify(false);
};
async function handleCloseMemo() {
setShowMemo(false);
};
async function handleAcceptNotify() {
try {
axios.post(`/api/children/listOfMeetingNotifyUnapprovel/${props.match.params?.id}`)
.then(response => {
if(response.data.status_code == 200){
axios.delete(`/api/smss/register/${props.match.params?.id}`)
.then(response => {
});
}
});
setShowNotify(false);
} catch (error) {
console.log('error', error);
}
};
async function handleCloseAlert() {
setShowAlert(false);
};
async function handleFavorite(meetingId, currentFavorite) {
const formdata = new FormData();
formdata.append('meeting_id', meetingId);
formdata.append('is_favorite', currentFavorite == 1 ? 0 : 1);
axios.post('/api/meetings/registerFavorite', formdata).then((response) => {})
const updatedItem = {
...meeting,
is_favorite: currentFavorite == 1 ? 0 : 1,
};
setMeeting(updatedItem);
};
if (!meeting) return null;
return (
<div className="l-content">
<ToastContainer />
<div className="l-content-w560">
<div className="l-content__ttl">
<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">
@ -87,52 +154,24 @@ const MeetingDetail = (props) => {
<div className="p-article__content">
<div className="meeting-member">
<div className="meeting-member-wrap">
<div data-url="login.html" className="meeting-member-link">
<div onClick={showModalArea} data-url="login.html" className="meeting-member-link">
<ul className="meeting-member-count">
<li className="numerator">3</li>
<li className="denominator">4</li>
<li className="numerator">{meeting?.meeting_approvals.length}</li>
<li className="denominator">{meeting?.meeting_approvals.length}</li>
</ul>
<ul className="meeting-member-list" role="list">
<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>
<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>
{ meeting?.meeting_approvals.map((v, inx) => {
return (<li className="meeting-member__item" role="listitem">
<div className="avatar">
<img alt="name" className="avatar-img" src={v?.child.image} />
</div>
</li>);
}) }
</ul>
<div className="meeting-member__read">
<p>3人既読</p>
<p>{meeting?.meeting_approvals.length}人既読</p>
</div>
</div>
</div>
@ -159,10 +198,18 @@ const MeetingDetail = (props) => {
<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>
<a
onClick={e => {
e.preventDefault();
history.push({
pathname: '/p-account/meeting/new',
state: {}
});
}}
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>
<a onClick={showModalNotify} className="btn-default btn-yellow btn-pdf btn-r8 btn-h48">再通知</a>
</li>
</ul>
@ -170,32 +217,28 @@ const MeetingDetail = (props) => {
<div className="p-file-list">
<div className="p-file-for">
<figure><img src="../../../assets/img/dummy/post-dummy01.jpg" alt="" /></figure>
<figure><img src={picture} alt="" /></figure>
</div>
<div className="p-file-nav">
<figure><img src="../../../assets/img/dummy/post-dummy01.jpg" alt="" /></figure>
<figure><img src="../../../assets/img/dummy/post-dummy02.jpg" alt="" /></figure>
<figure><img src="../../../assets/img/dummy/post-dummy03.jpg" alt="" /></figure>
<figure><img src="../../../assets/img/dummy/post-dummy04.jpg" alt="" /></figure>
<figure><img src="../../../assets/img/dummy/post-dummy05.jpg" alt="" /></figure>
<figure><img src="../../../assets/img/dummy/post-dummy01.jpg" alt="" /></figure>
<figure><img src="../../../assets/img/dummy/post-dummy02.jpg" alt="" /></figure>
<figure><img src="../../../assets/img/dummy/post-dummy03.jpg" alt="" /></figure>
<figure><img src="../../../assets/img/dummy/post-dummy04.jpg" alt="" /></figure>
<figure><img src="../../../assets/img/dummy/post-dummy05.jpg" alt="" /></figure>
<figure><img src="../../../assets/img/dummy/post-dummy03.jpg" alt="" /></figure>
<figure><img src="../../../assets/img/dummy/post-dummy04.jpg" alt="" /></figure>
<figure><img src="../../../assets/img/dummy/post-dummy05.jpg" alt="" /></figure>
{ meeting?.meeting_image.map((v, inx) => {
return ( <figure onClick={e => { setPicture(v.image);}} ><img src={v.image} alt="" /></figure> );
}) }
</div>
</div>
<div className="p-article__pdf">
<div className="p-article__pdf__btn">
<a data-v-ade1d018="" className="btn-default btn-yellow btn-pdf btn-r8 btn-h52">
<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" onClick={showModalMemo} aria-label="メモ" data-tooltip="メモ" aria-pressed="false" style={{marginRight:10}} className="icon a-icon like-icon icon-starFill-wrap a-icon-size_medium"></button>
<button type="button"
onClick={e => {
e.preventDefault();
handleFavorite(meeting.id, meeting.is_favorite);
}}
aria-label="お気に入り" data-tooltip="お気に入り" aria-pressed="false" className={`icon a-icon like-icon ${meeting.is_favorite == 1 ? "icon-starFill icon-starFill-wrap" : "icon-star icon-star-wrap"} a-icon-size_medium`}></button>
</div>
<p className="p-article__txt">{ meeting.text }</p>
@ -206,12 +249,31 @@ const MeetingDetail = (props) => {
</div>
</div>
</div>
<ModalSettingNotify
show={showArea}
meetingId={meeting.id}
// message={"\n"}
// handleClose={handleClose}
// handleAccept={handleAccept}
/>
<ModalMemo
show={showMemo}
title={"メモ"}
content={meeting?.memo}
handleClose={handleCloseMemo}
/>
<ModalConfirm
show={show}
message={"本当に削除しても\nよろしいでしょうか?"}
handleClose={handleClose}
handleAccept={handleAccept}
/>
<ModalConfirm
show={showNotify}
message={"本当に再通知しても\nよろしいでしょうか?"}
handleClose={handleCloseNotify}
handleAccept={handleAcceptNotify}
/>
<ModalAlert
show={showAlert}
message={messageAlert}

ファイルの表示

@ -3,11 +3,18 @@ import axios from 'axios';
const MeetingEdit = (props) => {
const [meeting, setMeeting] = useState(null);
const [title, setTitle] = useState(null);
const [memo, setMemo] = useState(null);
const [text, setText] = useState(null);
const fatherId = document.getElementById('father_id').value;
useEffect(() => {
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]);
setMeeting(response.data.params[0]);
setTitle(response.data.params[0]?.title);
setMemo(response.data.params[0]?.memo);
setText(response.data.params[0]?.text);
} else if(response.data.status_code==400){
//TODO
}
@ -15,6 +22,40 @@ const MeetingEdit = (props) => {
});
}, []);
async function handleClick() {
// setErrors({
// title:'',
// memo:'',
// text:'',
// pdf:'',
// images:''
// });
try {
const formdata = new FormData();
formdata.append('father_id', fatherId);
formdata.append('title', title);
formdata.append('memo', memo);
formdata.append('text', text);
// formdata.append('pdf', pdf);
// formdata.append('images', images);
// axios.post('/api/meetings/register', formdata)
// .then(response => {
// if(response.data.status_code==200){
// history.push({
// pathname: "/p-account/meetings/detail/1",
// state: {message : ""}
// });
// } else {
// setMessageAlert('error');
// setShowAlert(true);
// }
// });
} catch (error) {
console.log('error', error);
}
}
if (!meeting) return null;
return (
<div className="l-content">
@ -27,7 +68,7 @@ const MeetingEdit = (props) => {
<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" stroke-linecap="round" stroke-linejoin="round" stroke-width="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>
<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>
@ -41,21 +82,25 @@ const MeetingEdit = (props) => {
<div className="p-article__context">
<form action="" className="edit-form">
<div className="edit-set">
<label className="control-label" for="title">タイトル</label>
<input type="text" name="title" value={meeting.title} className="input-default input-title input-h60 input-w480" id="title" />
<label className="control-label" htmlFor="title">タイトル</label>
<input type="text" name="title" value={ title } onChange={e=>setTitle(e.target.value)} className="input-default input-title input-h60 input-w480" id="title" />
</div>
<div className="edit-set">
<label className="control-label" for="meeting_textarea">本文</label>
<textarea name="data[MeetingContent][description]" rows="8" className="textarea-default" id="meeting_textarea">{meeting.text}</textarea>
<label className="control-label" htmlFor="meeting_textarea">本文</label>
<textarea value={ text } onChange={e=>setText(e.target.value)} rows="8" className="textarea-default" id="meeting_textarea" />
</div>
<div className="edit-set">
<label className="control-label" htmlFor="meeting_textarea">メモ</label>
<textarea value={ memo } onChange={e=>setMemo(e.target.value)} rows="8" className="textarea-default" id="meeting_textarea" />
</div>
<div className="edit-set edit-set-mt15">
<label className="edit-set-file-label" for="file_pdf">
<label className="edit-set-file-label" htmlFor="file_pdf">
PDFアップロード
<input type="file" name="file_pdf" accept=".pdf" id="file_pdf" />
</label>
</div>
<div className="edit-set edit-set-mt15">
<label className="edit-set-file-label" for="file_image">
<label className="edit-set-file-label" htmlFor="file_image">
画像アップロード
<input type="file" name="file_image" accept=".png, .jpg, .jpeg" id="file_image" />
</label>
@ -75,39 +120,45 @@ const MeetingEdit = (props) => {
</div>
<div className="edit-set edit-set-send">
<label for="allmember_send">
<label htmlFor="allmember_send">
<input className="boolean optional" type="checkbox" name="allmember_send" id="allmember_send" />全員に送信</label>
</div>
<div className="edit-set-mt5 edit-set-send">
<label for="pickup_send">
<label htmlFor="pickup_send">
<input className="boolean optional" type="checkbox" name="pickup_send" id="pickup_send" />選んで送信</label>
</div>
<div className="checkbox-wrap edit-bg">
<div className="checkbox">
<label for="user_name01">
<label htmlFor="user_name01">
<input className="boolean optional" type="checkbox" name="chk[]" id="user_name01" />田中 達也</label>
</div>
<div className="checkbox">
<label for="user_name02">
<label htmlFor="user_name02">
<input className="boolean optional" type="checkbox" name="chk[]" id="user_name02" />田中 達也</label>
</div>
<div className="checkbox">
<label for="user_name03">
<label htmlFor="user_name03">
<input className="boolean optional" type="checkbox" name="chk[]" id="user_name03" />田中 達也</label>
</div>
<div className="checkbox">
<label for="user_name04">
<label htmlFor="user_name04">
<input className="boolean optional" type="checkbox" name="chk[]" id="user_name04" />田中 達也</label>
</div>
<div className="checkbox">
<label for="user_name05">
<label htmlFor="user_name05">
<input className="boolean optional" type="checkbox" name="chk[]" id="user_name05" />田中 達也</label>
</div>
</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>
</div>

ファイルの表示

@ -1,19 +1,22 @@
import React, { useEffect, useState } from 'react';
import { CircularProgress } from '@material-ui/core';
import Notification from '../../component/notification';
import moment from 'moment';
import axios from 'axios';
import { useHistory } from 'react-router-dom'
const Meeting = () => {
const history = useHistory();
const fatherId = document.getElementById('father_id').value;
const [loading, setLoading] = useState(true);
const [finish, setFinish] = useState(false);
const [completeOfFather, setCompleteOfFather ] = useState(null);
const [inCompleteOfFather, setInCompleteOfFather ] = useState(null);
useEffect(() => {
axios.get('/api/meetings/listOfCompleteOfFather', {params: { father_id: 1 }}).then((response) => {
axios.get('/api/meetings/listOfCompleteOfFather', {params: { father_id: fatherId }}).then((response) => {
if(response.data.status_code==200){
console.log(response.data.params);
setCompleteOfFather(response.data.params);
} else if(response.data.status_code==400){
//TODO
}
@ -33,6 +36,41 @@ const Meeting = () => {
});
}, []);
async function handleFavorite(meetingId, currentFavorite, stateName) {
const formdata = new FormData();
formdata.append('meeting_id', meetingId);
formdata.append('is_favorite', currentFavorite == 1 ? 0 : 1);
axios.post('/api/meetings/registerFavorite', formdata).then((response) => {})
if(stateName == "inCompleteOfFather") {
const newList = inCompleteOfFather.map((item) => {
if (item.id === meetingId) {
const updatedItem = {
...item,
is_favorite: currentFavorite == 1 ? 0 : 1,
};
return updatedItem;
}
return item;
});
setInCompleteOfFather(newList);
} else {
const newList = completeOfFather.map((item) => {
if (item.id === meetingId) {
const updatedItem = {
...item,
is_favorite: currentFavorite == 1 ? 0 : 1,
};
return updatedItem;
}
return item;
});
setCompleteOfFather(newList);
}
};
return (
<div className="l-content">
<div className="l-content__ttl">
@ -56,17 +94,7 @@ const Meeting = () => {
</a>
</div>
</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">
@ -100,7 +128,7 @@ const Meeting = () => {
<div className="meeting-content">
<div className={ `meeting-content-wrap ${!finish ? "is-active" : ""}` } id="item01">
{ !loading ? inCompleteOfFather?.map((item, index) => {
{ !loading ? inCompleteOfFather?.map((item, index1) => {
return (
<div className="meeting-item">
<a
@ -121,32 +149,29 @@ const Meeting = () => {
<div className="meeting-member-wrap">
<div data-url="login.html" className="meeting-member-link">
<ul className="meeting-member-count">
<li className="numerator">3</li>
<li className="denominator">4</li>
<li className="numerator">{item?.approvals.length}</li>
<li className="denominator">{item?.total}</li>
</ul>
<ul className="meeting-member-list" role="list">
<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>
{ item?.approvals.map((v, inx1) => {
return (<li className="meeting-member__item" role="listitem">
<div className="avatar">
<img alt="name" className="avatar-img" src={v?.child.image} />
</div>
</li>);
}) }
</ul>
</div>
</div>
</div>
</a>
<button type="button" aria-label="お気に入り" data-tooltip="お気に入り" aria-pressed="false" className="icon a-icon like-icon icon-star a-icon-size_medium"></button>
<button type="button" aria-label="お気に入り" data-tooltip="お気に入り" aria-pressed="false"
onClick={e => {
e.preventDefault();
handleFavorite(item.id, item.is_favorite, 'inCompleteOfFather');
}}
className={`icon a-icon like-icon ${item.is_favorite == 1 ? "icon-starFill" : "icon-star"} a-icon-size_medium`}></button>
</div>
);
}) : <CircularProgress /> }
@ -174,32 +199,29 @@ const Meeting = () => {
<div className="meeting-member-wrap">
<div data-url="login.html" className="meeting-member-link">
<ul className="meeting-member-count">
<li className="numerator">3</li>
<li className="denominator">4</li>
<li className="numerator">{item?.approvals.length}</li>
<li className="denominator">{item?.total}</li>
</ul>
<ul className="meeting-member-list" role="list">
<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>
{ item?.approvals.map((v, inx2) => {
return (<li className="meeting-member__item" role="listitem">
<div className="avatar">
<img alt="name" className="avatar-img" src={v?.child.image} />
</div>
</li>);
}) }
</ul>
</div>
</div>
</div>
</a>
<button type="button" aria-label="お気に入り" data-tooltip="お気に入り" aria-pressed="false" className="icon a-icon like-icon icon-star a-icon-size_medium"></button>
<button type="button" aria-label="お気に入り" data-tooltip="お気に入り" aria-pressed="false"
onClick={e => {
e.preventDefault();
handleFavorite(item.id, item.is_favorite, 'completeOfFather');
}}
className={`icon a-icon like-icon ${item.is_favorite == 1 ? "icon-starFill" : "icon-star"} a-icon-size_medium`}></button>
</div>
);
}) }

ファイルの表示

@ -7,7 +7,7 @@ export default function Side() {
return (
<div className="l-side">
<div className="l-side-logo">
<a href=""><img src="../assets/img/common/logo.svg" alt="ロゴ" /></a>
<a href=""><img src="../../../assets/img/common/logo.svg" alt="ロゴ" /></a>
</div>
<nav className="mypage-nav">
<ul className="mypage-nav-list">