update nhan anh
This commit is contained in:
parent
2b8ec4f708
commit
121aab8463
|
@ -23,6 +23,7 @@
|
||||||
"react-loading-overlay": "^1.0.1",
|
"react-loading-overlay": "^1.0.1",
|
||||||
"react-router-dom": "5.2.0",
|
"react-router-dom": "5.2.0",
|
||||||
"react-scripts": "5.0.0",
|
"react-scripts": "5.0.0",
|
||||||
|
"react-select": "^5.2.1",
|
||||||
"react-spinners": "^0.11.0",
|
"react-spinners": "^0.11.0",
|
||||||
"sweetalert": "^2.1.2",
|
"sweetalert": "^2.1.2",
|
||||||
"web-vitals": "^2.1.2"
|
"web-vitals": "^2.1.2"
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import ListItem from './components/List/ListItem';
|
import ListItem from './components/List/ListItem';
|
||||||
import Login from './components/Login/Login';
|
import Login from './components/Login/Login';
|
||||||
|
import LabelImage from './components/LabelImg/LabelImage';
|
||||||
import SearchImage from './components/SearchImg/SearchImage';
|
import SearchImage from './components/SearchImg/SearchImage';
|
||||||
import ImportImage from './components/ImportImg/ImportImage';
|
import ImportImage from './components/ImportImg/ImportImage';
|
||||||
|
import Test from './components/Test/Test';
|
||||||
import MenuBar from './components/layouts/MenuBar'
|
import MenuBar from './components/layouts/MenuBar'
|
||||||
import Header from './components/layouts/Header'
|
import Header from './components/layouts/Header'
|
||||||
import 'antd/dist/antd.css';
|
import 'antd/dist/antd.css';
|
||||||
|
@ -19,10 +21,12 @@ function App() {
|
||||||
<Header />
|
<Header />
|
||||||
<MenuBar />
|
<MenuBar />
|
||||||
<div>
|
<div>
|
||||||
{/* <Redirect exact from='/' to='/search-image' /> */}
|
<Redirect exact from='/' to='/search-image' />
|
||||||
<Route path='/login' component={Login} />
|
<Route path='/login' component={Login} />
|
||||||
<Route path='/import-image' component={ImportImage} />
|
<Route path='/import-image' component={ImportImage} />
|
||||||
<Route path='/search-image' component={SearchImage} />
|
<Route path='/search-image' component={SearchImage} />
|
||||||
|
<Route path='/label-image' component={LabelImage} />
|
||||||
|
<Route path='/test' component={Test} />
|
||||||
<Route path="/list-famous" component={ListItem} />
|
<Route path="/list-famous" component={ListItem} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -8,9 +8,10 @@ import { PulseLoader } from 'react-spinners';
|
||||||
import Modalupload from '../Modal/ModalUpload';
|
import Modalupload from '../Modal/ModalUpload';
|
||||||
import ModalEditImg from '../Modal/ModalEditImg';
|
import ModalEditImg from '../Modal/ModalEditImg';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { Avatar, Tooltip } from 'antd';
|
import { Avatar, Tooltip, Image } from 'antd';
|
||||||
import {UserOutlined} from '@ant-design/icons';
|
import {UserOutlined} from '@ant-design/icons';
|
||||||
import momment from 'moment';
|
import momment from 'moment';
|
||||||
|
import Select from "react-select";
|
||||||
class ImportImage extends Component {
|
class ImportImage extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -28,7 +29,9 @@ class ImportImage extends Component {
|
||||||
modalShow: false,
|
modalShow: false,
|
||||||
dataEdit: null,
|
dataEdit: null,
|
||||||
modalUploadShow: false,
|
modalUploadShow: false,
|
||||||
dataSearch: ""
|
dataSearch: "",
|
||||||
|
optionSelect: [{value: 1, label:"Facebook"}, {value: 2, label: "Tải lên"}],
|
||||||
|
valueSelected: {value: 2, label:"Tải lên"},
|
||||||
}
|
}
|
||||||
this.itemsPerPage = 5;
|
this.itemsPerPage = 5;
|
||||||
}
|
}
|
||||||
|
@ -52,7 +55,8 @@ class ImportImage extends Component {
|
||||||
data: {
|
data: {
|
||||||
index: page,
|
index: page,
|
||||||
item_per_page: this.itemsPerPage,
|
item_per_page: this.itemsPerPage,
|
||||||
search_data: this.state.dataSearch
|
search_data: this.state.dataSearch,
|
||||||
|
import_type: this.state.valueSelected.value
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -149,11 +153,20 @@ class ImportImage extends Component {
|
||||||
this.setState({
|
this.setState({
|
||||||
activePage: 1,
|
activePage: 1,
|
||||||
dataSearch: "",
|
dataSearch: "",
|
||||||
|
valueSelected: {value: 2, label:"Tải lên"},
|
||||||
}, () => {
|
}, () => {
|
||||||
this.getListImg(1);
|
this.getListImg(1);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
changeHandleFilter = (e) => {
|
||||||
|
this.setState({
|
||||||
|
valueSelected: e,
|
||||||
|
activePage: 1
|
||||||
|
}, () => {
|
||||||
|
this.getListImg(1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
// if (this.state.isLogin == false) {
|
// if (this.state.isLogin == false) {
|
||||||
|
@ -164,7 +177,7 @@ class ImportImage extends Component {
|
||||||
let bulletedListImg = this.state.listImgImport.map((value, index) => {
|
let bulletedListImg = this.state.listImgImport.map((value, index) => {
|
||||||
|
|
||||||
var listImg
|
var listImg
|
||||||
listImg = <img key={index} style={{ width: "80px", height: "80px" }} alt="" src={`${value.image_host}`} />
|
listImg = <Image style={{ width: "80px", height: "auto", objectFit: "contain"}} alt="" src={`${value.image_host}`} />
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -172,6 +185,7 @@ class ImportImage extends Component {
|
||||||
<td>{(index + this.state.offset + 1)}</td>
|
<td>{(index + this.state.offset + 1)}</td>
|
||||||
<td>{listImg}</td>
|
<td>{listImg}</td>
|
||||||
<td>{value.origin_name}</td>
|
<td>{value.origin_name}</td>
|
||||||
|
<td>{value.import_type === 1 ? "Facebook" : "Tải lên"}</td>
|
||||||
<td>{momment(value.created_time).format("DD-MM-YYYY")}</td>
|
<td>{momment(value.created_time).format("DD-MM-YYYY")}</td>
|
||||||
<td>
|
<td>
|
||||||
<Tooltip placement="top" title={"Sửa"}>
|
<Tooltip placement="top" title={"Sửa"}>
|
||||||
|
@ -235,6 +249,14 @@ class ImportImage extends Component {
|
||||||
data-col-index={0}
|
data-col-index={0}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="form-group m-form__group col-xl-2">
|
||||||
|
<Select
|
||||||
|
placeholder={'Loại ảnh'}
|
||||||
|
value={this.state.valueSelected}
|
||||||
|
onChange={this.changeHandleFilter}
|
||||||
|
options={this.state.optionSelect}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div className="pl-3">
|
<div className="pl-3">
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
@ -285,6 +307,7 @@ class ImportImage extends Component {
|
||||||
<th style={{width: "50px"}}>STT</th>
|
<th style={{width: "50px"}}>STT</th>
|
||||||
<th>Ảnh</th>
|
<th>Ảnh</th>
|
||||||
<th>Tên ảnh</th>
|
<th>Tên ảnh</th>
|
||||||
|
<th>Loại ảnh</th>
|
||||||
<th>Ngày tải lên</th>
|
<th>Ngày tải lên</th>
|
||||||
<th>Thao tác</th>
|
<th>Thao tác</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
334
app/src/components/LabelImg/LabelImage.js
Normal file
334
app/src/components/LabelImg/LabelImage.js
Normal file
|
@ -0,0 +1,334 @@
|
||||||
|
import { UserOutlined } from '@ant-design/icons';
|
||||||
|
import { Avatar, Tooltip } from 'antd';
|
||||||
|
import axios from 'axios';
|
||||||
|
import ModalEditLabel from '../Modal/ModaEditLabel';
|
||||||
|
import momment from 'moment';
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import Pagination from "react-js-pagination";
|
||||||
|
import { PulseLoader } from 'react-spinners';
|
||||||
|
import { HOST } from '../../config/index';
|
||||||
|
import swal from 'sweetalert';
|
||||||
|
import { useLocation } from 'react-router-dom';
|
||||||
|
|
||||||
|
const initialDataPost = {
|
||||||
|
index: 1,
|
||||||
|
item_per_page: 5,
|
||||||
|
search_data: "",
|
||||||
|
person_type: 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function LabelImage() {
|
||||||
|
|
||||||
|
const [data, setData] = useState(null)
|
||||||
|
const [showModal, setShowModal] = useState(false)
|
||||||
|
const [dataEdit, setDataEdit] = useState(null)
|
||||||
|
|
||||||
|
const [loading, setLoading] = useState(true)
|
||||||
|
|
||||||
|
const [activePage, setActivePage] = useState(1)
|
||||||
|
const [totalItems, setTotalItems] = useState(0)
|
||||||
|
|
||||||
|
const [dataPost, setDataPost] = useState(initialDataPost)
|
||||||
|
const itemsPerPage = 5
|
||||||
|
|
||||||
|
const [token, setToken] = useState('');
|
||||||
|
|
||||||
|
const location = useLocation();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (location.search) {
|
||||||
|
let path = location.search.replace('?', '').split('&');
|
||||||
|
let obj = {}
|
||||||
|
path.forEach(value => {
|
||||||
|
let arr = value.split('=');
|
||||||
|
obj[arr[0]] = arr[1]
|
||||||
|
})
|
||||||
|
setToken(decodeURIComponent(obj.token))
|
||||||
|
setToken((obj.token))
|
||||||
|
}
|
||||||
|
}, [location])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getData()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const onClickEdit = (data) => {
|
||||||
|
setDataEdit(data)
|
||||||
|
setShowModal(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
const onDelete = async (value) => {
|
||||||
|
let dataDel = {
|
||||||
|
obj_id: value._id,
|
||||||
|
id: value.id,
|
||||||
|
name: value.name,
|
||||||
|
birthday: value.birthday,
|
||||||
|
gender: value.gender,
|
||||||
|
is_deleted : 1
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const result = await axios({
|
||||||
|
method: 'POST',
|
||||||
|
url: `${HOST}/api/famous_persons/insert_or_update`,
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
// 'Authorization': token,
|
||||||
|
},
|
||||||
|
data: dataDel,
|
||||||
|
})
|
||||||
|
if (result.data.status === 10000) {
|
||||||
|
if (data.length === 1) {
|
||||||
|
setActivePage(activePage - 1)
|
||||||
|
setDataPost({ ...dataPost, index: activePage - 1 })
|
||||||
|
}
|
||||||
|
swal({
|
||||||
|
icon: 'success',
|
||||||
|
title: 'Thành công',
|
||||||
|
text: 'Xoá thành công',
|
||||||
|
timer: 1500,
|
||||||
|
buttons: false,
|
||||||
|
})
|
||||||
|
getData(dataPost)
|
||||||
|
} else {
|
||||||
|
swal("Thất bại", "Xoá thất bại!", "error");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
setLoading(false)
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlePageChange = (pageNumber) => {
|
||||||
|
setActivePage(pageNumber);
|
||||||
|
const data = {
|
||||||
|
...dataPost,
|
||||||
|
index: pageNumber,
|
||||||
|
}
|
||||||
|
getData(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getData = async (data) => {
|
||||||
|
try {
|
||||||
|
const result = await axios({
|
||||||
|
method: 'POST',
|
||||||
|
url: `${HOST}/api/famous_persons/search`,
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
// 'Authorization': token
|
||||||
|
},
|
||||||
|
data: data ? data : dataPost,
|
||||||
|
})
|
||||||
|
if (result.data.status === 10000) {
|
||||||
|
setData(result.data.data)
|
||||||
|
setTotalItems(result.data.count)
|
||||||
|
setLoading(false)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
setLoading(false)
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleOnKeyDown = e => {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
setActivePage(1)
|
||||||
|
getData(dataPost);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const tableRows = (dataAll) => dataAll.map((value, index) => {
|
||||||
|
var gender = ""
|
||||||
|
if (value.gender === "1") {
|
||||||
|
gender = "Nam"
|
||||||
|
} else if (value.gender === "2") {
|
||||||
|
gender = "Nữ"
|
||||||
|
} else if (value.gender === "3") {
|
||||||
|
gender = "Giới tính khác"
|
||||||
|
} else {
|
||||||
|
gender = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
var listImg
|
||||||
|
if (value.sample_images.length > 0) {
|
||||||
|
let getDateImg = value.sample_images[0].split("_")
|
||||||
|
let dataImg = getDateImg.length > 0 && getDateImg[1].slice(0,6)
|
||||||
|
listImg = <img key={index} style={{ width: "80px", height: "80px" }} alt="" src={`${value.sample_images.length > 0 && value.image_host +dataImg+ "/" +value.sample_images[0]}`} />
|
||||||
|
} else {
|
||||||
|
listImg = <Avatar shape="square" size={80} icon={<UserOutlined />} />
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<tr key={index}>
|
||||||
|
<td>{listImg}</td>
|
||||||
|
<td>{value.name}</td>
|
||||||
|
<td>{value.id}</td>
|
||||||
|
<td>{gender}</td>
|
||||||
|
<td>{value.birthday !== "" ? momment(value.birthday).format("DD-MM-YYYY") : ""}</td>
|
||||||
|
<td>
|
||||||
|
<Tooltip placement="top" title={"Sửa"}>
|
||||||
|
<button
|
||||||
|
onClick={() => onClickEdit(value)}
|
||||||
|
className="m-portlet__nav-link btn m-btn m-btn--hover-warning m-btn--icon m-btn--icon-only m-btn--pill" data-tip data-for="Edit" >
|
||||||
|
<i className="la la-edit" />
|
||||||
|
</button>
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip placement="top" title={"Xoá"}>
|
||||||
|
<button
|
||||||
|
onClick={f => {
|
||||||
|
f.preventDefault();
|
||||||
|
swal({
|
||||||
|
// title: "Are you sure?",
|
||||||
|
text: "Bạn có chắc muốn xoá " + value.name,
|
||||||
|
icon: "warning",
|
||||||
|
buttons: ["Huỷ", "Xoá"],
|
||||||
|
dangerMode: true,
|
||||||
|
})
|
||||||
|
.then(willDelete => {
|
||||||
|
if (willDelete) {
|
||||||
|
onDelete(value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
className="m-portlet__nav-link btn m-btn m-btn--hover-danger m-btn--icon m-btn--icon-only m-btn--pill" data-tip data-for="Edit" >
|
||||||
|
<i className="la la-trash" />
|
||||||
|
</button>
|
||||||
|
</Tooltip>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const onCloseModal = () => {
|
||||||
|
setShowModal(false)
|
||||||
|
// setActivePage(activePage)
|
||||||
|
const data = {
|
||||||
|
...dataPost,
|
||||||
|
index: activePage,
|
||||||
|
}
|
||||||
|
getData(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
const reset = () => {
|
||||||
|
setActivePage(1)
|
||||||
|
setDataPost({...dataPost, search_data: ""})
|
||||||
|
getData(initialDataPost)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{showModal && <ModalEditLabel data={dataEdit} onHide={onCloseModal} show={showModal} />}
|
||||||
|
<div className="m-portlet m-portlet--mobile pb-3">
|
||||||
|
<div className="m-portlet__head">
|
||||||
|
<div className="m-portlet__head-caption">
|
||||||
|
<div className="m-portlet__head-title">
|
||||||
|
<h3 className="m-portlet__head-text">
|
||||||
|
Gán nhãn
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="m-portlet__body pt-2">
|
||||||
|
<div className="row pl-4">
|
||||||
|
<div className="row p-3 col-xl-11">
|
||||||
|
<div className="col-lg-2 p-0 m--margin-bottom-10-tablet-and-mobile">
|
||||||
|
<input type="text"
|
||||||
|
onKeyPress={(e) => handleOnKeyDown(e)}
|
||||||
|
onChange={(e) => {
|
||||||
|
setDataPost({ ...dataPost, search_data: e.target.value })
|
||||||
|
}}
|
||||||
|
value={dataPost.search_data}
|
||||||
|
id="inputSearch" className="form-control m-input"
|
||||||
|
placeholder="Họ tên..."
|
||||||
|
data-col-index={0}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="pl-3">
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
setActivePage(1)
|
||||||
|
getData(dataPost)
|
||||||
|
}}
|
||||||
|
className="btn btn-accent m-btn m-btn--icon" id="m_search">
|
||||||
|
<span>
|
||||||
|
<i className="la la-search" />
|
||||||
|
<span>Tìm kiếm</span>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="pl-3">
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
reset()
|
||||||
|
}}
|
||||||
|
className="btn btn-secondary m-btn m-btn--icon" id="m_reset">
|
||||||
|
<span>
|
||||||
|
<i className="la la-rotate-left" />
|
||||||
|
<span>Tải lại</span>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="m-portlet__head-tools col-xl-1 d-flex align-items-center">
|
||||||
|
<button
|
||||||
|
onClick={(e) => {
|
||||||
|
let dataEdit = {
|
||||||
|
obj_id: "",
|
||||||
|
id: "",
|
||||||
|
name: "",
|
||||||
|
birthday: "",
|
||||||
|
gender: "",
|
||||||
|
sample_images: [],
|
||||||
|
image_host: ""
|
||||||
|
};
|
||||||
|
setDataEdit(dataEdit)
|
||||||
|
setShowModal(true)
|
||||||
|
}}
|
||||||
|
className="btn btn-accent m-btn m-btn--custom m-btn--icon m-btn--pill m-btn--air">
|
||||||
|
<span>
|
||||||
|
<i className="la la-plus" />
|
||||||
|
<span>Thêm mới</span>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/*begin: Datatable */}
|
||||||
|
<table className="table table-striped- table-bordered table-hover table-checkable" id="m_table_1">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Ảnh</th>
|
||||||
|
<th>Họ tên</th>
|
||||||
|
<th>FacebookID</th>
|
||||||
|
<th>Giới tính</th>
|
||||||
|
<th>Ngày sinh</th>
|
||||||
|
<th>Thao tác</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>{data && tableRows(data)}</tbody>
|
||||||
|
</table>
|
||||||
|
<PulseLoader
|
||||||
|
// css={override}
|
||||||
|
sizeUnit={"px"}
|
||||||
|
size={12}
|
||||||
|
margin={'2px'}
|
||||||
|
color={'#36D7B7'}
|
||||||
|
loading={loading}
|
||||||
|
/>
|
||||||
|
<Pagination
|
||||||
|
prevPageText='Trang trước'
|
||||||
|
nextPageText='Trang sau'
|
||||||
|
firstPageText='Trang đầu'
|
||||||
|
lastPageText='Trang cuối'
|
||||||
|
activePage={activePage}
|
||||||
|
itemsCountPerPage={itemsPerPage}
|
||||||
|
totalItemsCount={totalItems}
|
||||||
|
pageRangeDisplayed={5}
|
||||||
|
onChange={handlePageChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
|
@ -13,7 +13,8 @@ import { useLocation } from 'react-router-dom';
|
||||||
const initialDataPost = {
|
const initialDataPost = {
|
||||||
index: 1,
|
index: 1,
|
||||||
item_per_page: 5,
|
item_per_page: 5,
|
||||||
search_data: ""
|
search_data: "",
|
||||||
|
person_type: 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ListItem() {
|
export default function ListItem() {
|
||||||
|
|
406
app/src/components/Modal/ModaEditLabel.js
Normal file
406
app/src/components/Modal/ModaEditLabel.js
Normal file
|
@ -0,0 +1,406 @@
|
||||||
|
import { UploadOutlined, UserOutlined } from '@ant-design/icons';
|
||||||
|
import { Avatar, Button as ButtonAntd, DatePicker, Form, Input, Radio, Upload } from 'antd';
|
||||||
|
import { useLocation } from 'react-router-dom';
|
||||||
|
import viVN from 'antd/lib/locale/vi_VN';
|
||||||
|
import axios from 'axios';
|
||||||
|
import moment from 'moment';
|
||||||
|
import 'moment/locale/vi';
|
||||||
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
|
import { Button, Modal } from 'react-bootstrap';
|
||||||
|
import swal from 'sweetalert';
|
||||||
|
import { HOST } from '../../config/index';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const ModalEditLabel = (props) => {
|
||||||
|
const { show, onHide, data } = props;
|
||||||
|
const [crrImages, setCrrImages] = useState([]);
|
||||||
|
|
||||||
|
const [form] = Form.useForm()
|
||||||
|
|
||||||
|
|
||||||
|
const [birthday, setBirthday] = useState(moment())
|
||||||
|
const [crrData, setCrrData] = useState(null);
|
||||||
|
|
||||||
|
const [checkDeleteMulti, setCheckDeleteMulti] = useState(false);
|
||||||
|
const [crrIdx, setCrrIdx] = useState(0)
|
||||||
|
const [listChecked, setListChecked] = useState({ url: [] });
|
||||||
|
|
||||||
|
const [disableBtn, setDisableBtn] = useState(true);
|
||||||
|
|
||||||
|
const [dateImage, setDateImg] = useState("")
|
||||||
|
|
||||||
|
const [hostImg, setHostImg] = useState('');
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setCrrData(data);
|
||||||
|
setCrrImages(data.sample_images)
|
||||||
|
setBirthday(data.birthday !== "" ? moment(data.birthday) : null)
|
||||||
|
setDisableBtn(data._id ? false : true)
|
||||||
|
setHostImg(data.image_host)
|
||||||
|
return () => {
|
||||||
|
setCrrData(null);
|
||||||
|
}
|
||||||
|
}, [data]);
|
||||||
|
|
||||||
|
|
||||||
|
const handleCheckedImg = (event, value) => {
|
||||||
|
let newListChecked = { ...listChecked }
|
||||||
|
if (newListChecked.url.indexOf(event.target.value) === -1) {
|
||||||
|
newListChecked.url.push(event.target.value)
|
||||||
|
} else {
|
||||||
|
var i = newListChecked.url.indexOf(event.target.value);
|
||||||
|
if (i !== -1) {
|
||||||
|
newListChecked.url.splice(i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setListChecked(newListChecked)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (crrImages.length > 0) {
|
||||||
|
let crrDateImg = crrImages[crrIdx]
|
||||||
|
let getDateImg = crrDateImg !== "" && crrDateImg.split("_")
|
||||||
|
let dataImg = getDateImg.length > 0 && getDateImg[1].slice(0,6)
|
||||||
|
setDateImg(dataImg)
|
||||||
|
}
|
||||||
|
},[crrImages,crrIdx])
|
||||||
|
|
||||||
|
const click_handle = async () => {
|
||||||
|
let dataPost = {
|
||||||
|
obj_id: crrData._id ? crrData._id : "",
|
||||||
|
name: crrData.name,
|
||||||
|
birthday: crrData.birthday,
|
||||||
|
gender: crrData.gender ? crrData.gender : "",
|
||||||
|
id: crrData.id ? crrData.id : "",
|
||||||
|
person_type: 4
|
||||||
|
}
|
||||||
|
const result = await axios({
|
||||||
|
method: 'POST',
|
||||||
|
url: `${HOST}/api/famous_persons/insert_or_update`,
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
// 'Authorization': token,
|
||||||
|
},
|
||||||
|
data: dataPost,
|
||||||
|
})
|
||||||
|
if (result.data.status === 10000) {
|
||||||
|
if (crrData._id) {
|
||||||
|
swal({
|
||||||
|
icon: 'success',
|
||||||
|
title: 'Thành công',
|
||||||
|
text: 'Sửa thông tin thành công',
|
||||||
|
timer: 1500,
|
||||||
|
buttons: false,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
swal({
|
||||||
|
icon: 'success',
|
||||||
|
title: 'Thành công',
|
||||||
|
text: 'Thêm mới thành công',
|
||||||
|
timer: 1500,
|
||||||
|
buttons: false,
|
||||||
|
})
|
||||||
|
setCrrData({...crrData, _id: result.data.data})
|
||||||
|
setDisableBtn(false)
|
||||||
|
}
|
||||||
|
} else if (result.data.status === 10002) {
|
||||||
|
swal("Thất bại", "Lỗi hệ thống!", "error");
|
||||||
|
} else {
|
||||||
|
swal("Thất bại", "Sửa thông tin thất bại!", "error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const bulletedImg = crrImages.map((value, index) => {
|
||||||
|
let getDateImg = value.split("_")
|
||||||
|
let dataImg = getDateImg.length > 0 && getDateImg[1].slice(0,6)
|
||||||
|
|
||||||
|
let renderImg = value.includes("data:image") ? value : hostImg +dataImg+ "/" + value
|
||||||
|
return (
|
||||||
|
<div className="img-res col-md-4 pl-0 mb-3" key={index + 1}>
|
||||||
|
<div style={{ 'height': 80 }}>
|
||||||
|
{
|
||||||
|
checkDeleteMulti === false ?
|
||||||
|
<img alt="" src={renderImg} onClick={() => { setCrrIdx(index) }} className={"opacity_img_click img_check " + (crrIdx === index ? 'active' : '')} />
|
||||||
|
:
|
||||||
|
<label className="m-checkbox img-checkbox m-checkbox-day pl-0 mb-0" style={{ 'width': '100%' }}>
|
||||||
|
<input type="checkbox"
|
||||||
|
defaultValue={value}
|
||||||
|
name="img_checked"
|
||||||
|
checked={listChecked.url.indexOf(value) === -1 ? false : true}
|
||||||
|
onClick={e => {
|
||||||
|
handleCheckedImg(e, value)
|
||||||
|
}} readOnly />
|
||||||
|
<img alt="" src={renderImg} className="opacity_img img_check" />
|
||||||
|
<span />
|
||||||
|
</label>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const uploadImage = async (options) => {
|
||||||
|
if (crrImages.length >= 3) {
|
||||||
|
swal("Cảnh báo", "Bạn chỉ được tải lên tối đa 3 ảnh!", "warning");
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
const { file } = options;
|
||||||
|
const base64 = await convertBase64(file)
|
||||||
|
|
||||||
|
let dataUploadImg = {
|
||||||
|
obj_id: crrData._id ? crrData._id : "",
|
||||||
|
base64_image_list: [base64.split(',')[1]]
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch(`${HOST}/api/face_images/famous_person`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
// 'Authorization': token
|
||||||
|
},
|
||||||
|
body: JSON.stringify(dataUploadImg)
|
||||||
|
})
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.status === 10000) {
|
||||||
|
setHostImg(data.image_host)
|
||||||
|
let listImg = [...crrImages]
|
||||||
|
listImg.unshift(data.data.toString())
|
||||||
|
setCrrImages(listImg)
|
||||||
|
setCheckDeleteMulti(false)
|
||||||
|
} else if (data.status === 10003) {
|
||||||
|
if (data.message === "Too many face in image") {
|
||||||
|
swal("Thất bại", "Ảnh có nhiều khuôn mặt!", "error");
|
||||||
|
} else {
|
||||||
|
swal("Thất bại", "Ảnh không hợp lệ", "error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const convertBase64 = (file) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const fileReader = new FileReader();
|
||||||
|
fileReader.readAsDataURL(file)
|
||||||
|
fileReader.onload = () => {
|
||||||
|
resolve(fileReader.result);
|
||||||
|
}
|
||||||
|
fileReader.onerror = (error) => {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const deleteFaceMulti = () => {
|
||||||
|
let listDelImg = listChecked.url
|
||||||
|
fetch(`${HOST}/api/face_images/ignore_face`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
// 'Authorization': token
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
person_obj_id: crrData._id ? crrData._id : "",
|
||||||
|
images: listDelImg
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.status === 10000) {
|
||||||
|
let listDetele = crrImages.filter(item => !listDelImg.includes(item));
|
||||||
|
if (crrIdx >= 1) {
|
||||||
|
setCrrIdx(crrIdx - 1)
|
||||||
|
}
|
||||||
|
setCrrImages(listDetele)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const UserHandle = (e) => {
|
||||||
|
setCrrData({ ...crrData, [e.target.name]: e.target.value })
|
||||||
|
}
|
||||||
|
|
||||||
|
const onChangeBirthday = (date) => {
|
||||||
|
setBirthday(date)
|
||||||
|
setCrrData({ ...crrData, birthday: moment(date).format("YYYY-MM-DD") })
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!crrData) return <></>;
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
{...props}
|
||||||
|
animation={false}
|
||||||
|
size="lg"
|
||||||
|
// keyboard={false}
|
||||||
|
dialogClassName={`${window.innerWidth >= 1920 ? "modal-size-res" : "modal-size"}`}
|
||||||
|
aria-labelledby="contained-modal-title-vcenter"
|
||||||
|
>
|
||||||
|
<Modal.Header closeButton>
|
||||||
|
<Modal.Title id="contained-modal-title-vcenter">{crrData._id ? "Sửa thông tin" : "Thêm mới"}
|
||||||
|
</Modal.Title>
|
||||||
|
</Modal.Header>
|
||||||
|
{crrData &&
|
||||||
|
<Modal.Body>
|
||||||
|
<div id="formUpdateMeeting">
|
||||||
|
<div className="m-widget14 p-0">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-7 boder-right d-flex flex-column justify-content-between ">
|
||||||
|
<div className="row justify-content-center pb-3">
|
||||||
|
{
|
||||||
|
crrImages[crrIdx] ?
|
||||||
|
<Avatar shape="square" src={crrImages[crrIdx].includes("data:image") ? crrImages[crrIdx] : hostImg +dateImage+"/"+ crrImages[crrIdx]} size={180} icon={<UserOutlined />} /> :
|
||||||
|
<Avatar shape="square" size={180} icon={<UserOutlined />} />
|
||||||
|
}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div className="row mr-4 ml-4">
|
||||||
|
{
|
||||||
|
crrImages.length > 0
|
||||||
|
?
|
||||||
|
<div className="col-md-12 mt-2 mb-2 p-0">
|
||||||
|
<label className="m-checkbox m-checkbox--success mt-3 ml-1">
|
||||||
|
<input type="checkbox"
|
||||||
|
onClick={(e) => {
|
||||||
|
setCheckDeleteMulti(!checkDeleteMulti)
|
||||||
|
setListChecked({
|
||||||
|
url: [],
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
checked={checkDeleteMulti} /> <div style={{ 'paddingTop': '2px' }}>Chọn</div>
|
||||||
|
<span />
|
||||||
|
</label>
|
||||||
|
{
|
||||||
|
checkDeleteMulti === true
|
||||||
|
?
|
||||||
|
<div style={{ 'display': 'inline-flex' }} className="pull-right">
|
||||||
|
<button
|
||||||
|
onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
if (listChecked.url.length > 0) {
|
||||||
|
swal({
|
||||||
|
title: "Bạn chắc chắn muốn xóa ảnh này",
|
||||||
|
icon: "warning",
|
||||||
|
buttons: ["Huỷ", "Oke!"],
|
||||||
|
dangerMode: false,
|
||||||
|
})
|
||||||
|
.then((willDelete) => {
|
||||||
|
if (!willDelete) throw null;
|
||||||
|
deleteFaceMulti();
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
swal("Cảnh báo!", "Bạn chưa chọn ảnh để xóa", "warning");
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
className="btn btn-sm btn-danger width-mobie--100 m-loader--light m-loader--right" id="btn_deleteMulti">
|
||||||
|
Xóa ảnh đã chọn
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
:
|
||||||
|
""
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
:
|
||||||
|
""
|
||||||
|
}
|
||||||
|
<div className="row col-md-12 pr-0 image_capture_small pull-left">
|
||||||
|
{
|
||||||
|
bulletedImg
|
||||||
|
}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<Upload
|
||||||
|
customRequest = {uploadImage}
|
||||||
|
accept="image/*"
|
||||||
|
showUploadList={false}
|
||||||
|
disabled={disableBtn}
|
||||||
|
>
|
||||||
|
<ButtonAntd className={`${disableBtn ? "disable-btn-upload" : ""}`} icon={<UploadOutlined />}>Tải ảnh lên</ButtonAntd>
|
||||||
|
</Upload>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-5 d-flex flex-column justify-content-between">
|
||||||
|
<Form
|
||||||
|
id="formEdit"
|
||||||
|
form={form}
|
||||||
|
layout="vertical"
|
||||||
|
onFinish={() => click_handle()}
|
||||||
|
// onFinishFailed={onFinishFailed}
|
||||||
|
autoComplete="off"
|
||||||
|
initialValues={{
|
||||||
|
name: crrData.name,
|
||||||
|
id: crrData.id,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Form.Item
|
||||||
|
label="Họ tên"
|
||||||
|
name="name"
|
||||||
|
rules={[{ required: true, message: '' }]}
|
||||||
|
>
|
||||||
|
<Input placeholder="Họ tên" value={crrData.name} onChange={e => UserHandle(e)} name='name' />
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item
|
||||||
|
label="FacebookID"
|
||||||
|
name="id"
|
||||||
|
>
|
||||||
|
<Input placeholder="FacebookID" value={crrData.id} onChange={e => UserHandle(e)} name='id' />
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item name="radio-group" label="Giới tính">
|
||||||
|
<Radio.Group name="gender" onChange={e => UserHandle(e)} defaultValue={crrData.gender}>
|
||||||
|
<Radio name="gender" value={"1"}>Nam</Radio>
|
||||||
|
<Radio name="gender" value={"2"}>Nữ</Radio>
|
||||||
|
<Radio name="gender" value={"3"}>Giới tính khác</Radio>
|
||||||
|
</Radio.Group>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label="Ngày sinh"
|
||||||
|
name="birthday"
|
||||||
|
>
|
||||||
|
<DatePicker className="form-control m-input"
|
||||||
|
locale={viVN}
|
||||||
|
defaultValue={birthday !== null ? moment(birthday, 'DD-MM-YYYY') : null}
|
||||||
|
format={'DD-MM-YYYY'}
|
||||||
|
onChange={e => onChangeBirthday(e)}
|
||||||
|
placeholder="Ngày sinh"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
</Form>
|
||||||
|
<div className="row d-flex justify-content-end mr-1">
|
||||||
|
<Button variant="accent" className={"m-loader--light m-loader--right "}
|
||||||
|
// disabled={loading}
|
||||||
|
onClick={() => form.submit()}
|
||||||
|
>Lưu</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Modal.Body>
|
||||||
|
}
|
||||||
|
{/* <Modal.Footer>
|
||||||
|
<Button variant="accent" className={"m-loader--light m-loader--right "}
|
||||||
|
// disabled={loading}
|
||||||
|
onClick={() => form.submit()}
|
||||||
|
>Lưu</Button>
|
||||||
|
<Button variant="secondary" onClick={onHide}>Đóng</Button>
|
||||||
|
</Modal.Footer> */}
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ModalEditLabel;
|
|
@ -73,7 +73,8 @@ const Modaledit = (props) => {
|
||||||
id: crrData.id,
|
id: crrData.id,
|
||||||
name: crrData.name,
|
name: crrData.name,
|
||||||
birthday: crrData.birthday,
|
birthday: crrData.birthday,
|
||||||
gender: crrData.gender ? crrData.gender : ""
|
gender: crrData.gender ? crrData.gender : "",
|
||||||
|
person_type: 2
|
||||||
}
|
}
|
||||||
const result = await axios({
|
const result = await axios({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|
|
@ -84,7 +84,7 @@ class ModalEditImg extends Component {
|
||||||
<div className="col-md-6 boder-right d-flex flex-column justify-content-between ">
|
<div className="col-md-6 boder-right d-flex flex-column justify-content-between ">
|
||||||
<div className="d-flex justify-content-center">
|
<div className="d-flex justify-content-center">
|
||||||
<Image
|
<Image
|
||||||
width={240}
|
style={{ width: "350px", height: "auto", objectFit: "contain"}}
|
||||||
src={this.state.valueImg.image_host}
|
src={this.state.valueImg.image_host}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
44
app/src/components/Test/Test.js
Normal file
44
app/src/components/Test/Test.js
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
import { UserOutlined } from '@ant-design/icons';
|
||||||
|
import { Avatar, Tooltip } from 'antd';
|
||||||
|
import axios from 'axios';
|
||||||
|
import ModalEditLabel from '../Modal/ModaEditLabel';
|
||||||
|
import momment from 'moment';
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import Pagination from "react-js-pagination";
|
||||||
|
import { PulseLoader } from 'react-spinners';
|
||||||
|
import { HOST } from '../../config/index';
|
||||||
|
import swal from 'sweetalert';
|
||||||
|
import { useLocation } from 'react-router-dom';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default function Test() {
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className="m-portlet m-portlet--mobile pb-3">
|
||||||
|
<div className="m-portlet__head">
|
||||||
|
<div className="m-portlet__head-caption">
|
||||||
|
<div className="m-portlet__head-title">
|
||||||
|
<h3 className="m-portlet__head-text">
|
||||||
|
Test
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="m-portlet__body pt-2">
|
||||||
|
<PulseLoader
|
||||||
|
// css={override}
|
||||||
|
sizeUnit={"px"}
|
||||||
|
size={12}
|
||||||
|
margin={'2px'}
|
||||||
|
color={'#36D7B7'}
|
||||||
|
// loading={loading}
|
||||||
|
/>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
|
@ -67,7 +67,27 @@ class MenuBar extends Component {
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<li className="m-menu__item m-menu__item--submenu" aria-haspopup="true" m-menu-submenu-toggle="hover">
|
||||||
|
<NavLink to="/label-image" className={"m-menu__link " + active} activeClassName="m-menu__item--active" onClick={() => this.onClickClose()}>
|
||||||
|
<i className="m-menu__link-icon flaticon-delete" />
|
||||||
|
<span className="m-menu__link-title">
|
||||||
|
<span className="m-menu__link-wrap">
|
||||||
|
<span className="m-menu__link-text">Gán nhãn</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</NavLink>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li className="m-menu__item m-menu__item--submenu" aria-haspopup="true" m-menu-submenu-toggle="hover">
|
||||||
|
<NavLink to="/test" className={"m-menu__link " + active} activeClassName="m-menu__item--active" onClick={() => this.onClickClose()}>
|
||||||
|
<i className="m-menu__link-icon flaticon-edit" />
|
||||||
|
<span className="m-menu__link-title">
|
||||||
|
<span className="m-menu__link-wrap">
|
||||||
|
<span className="m-menu__link-text">Test</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</NavLink>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{/* END: Aside Menu */}
|
{/* END: Aside Menu */}
|
||||||
|
|
|
@ -1049,7 +1049,7 @@
|
||||||
core-js-pure "^3.20.2"
|
core-js-pure "^3.20.2"
|
||||||
regenerator-runtime "^0.13.4"
|
regenerator-runtime "^0.13.4"
|
||||||
|
|
||||||
"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.16.3", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
|
"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.16.3", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
|
||||||
version "7.16.7"
|
version "7.16.7"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.7.tgz#03ff99f64106588c9c403c6ecb8c3bafbbdff1fa"
|
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.7.tgz#03ff99f64106588c9c403c6ecb8c3bafbbdff1fa"
|
||||||
integrity sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ==
|
integrity sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ==
|
||||||
|
@ -1114,7 +1114,7 @@
|
||||||
"@emotion/utils" "0.11.3"
|
"@emotion/utils" "0.11.3"
|
||||||
"@emotion/weak-memoize" "0.2.5"
|
"@emotion/weak-memoize" "0.2.5"
|
||||||
|
|
||||||
"@emotion/cache@^11.7.1":
|
"@emotion/cache@^11.4.0", "@emotion/cache@^11.7.1":
|
||||||
version "11.7.1"
|
version "11.7.1"
|
||||||
resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.7.1.tgz#08d080e396a42e0037848214e8aa7bf879065539"
|
resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.7.1.tgz#08d080e396a42e0037848214e8aa7bf879065539"
|
||||||
integrity sha512-r65Zy4Iljb8oyjtLeCuBH8Qjiy107dOYC6SJq7g7GV5UCQWMObY4SJDPGFjiiVpPrOJ2hmJOoBiYTC7hwx9E2A==
|
integrity sha512-r65Zy4Iljb8oyjtLeCuBH8Qjiy107dOYC6SJq7g7GV5UCQWMObY4SJDPGFjiiVpPrOJ2hmJOoBiYTC7hwx9E2A==
|
||||||
|
@ -1140,7 +1140,7 @@
|
||||||
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.5.tgz#2c40f81449a4e554e9fc6396910ed4843ec2be50"
|
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.5.tgz#2c40f81449a4e554e9fc6396910ed4843ec2be50"
|
||||||
integrity sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ==
|
integrity sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ==
|
||||||
|
|
||||||
"@emotion/react@^11.1.4":
|
"@emotion/react@^11.1.1", "@emotion/react@^11.1.4":
|
||||||
version "11.7.1"
|
version "11.7.1"
|
||||||
resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.7.1.tgz#3f800ce9b20317c13e77b8489ac4a0b922b2fe07"
|
resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.7.1.tgz#3f800ce9b20317c13e77b8489ac4a0b922b2fe07"
|
||||||
integrity sha512-DV2Xe3yhkF1yT4uAUoJcYL1AmrnO5SVsdfvu+fBuS7IbByDeTVx9+wFmvx9Idzv7/78+9Mgx2Hcmr7Fex3tIyw==
|
integrity sha512-DV2Xe3yhkF1yT4uAUoJcYL1AmrnO5SVsdfvu+fBuS7IbByDeTVx9+wFmvx9Idzv7/78+9Mgx2Hcmr7Fex3tIyw==
|
||||||
|
@ -1948,7 +1948,14 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc"
|
resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc"
|
||||||
integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==
|
integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==
|
||||||
|
|
||||||
"@types/react@>=16.9.11":
|
"@types/react-transition-group@^4.4.0":
|
||||||
|
version "4.4.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.4.tgz#acd4cceaa2be6b757db61ed7b432e103242d163e"
|
||||||
|
integrity sha512-7gAPz7anVK5xzbeQW9wFBDg7G++aPLAFY0QaSMOou9rJZpbuI58WAuJrgu+qR92l61grlnCUe7AFX8KGahAgug==
|
||||||
|
dependencies:
|
||||||
|
"@types/react" "*"
|
||||||
|
|
||||||
|
"@types/react@*", "@types/react@>=16.9.11":
|
||||||
version "17.0.38"
|
version "17.0.38"
|
||||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.38.tgz#f24249fefd89357d5fa71f739a686b8d7c7202bd"
|
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.38.tgz#f24249fefd89357d5fa71f739a686b8d7c7202bd"
|
||||||
integrity sha512-SI92X1IA+FMnP3qM5m4QReluXzhcmovhZnLNm3pyeQlooi02qI7sLiepEYqT678uNiyc25XfCqxREFpy3W7YhQ==
|
integrity sha512-SI92X1IA+FMnP3qM5m4QReluXzhcmovhZnLNm3pyeQlooi02qI7sLiepEYqT678uNiyc25XfCqxREFpy3W7YhQ==
|
||||||
|
@ -6597,6 +6604,11 @@ memfs@^3.1.2, memfs@^3.2.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
fs-monkey "1.0.3"
|
fs-monkey "1.0.3"
|
||||||
|
|
||||||
|
memoize-one@^5.0.0:
|
||||||
|
version "5.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e"
|
||||||
|
integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==
|
||||||
|
|
||||||
memoize-one@^6.0.0:
|
memoize-one@^6.0.0:
|
||||||
version "6.0.0"
|
version "6.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-6.0.0.tgz#b2591b871ed82948aee4727dc6abceeeac8c1045"
|
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-6.0.0.tgz#b2591b871ed82948aee4727dc6abceeeac8c1045"
|
||||||
|
@ -7944,7 +7956,7 @@ prop-types-extra@^1.1.0:
|
||||||
react-is "^16.3.2"
|
react-is "^16.3.2"
|
||||||
warning "^4.0.0"
|
warning "^4.0.0"
|
||||||
|
|
||||||
"prop-types@15.x.x - 16.x.x", prop-types@^15.5.0, prop-types@^15.6.2, prop-types@^15.7.2:
|
"prop-types@15.x.x - 16.x.x", prop-types@^15.5.0, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2:
|
||||||
version "15.8.1"
|
version "15.8.1"
|
||||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
|
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
|
||||||
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
|
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
|
||||||
|
@ -8643,6 +8655,19 @@ react-scripts@5.0.0:
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents "^2.3.2"
|
fsevents "^2.3.2"
|
||||||
|
|
||||||
|
react-select@^5.2.1:
|
||||||
|
version "5.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-select/-/react-select-5.2.1.tgz#416c25c6b79b94687702374e019c4f2ed9d159d6"
|
||||||
|
integrity sha512-OOyNzfKrhOcw/BlembyGWgdlJ2ObZRaqmQppPFut1RptJO423j+Y+JIsmxkvsZ4D/3CpOmwIlCvWbbAWEdh12A==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.12.0"
|
||||||
|
"@emotion/cache" "^11.4.0"
|
||||||
|
"@emotion/react" "^11.1.1"
|
||||||
|
"@types/react-transition-group" "^4.4.0"
|
||||||
|
memoize-one "^5.0.0"
|
||||||
|
prop-types "^15.6.0"
|
||||||
|
react-transition-group "^4.3.0"
|
||||||
|
|
||||||
react-spinners@^0.11.0:
|
react-spinners@^0.11.0:
|
||||||
version "0.11.0"
|
version "0.11.0"
|
||||||
resolved "https://registry.yarnpkg.com/react-spinners/-/react-spinners-0.11.0.tgz#186fd150cc9f7ab1436227f70d5d113b47e9e43d"
|
resolved "https://registry.yarnpkg.com/react-spinners/-/react-spinners-0.11.0.tgz#186fd150cc9f7ab1436227f70d5d113b47e9e43d"
|
||||||
|
@ -8660,7 +8685,7 @@ react-transition-group@^2.5.0:
|
||||||
prop-types "^15.6.2"
|
prop-types "^15.6.2"
|
||||||
react-lifecycles-compat "^3.0.4"
|
react-lifecycles-compat "^3.0.4"
|
||||||
|
|
||||||
react-transition-group@^4.0.0:
|
react-transition-group@^4.0.0, react-transition-group@^4.3.0:
|
||||||
version "4.4.2"
|
version "4.4.2"
|
||||||
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.2.tgz#8b59a56f09ced7b55cbd53c36768b922890d5470"
|
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.2.tgz#8b59a56f09ced7b55cbd53c36768b922890d5470"
|
||||||
integrity sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==
|
integrity sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==
|
||||||
|
|
Loading…
Reference in New Issue
Block a user