them tinh nang impor anh va menu
This commit is contained in:
@@ -340,3 +340,29 @@ button.close:hover {
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* //dropzone */
|
||||
.dropzone {
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
border: 3px dashed #eeeeee;
|
||||
background-color: #fafafa;
|
||||
color: #bdbdbd;
|
||||
cursor: pointer;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.accept {
|
||||
border-color: #107c10 !important;
|
||||
}
|
||||
|
||||
.reject {
|
||||
border-color: #58b4ff !important;
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.m-header {
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,22 +2,33 @@ import React from 'react'
|
||||
import ListItem from './components/List/ListItem';
|
||||
import Login from './components/Login/Login';
|
||||
import SearchImage from './components/SearchImg/SearchImage';
|
||||
import 'antd/dist/antd.css';
|
||||
import ImportImage from './components/ImportImg/ImportImage';
|
||||
import MenuBar from './components/layouts/MenuBar'
|
||||
import Header from './components/layouts/Header'
|
||||
import 'antd/dist/antd.css';
|
||||
import "./App.css";
|
||||
import { BrowserRouter as Router, Navigate, Route, Routes } from 'react-router-dom';
|
||||
import { BrowserRouter as Router, Redirect, Route, Switch } from 'react-router-dom';
|
||||
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div className="Container">
|
||||
<Router>
|
||||
<Routes>
|
||||
<Route path="/" element={<Navigate replace to="/list-famous" />} />
|
||||
<Route path='/login' element={<Login />} />
|
||||
<Route path='/search-image' element={<SearchImage />} />
|
||||
<Route path="/list-famous" element={<ListItem />} />
|
||||
</Routes>
|
||||
</Router>
|
||||
<div>
|
||||
<Router>
|
||||
<Switch>
|
||||
<div className="m-grid m-grid--hor m-grid--root m-page">
|
||||
<Header />
|
||||
<MenuBar />
|
||||
<div>
|
||||
{/* <Redirect exact from='/' to='/search-image' /> */}
|
||||
<Route path='/login' component={Login} />
|
||||
<Route path='/import-image' component={ImportImage} />
|
||||
<Route path='/search-image' component={SearchImage} />
|
||||
<Route path="/list-famous" component={ListItem} />
|
||||
</div>
|
||||
</div>
|
||||
</Switch>
|
||||
|
||||
</Router>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
330
app/src/components/ImportImg/ImportImage.js
Normal file
330
app/src/components/ImportImg/ImportImage.js
Normal file
@@ -0,0 +1,330 @@
|
||||
import React, { Component } from "react";
|
||||
import { HOST } from '../../config';
|
||||
import swal from 'sweetalert';
|
||||
import { Redirect } from 'react-router-dom';
|
||||
import Pagination from "react-js-pagination";
|
||||
import $ from 'jquery';
|
||||
import { PulseLoader } from 'react-spinners';
|
||||
import Modalupload from '../Modal/ModalUpload';
|
||||
import ModalEditImg from '../Modal/ModalEditImg';
|
||||
import axios from 'axios';
|
||||
import { Avatar, Tooltip } from 'antd';
|
||||
import {UserOutlined} from '@ant-design/icons';
|
||||
import momment from 'moment';
|
||||
class ImportImage extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
listImgImport: [],
|
||||
crrImg: [],
|
||||
activePage: 1,
|
||||
offset: 0,
|
||||
showFirst: 0,
|
||||
showLast: 0,
|
||||
totalLength: 0,
|
||||
loading: true,
|
||||
count: 0,
|
||||
modalShow: false,
|
||||
dataEdit: null,
|
||||
modalUploadShow: false,
|
||||
dataSearch: ""
|
||||
}
|
||||
this.itemsPerPage = 5;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.getListImg(1);
|
||||
}
|
||||
|
||||
|
||||
getListImg = async (page) => {
|
||||
this.setState({ loading: true });
|
||||
try {
|
||||
const result = await axios({
|
||||
method: 'POST',
|
||||
url: `${HOST}/api/face_images/search`,
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
// 'Authorization': token
|
||||
},
|
||||
data: {
|
||||
index: page,
|
||||
item_per_page: this.itemsPerPage,
|
||||
search_data: this.state.dataSearch
|
||||
},
|
||||
})
|
||||
|
||||
if (result.data.status === 10000) {
|
||||
this.setState({
|
||||
listImgImport: result.data.data,
|
||||
totalLength: result.data.count,
|
||||
}, () => {
|
||||
this.FilterItem(this.state.activePage)
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
this.setState({
|
||||
})
|
||||
console.log(error);
|
||||
}
|
||||
this.setState({ loading: false });
|
||||
}
|
||||
|
||||
|
||||
|
||||
modalClose = () => {
|
||||
this.setState({
|
||||
modalShow: false,
|
||||
});
|
||||
this.getListImg(this.state.activePage);
|
||||
}
|
||||
|
||||
modalUploadClose = () => {
|
||||
this.setState({
|
||||
modalUploadShow: false,
|
||||
});
|
||||
this.getListImg(this.state.activePage);
|
||||
}
|
||||
|
||||
FilterItem = (activePage) => {
|
||||
const offset = (activePage - 1) * this.itemsPerPage;
|
||||
this.setState({
|
||||
offset: offset
|
||||
})
|
||||
}
|
||||
|
||||
onClickEdit = (value) => {
|
||||
this.setState({
|
||||
modalShow: true,
|
||||
dataEdit: value
|
||||
})
|
||||
}
|
||||
|
||||
handlePageChange = (pageNumber) => {
|
||||
this.setState({
|
||||
activePage: pageNumber
|
||||
}, () => {
|
||||
this.getListImg(pageNumber);
|
||||
})
|
||||
}
|
||||
|
||||
onDelete = async (img) => {
|
||||
let data = await fetch(`${HOST}/api/face_images/delete`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
// 'Authorization': token
|
||||
},
|
||||
body: JSON.stringify({ 'image_obj_id_list': [img._id] })
|
||||
}).then((response) => {
|
||||
return response.json()
|
||||
});
|
||||
|
||||
if (data.status === 10000) {
|
||||
var { activePage } = this.state
|
||||
if (this.state.listImgImport.length === 1) {
|
||||
activePage = activePage - 1
|
||||
}
|
||||
this.setState({
|
||||
activePage: activePage
|
||||
})
|
||||
swal("Thành công", "Xoá ảnh thành công", "success")
|
||||
this.getListImg(this.state.activePage);
|
||||
}
|
||||
else {
|
||||
swal("Thất bại", "Xoá ảnh thất bại", "error");
|
||||
}
|
||||
}
|
||||
|
||||
handleOnKeyDown = e => {
|
||||
if (e.key === 'Enter') {
|
||||
this.getListImg(1)
|
||||
}
|
||||
}
|
||||
|
||||
reset = () => {
|
||||
this.setState({
|
||||
activePage: 1,
|
||||
dataSearch: "",
|
||||
}, () => {
|
||||
this.getListImg(1);
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
// if (this.state.isLogin == false) {
|
||||
// return (
|
||||
// <Redirect to={'/login'} />
|
||||
// )
|
||||
// }
|
||||
let bulletedListImg = this.state.listImgImport.map((value, index) => {
|
||||
|
||||
var listImg
|
||||
listImg = <img key={index} style={{ width: "80px", height: "80px" }} alt="" src={`${value.image_host}`} />
|
||||
|
||||
|
||||
return (
|
||||
<tr key={index}>
|
||||
<td>{(index + this.state.offset + 1)}</td>
|
||||
<td>{listImg}</td>
|
||||
<td>{value.origin_name}</td>
|
||||
<td>{momment(value.created_time).format("DD-MM-YYYY")}</td>
|
||||
<td>
|
||||
<Tooltip placement="top" title={"Sửa"}>
|
||||
<button
|
||||
onClick={() => this.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á ảnh này",
|
||||
icon: "warning",
|
||||
buttons: ["Huỷ", "Xoá"],
|
||||
dangerMode: true,
|
||||
})
|
||||
.then(willDelete => {
|
||||
if (willDelete) {
|
||||
this.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>
|
||||
)
|
||||
});
|
||||
|
||||
return (
|
||||
<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">
|
||||
Kho ảnh
|
||||
</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) => this.handleOnKeyDown(e)}
|
||||
onChange={(e) => {
|
||||
this.setState({
|
||||
dataSearch: e.target.value
|
||||
})
|
||||
}}
|
||||
value={this.state.dataSearch}
|
||||
id="inputSearch" className="form-control m-input"
|
||||
placeholder="Tên ảnh..."
|
||||
data-col-index={0}
|
||||
/>
|
||||
</div>
|
||||
<div className="pl-3">
|
||||
<button
|
||||
onClick={() => {
|
||||
this.getListImg(1);
|
||||
this.setState({
|
||||
activePage: 1
|
||||
})
|
||||
}}
|
||||
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={() => {
|
||||
this.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) => {
|
||||
this.setState({
|
||||
modalUploadShow: 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>Tải ảnh lên</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 style={{width: "50px"}}>STT</th>
|
||||
<th>Ảnh</th>
|
||||
<th>Tên ảnh</th>
|
||||
<th>Ngày tải lên</th>
|
||||
<th>Thao tác</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>{bulletedListImg}</tbody>
|
||||
</table>
|
||||
<Modalupload
|
||||
show={this.state.modalUploadShow}
|
||||
onHide={this.modalUploadClose}
|
||||
/>
|
||||
<ModalEditImg
|
||||
show={this.state.modalShow}
|
||||
onHide={this.modalClose}
|
||||
data={this.state.dataEdit}
|
||||
/>
|
||||
<PulseLoader
|
||||
// css={override}
|
||||
sizeUnit={"px"}
|
||||
size={12}
|
||||
margin={'2px'}
|
||||
color={'#36D7B7'}
|
||||
loading={this.state.loading}
|
||||
/>
|
||||
<Pagination
|
||||
prevPageText='Trang trước'
|
||||
nextPageText='Trang sau'
|
||||
firstPageText='Trang đầu'
|
||||
lastPageText='Trang cuối'
|
||||
activePage={this.state.activePage}
|
||||
itemsCountPerPage={this.itemsPerPage}
|
||||
totalItemsCount={this.state.totalLength}
|
||||
pageRangeDisplayed={5}
|
||||
onChange={this.handlePageChange}
|
||||
/>
|
||||
<div>Tổng kết quả <strong>{this.state.totalLength}</strong></div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default ImportImage;
|
||||
@@ -58,15 +58,11 @@ const Modaledit = (props) => {
|
||||
|
||||
const click_handle = async () => {
|
||||
let dataPost = {
|
||||
obj_id: crrData._id ? crrData._id : "",
|
||||
id: crrData.id,
|
||||
name: crrData.name,
|
||||
birthday: crrData.birthday,
|
||||
gender: crrData.gender ? crrData.gender : ""
|
||||
origin_name : crrData.name,
|
||||
}
|
||||
const result = await axios({
|
||||
method: 'POST',
|
||||
url: `${HOST}/api/famous_persons/insert_or_update`,
|
||||
url: `${HOST}/api/face_images/insert_or_update`,
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
|
||||
146
app/src/components/Modal/ModalEditImg.js
Normal file
146
app/src/components/Modal/ModalEditImg.js
Normal file
@@ -0,0 +1,146 @@
|
||||
import { Form, Image, Input } from 'antd';
|
||||
import moment from 'moment';
|
||||
import 'moment/locale/vi';
|
||||
import React, { Component } from 'react';
|
||||
import { Button, Modal } from 'react-bootstrap';
|
||||
import swal from 'sweetalert';
|
||||
import { HOST } from '../../config/index';
|
||||
|
||||
class ModalEditImg extends Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
valueImg: {},
|
||||
show: this.props.show
|
||||
}
|
||||
this.refForm = React.createRef();
|
||||
}
|
||||
|
||||
UpdateNameImg = async (event) => {
|
||||
//Insert
|
||||
this.state.valueImg.origin_name = this.state.valueImg.origin_name.trim()
|
||||
let data = await fetch(`${HOST}/api/face_images/insert_or_update`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
// 'Authorization': token
|
||||
},
|
||||
body: JSON.stringify({
|
||||
"origin_name": this.state.valueImg.origin_name,
|
||||
"obj_id": this.state.valueImg._id
|
||||
})
|
||||
}).then((response) => {
|
||||
return (
|
||||
response.json()
|
||||
)
|
||||
});
|
||||
if (data.status === 10000) {
|
||||
swal("Thành công!", "Cập nhật ảnh thành công!", "success", {
|
||||
buttons: false,
|
||||
timer: 1500,
|
||||
});
|
||||
return this.props.onHide();
|
||||
}
|
||||
else {
|
||||
swal("Lỗi!", "Cập nhật ảnh thất bại", "error");
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.show === true) {
|
||||
this.setState({ valueImg: nextProps.data });
|
||||
}
|
||||
}
|
||||
|
||||
nameHandle = (e) => {
|
||||
var nameImg = this.state.valueImg;
|
||||
nameImg[e.target.name] = e.target.value;
|
||||
this.setState({
|
||||
valueImg: nameImg
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
return (
|
||||
<Modal
|
||||
{...this.props}
|
||||
animation={false}
|
||||
size="md"
|
||||
// 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">Sửa thông tin ảnh
|
||||
</Modal.Title>
|
||||
</Modal.Header>
|
||||
<Modal.Body>
|
||||
<div id="formUpdateMeeting">
|
||||
<div className="m-widget14 p-0">
|
||||
<div className="row">
|
||||
<div className="col-md-6 boder-right d-flex flex-column justify-content-between ">
|
||||
<div className="d-flex justify-content-center">
|
||||
<Image
|
||||
width={240}
|
||||
src={this.state.valueImg.image_host}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-md-6 d-flex flex-column justify-content-between">
|
||||
<Form
|
||||
id="formEdit"
|
||||
// form={form}
|
||||
ref={this.refForm}
|
||||
layout="vertical"
|
||||
onFinish={() => this.UpdateNameImg()}
|
||||
// onFinishFailed={onFinishFailed}
|
||||
autoComplete="off"
|
||||
initialValues={{
|
||||
origin_name: this.state.valueImg.origin_name
|
||||
}}
|
||||
>
|
||||
|
||||
<Form.Item
|
||||
label="Tên ảnh"
|
||||
rules={[{ required: true, message: '' }]}
|
||||
name='origin_name'
|
||||
>
|
||||
<Input
|
||||
value={this.state.valueImg.origin_name}
|
||||
onChange={e => this.nameHandle(e)}
|
||||
name='origin_name'
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
label="Ngày tải lên"
|
||||
>
|
||||
<Input disabled value={moment(this.state.valueImg.created_time).format("DD-MM-YYYY")}
|
||||
// onChange={e => UserHandle(e)}
|
||||
name='date_create' />
|
||||
</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={() => this.refForm.current.submit()}
|
||||
>Lưu</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Modal.Body>
|
||||
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ModalEditImg;
|
||||
139
app/src/components/Modal/ModalUpload.js
Normal file
139
app/src/components/Modal/ModalUpload.js
Normal file
@@ -0,0 +1,139 @@
|
||||
import { InboxOutlined } from '@ant-design/icons';
|
||||
import { Upload } from 'antd';
|
||||
import axios from 'axios';
|
||||
import 'moment/locale/vi';
|
||||
import React, { useState } from 'react';
|
||||
import { Modal } from 'react-bootstrap';
|
||||
import Dropzone from "react-dropzone";
|
||||
import LoadingOverlay from 'react-loading-overlay';
|
||||
import { PulseLoader } from 'react-spinners';
|
||||
import swal from 'sweetalert';
|
||||
import { HOST } from '../../config/index';
|
||||
|
||||
const { Dragger } = Upload;
|
||||
|
||||
|
||||
const ModalUpload = (props) => {
|
||||
const { show, onHide } = props;
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const handleDrop = async acceptedFiles => {
|
||||
let formData = new FormData()
|
||||
|
||||
const fileObjects = acceptedFiles.map(file => {
|
||||
formData.append('files', file, file.name)
|
||||
})
|
||||
|
||||
setLoading(true)
|
||||
try {
|
||||
let result = await axios
|
||||
.post(`${HOST}/api/files_face_import`, formData, {
|
||||
headers: {
|
||||
"X-Requested-With": "XMLHttpRequest",
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
"Authorization": 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlcyI6WyJjbGFzc2lmeS9sb2dpbiJdLCJleHAiOjE2NDE5NzQ5NjV9.2F2PAUKjpfjPJKzgvzgCDtyBuTXDRl86EnJJGdYgWTM'
|
||||
}
|
||||
})
|
||||
console.log(result)
|
||||
if (result.data.status === 10000) {
|
||||
setLoading(false)
|
||||
swal({
|
||||
text: "Tải ảnh lên thành công",
|
||||
icon: "success",
|
||||
// buttons: ["Thử lại", "Huỷ"],
|
||||
})
|
||||
.then(willTry => {
|
||||
if (willTry) {
|
||||
onHide()
|
||||
}
|
||||
})
|
||||
} else if (result.data.status === 10002) {
|
||||
swal("Thất bại", "Lỗi hệ thống!", "error")
|
||||
} else if (result.data.status === 10003) {
|
||||
swal("Thất bại", "Không có quyền!", "error")
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
swal("Thất bại", "Tải ảnh lên thất bại!", "error")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<Modal
|
||||
{...props}
|
||||
animation={false}
|
||||
size="md"
|
||||
backdrop={loading ? 'static' : true}
|
||||
keyboard={false}
|
||||
dialogClassName={`${window.innerWidth >= 1920 ? "modal-size-res" : "modal-size"}`}
|
||||
aria-labelledby="contained-modal-title-vcenter"
|
||||
>
|
||||
<LoadingOverlay
|
||||
active={loading}
|
||||
spinner={<PulseLoader
|
||||
sizeUnit={"px"}
|
||||
size={12}
|
||||
margin={'2px'}
|
||||
color={'#36D7B7'}
|
||||
loading={true}
|
||||
/>}
|
||||
styles={{
|
||||
overlay: (base) => ({
|
||||
...base,
|
||||
background: 'rgba(0, 0, 0, 0.58)'
|
||||
})
|
||||
}}
|
||||
|
||||
className="col-xl-12 p-0"
|
||||
>
|
||||
<Modal.Header closeButton>
|
||||
<Modal.Title id="contained-modal-title-vcenter">Tải ảnh lên
|
||||
</Modal.Title>
|
||||
</Modal.Header>
|
||||
|
||||
<Modal.Body>
|
||||
<div className="Container-modal">
|
||||
<Dropzone
|
||||
onDrop={handleDrop}
|
||||
accept="image/*"
|
||||
// minSize={1024}
|
||||
// maxSize={300000}
|
||||
>
|
||||
{({
|
||||
getRootProps,
|
||||
getInputProps,
|
||||
isDragActive,
|
||||
isDragAccept,
|
||||
isDragReject
|
||||
}) => {
|
||||
const additionalClass = isDragAccept
|
||||
? "accept"
|
||||
: isDragReject
|
||||
? "reject"
|
||||
: "";
|
||||
|
||||
return (
|
||||
<div
|
||||
{...getRootProps({
|
||||
className: `dropzone ${additionalClass}`
|
||||
})}
|
||||
>
|
||||
<input {...getInputProps()} />
|
||||
<InboxOutlined style={{ fontSize: "50px" }} />
|
||||
<p>Kéo thả thư mục hình ảnh, hoặc chọn ảnh để nhập</p>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
</Dropzone>
|
||||
</div>
|
||||
|
||||
</Modal.Body>
|
||||
</LoadingOverlay>
|
||||
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
export default ModalUpload;
|
||||
@@ -43,11 +43,13 @@ class SearchImage extends Component {
|
||||
this.onchange = this.onchange.bind(this);
|
||||
this.closeModal = this.closeModal.bind(this);
|
||||
|
||||
var itemsPerPage = 1;
|
||||
if ($(window).width() < 768) {
|
||||
var itemsPerPage = 6;
|
||||
if ($(window).width() >= 1400 && $(window).width() < 1750) {
|
||||
itemsPerPage = 6
|
||||
} else if ($(window).width() <= 1280 ) {
|
||||
itemsPerPage = 6
|
||||
} else {
|
||||
itemsPerPage = 6
|
||||
itemsPerPage = 8
|
||||
}
|
||||
this.itemsPerPage = itemsPerPage;
|
||||
|
||||
@@ -382,7 +384,7 @@ class SearchImage extends Component {
|
||||
<Card
|
||||
style={{ width: 300 }}
|
||||
cover={<ImageAntd
|
||||
style={{ objectFit: 'contain', maxHeight: '200px'}}
|
||||
style={{ objectFit: 'contain', height: '180px'}}
|
||||
// width={200}
|
||||
src={value.image_url}
|
||||
/>}
|
||||
|
||||
88
app/src/components/layouts/Header.js
Normal file
88
app/src/components/layouts/Header.js
Normal file
@@ -0,0 +1,88 @@
|
||||
import $ from 'jquery';
|
||||
import React, { Component } from 'react';
|
||||
import { withRouter } from 'react-router';
|
||||
|
||||
class Header extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
onClickOpen = () => {
|
||||
$('#m_aside_left').addClass('m-aside-left--on')
|
||||
$('#body_form').addClass('m-aside-left--on')
|
||||
$('#m_aside_left_toggle').addClass('m-aside-left-toggler--active')
|
||||
$('#root').append(
|
||||
$('<div/>', {
|
||||
'class': 'm-aside-left-overlay',
|
||||
}).on({
|
||||
'click': function () {
|
||||
$('#m_aside_left').removeClass('m-aside-left--on')
|
||||
$('#body_form').removeClass('m-aside-left--on')
|
||||
$('#m_aside_left_toggle').removeClass('m-aside-left-toggler--active')
|
||||
$('.m-aside-left-overlay').remove()
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
return (
|
||||
<header id="m_header" className="m-grid__item m-header" m-minimize="minimize" m-minimize-mobile="minimize" m-minimize-offset={200} m-minimize-mobile-offset={200}>
|
||||
<div className="m-container m-container--fluid m-container--full-height pr-4 pl-4">
|
||||
<div className="m-stack m-stack--ver m-stack--desktop m-header__wrapper">
|
||||
<div className="m-stack__item m-brand m-brand--mobile">
|
||||
<div className="m-stack m-stack--ver m-stack--general">
|
||||
<div className="m-stack__item m-stack__item--middle m-brand__logo">
|
||||
{/* <a href="/dashboard" className="m-brand__logo-wrapper">
|
||||
<img alt="" src={this.state.logo_link} style={{ 'width': '160px' }} />
|
||||
</a> */}
|
||||
</div>
|
||||
<div className="m-stack__item m-stack__item--middle m-brand__tools">
|
||||
{/* BEGIN: Responsive Aside Left Menu Toggler */}
|
||||
<a href="#/" id="m_aside_left_toggle_mobile" className="m-brand__icon m-brand__toggler m-brand__toggler--left">
|
||||
<span />
|
||||
</a>
|
||||
{/* END */}
|
||||
{/* BEGIN: Topbar Toggler */}
|
||||
<a id="m_aside_header_topbar_mobile_toggle" href="#/" className="m-brand__icon">
|
||||
<i className="flaticon-more" />
|
||||
</a>
|
||||
{/* BEGIN: Topbar Toggler */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="m-stack__item m-stack__item--middle m-stack__item--left m-header-head" id="m_header_nav">
|
||||
<div className="m-stack m-stack--ver m-stack--desktop">
|
||||
<div className="m-stack__item m-stack__item--middle m-stack__item--fit">
|
||||
{/* BEGIN: Aside Left Toggle */}
|
||||
<a className="m-aside-left-toggler m-aside-left-toggler--left m_aside_left_toggler" onClick={() => this.onClickOpen()}>
|
||||
<span />
|
||||
</a>
|
||||
{/* END: Aside Left Toggle */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="m-stack__item m-stack__item--middle m-stack__item--center" style={{ 'width': '160px' }}>
|
||||
<a href="/" className="m-brand m-brand--desktop">
|
||||
{/* <img alt="" src={this.state.logo_link} style={{ 'width': '100%' }} /> */}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default withRouter(Header);
|
||||
80
app/src/components/layouts/MenuBar.js
Normal file
80
app/src/components/layouts/MenuBar.js
Normal file
@@ -0,0 +1,80 @@
|
||||
import React, { Component } from 'react';
|
||||
import { NavLink } from 'react-router-dom';
|
||||
import $ from 'jquery';
|
||||
|
||||
|
||||
class MenuBar extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
type: '',
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
onClickClose = () => {
|
||||
$('#m_aside_left').removeClass('m-aside-left--on')
|
||||
$('#body_form').removeClass('m-aside-left--on')
|
||||
$('#m_aside_left_toggle').removeClass('m-aside-left-toggler--active')
|
||||
$('.m-aside-left-overlay').remove()
|
||||
}
|
||||
|
||||
render() {
|
||||
var active = '';
|
||||
|
||||
|
||||
return (
|
||||
<div id="m_aside_left" className="m-aside-left m-aside-left--skin-dark">
|
||||
{/* BEGIN: Aside Menu */}
|
||||
<div id="m_ver_menu" className="m-aside-menu m-aside-menu--skin-dark m-aside-menu--submenu-skin-dark " data-menu-vertical="true" m-menu-scrollable={1} m-menu-dropdown-timeout={500}>
|
||||
<ul className="m-menu__nav m-menu__nav--dropdown-submenu-arrow ">
|
||||
<li className="m-menu__section m-menu__section--first">
|
||||
{/* <h4 className="m-menu__section-text">Departments</h4> */}
|
||||
<i className="m-menu__section-icon flaticon-more-v3" />
|
||||
</li>
|
||||
<li className="m-menu__item m-menu__item--submenu" aria-haspopup="true" m-menu-submenu-toggle="hover">
|
||||
<NavLink to="/search-image" className={"m-menu__link " + active} activeClassName="m-menu__item--active" onClick={() => this.onClickClose()}>
|
||||
<i className="m-menu__link-icon flaticon-search-1"/>
|
||||
<span className="m-menu__link-title">
|
||||
<span className="m-menu__link-wrap">
|
||||
<span className="m-menu__link-text">Tìm kiếm</span>
|
||||
</span>
|
||||
</span>
|
||||
</NavLink>
|
||||
</li>
|
||||
|
||||
<li className="m-menu__item m-menu__item--submenu" aria-haspopup="true" m-menu-submenu-toggle="hover">
|
||||
<NavLink to="/import-image" className={"m-menu__link " + active} activeClassName="m-menu__item--active" onClick={() => this.onClickClose()}>
|
||||
<i className="m-menu__link-icon flaticon-tabs" />
|
||||
<span className="m-menu__link-title">
|
||||
<span className="m-menu__link-wrap">
|
||||
<span className="m-menu__link-text">Kho ảnh</span>
|
||||
</span>
|
||||
</span>
|
||||
</NavLink>
|
||||
</li>
|
||||
|
||||
<li className="m-menu__item m-menu__item--submenu" aria-haspopup="true" m-menu-submenu-toggle="hover">
|
||||
<NavLink to="/list-famous" className={"m-menu__link " + active} activeClassName="m-menu__item--active" onClick={() => this.onClickClose()}>
|
||||
<i className="m-menu__link-icon flaticon-avatar" />
|
||||
<span className="m-menu__link-title">
|
||||
<span className="m-menu__link-wrap">
|
||||
<span className="m-menu__link-text">Người nổi tiếng</span>
|
||||
</span>
|
||||
</span>
|
||||
</NavLink>
|
||||
</li>
|
||||
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
{/* END: Aside Menu */}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default MenuBar;
|
||||
Reference in New Issue
Block a user