조민지

feat: 킥보드 페이지 데이터 구성

......@@ -4920,6 +4920,12 @@
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.413.tgz",
"integrity": "sha512-Jm1Rrd3siqYHO3jftZwDljL2LYQafj3Kki5r+udqE58d0i91SkjItVJ5RwlJn9yko8i7MOcoidVKjQlgSdd1hg=="
},
"element-resize-event": {
"version": "2.0.9",
"resolved": "https://registry.npmjs.org/element-resize-event/-/element-resize-event-2.0.9.tgz",
"integrity": "sha1-L14VgaKW61J1IQwUG8VjQuIY+HY=",
"dev": true
},
"elliptic": {
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz",
......@@ -9774,6 +9780,11 @@
"minimist": "^1.2.5"
}
},
"moment": {
"version": "2.26.0",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.26.0.tgz",
"integrity": "sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw=="
},
"move-concurrently": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
......@@ -12017,6 +12028,15 @@
}
}
},
"react-dimensions": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/react-dimensions/-/react-dimensions-1.3.1.tgz",
"integrity": "sha512-go5vMuGUxaB5PiTSIk+ZfAxLbHwcIgIfLhkBZ2SIMQjaCgnpttxa30z5ijEzfDjeOCTGRpxvkzcmE4Vt4Ppvyw==",
"dev": true,
"requires": {
"element-resize-event": "^2.0.4"
}
},
"react-dom": {
"version": "16.8.6",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.8.6.tgz",
......@@ -12061,6 +12081,11 @@
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
},
"react-moment": {
"version": "0.9.7",
"resolved": "https://registry.npmjs.org/react-moment/-/react-moment-0.9.7.tgz",
"integrity": "sha512-ifzUrUGF6KRsUN2pRG5k56kO0mJBr8kRkWb0wNvtFIsBIxOuPxhUpL1YlXwpbQCbHq23hUu6A0VEk64HsFxk9g=="
},
"react-notification-system": {
"version": "0.2.17",
"resolved": "https://registry.npmjs.org/react-notification-system/-/react-notification-system-0.2.17.tgz",
......
......@@ -5,12 +5,14 @@
"dependencies": {
"bootstrap": "3.3.7",
"chartist": "0.10.1",
"moment": "^2.26.0",
"node-sass": "4.12.0",
"react": "16.8.6",
"react-bootstrap": "0.32.4",
"react-chartist": "0.13.3",
"react-dom": "16.8.6",
"react-google-maps": "9.4.5",
"react-moment": "^0.9.7",
"react-notification-system": "0.2.17",
"react-router": "5.0.0",
"react-router-dom": "5.0.0",
......@@ -21,6 +23,7 @@
"@types/googlemaps": "3.30.19",
"@types/markerclustererplus": "2.1.33",
"@types/react": "16.8.13",
"react-dimensions": "^1.3.1",
"typescript": "3.4.3"
},
"scripts": {
......
import React, {useEffect} from "react";
import Dimensions from "react-dimensions";
let map, infoWindow;
const GoogleMap = (props) => {
useEffect(() => {
console.log('mount');
const { google } = window;
infoWindow = new window.google.maps.InfoWindow({});
map = new google.maps.Map(document.getElementById("map"), {
zoom: 11,
center: {lat: -34.397, lng: 150.644},
disableDefaultUI: true,
zoomControl: true
});
}, []);
return (
<div id="map" style={{height:props.containerWidth, backgroundColor:'pink'}}>
</div>
)
};
export default Dimensions()(GoogleMap) // Enhanced component
\ No newline at end of file
import React from "react";
import { Card } from "components/Card/Card.jsx";
import Dimensions from 'react-dimensions'
import moment from 'moment';
import GoogleMap from './GoogleMap';
const GoogleMapCard = (props) => {
const getStats = `마지막 업데이트 ${moment().format("YYYY/MM/DD hh:mm")}`;
return (
<Card
id="chartActivity"
title="서비스 현황"
category="All products including Taxes"
stats={getStats}
statsIcon="fa fa-history"
content={
<GoogleMap/>
}
/>
);
};
export default GoogleMapCard // Enhanced component
\ No newline at end of file
import React from "react";
import {Table} from "react-bootstrap";
import { Card } from "components/Card/Card.jsx";
import { tdArray } from "variables/Variables.jsx";
const thArray = ['유저ID', '대여 시각', '반납 시각', '대여 시간', '이동 거리', '대여 금액'];
const KickboardHistoryTable = () => {
return (
<Card
title="Striped Table with Hover"
category="Here is a subtitle for this table"
ctTableFullWidth
ctTableResponsive
content={
<Table striped hover>
<thead>
<tr>
{thArray.map((prop, key) => {
return <th key={key}>{prop}</th>;
})}
</tr>
</thead>
<tbody>
{tdArray.map((prop, key) => {
return (
<tr key={key}>
{prop.map((prop, key) => {
return <td key={key}>{prop}</td>;
})}
</tr>
);
})}
</tbody>
</Table>
}
/>
)
};
export default KickboardHistoryTable;
import React from "react";
import { Card } from "components/Card/Card.jsx";
import {Col, Row} from "react-bootstrap";
import styled from "styled-components"
import moment from "moment";
// border: 1px solid #E3E3E3;
const KickboardButton = styled.div`
background-color: #e7e7e7;
border-radius: 4px;
color: #565656;
padding: 8px 12px;
height: 40px;
box-shadow: none;
margin: 0 auto;
text-align: center;
margin-bottom: 10px;
&:hover {
background-color: #565656;
color: white;
cursor: pointer;
}
`;
const KickboardDataList = styled.ul`
font-size: 16px;
`;
const KickboardData = styled.li`
padding: 3px 0;
`;
const kickboardDataKey = {
a: '배터리',
b: '킥보드 위치',
c: '킥보드 상태',
d: '킥보드 자세 여부',
e: '총 누적 이동 거리',
f: '총 누적 대여 시간',
g: '신호 양호 여부',
h: '현재 네트워크 연결 여부',
i: '최근 gps 업데이트 시각',
j: '최근 연결 업데이트 시각',
k: '모델명',
l: '최근 업데이트 시각',
};
const KickboardStatusCard = () => {
const getStats = `마지막 업데이트 ${moment().format("YYYY/MM/DD hh:mm")}`;
return (
<Card
title={'000000번 킥보드'}
stats={getStats}
statsIcon="fa fa-history"
content={
<Row>
<Col md={4} sm={4} xs={4}>
<KickboardButton>경적 울리기</KickboardButton>
</Col>
<Col md={4} sm={4} xs={4}>
<KickboardButton>반납하기</KickboardButton>
</Col>
<Col md={4} sm={4} xs={4}>
<KickboardButton>운행 종료하기</KickboardButton>
</Col>
<KickboardDataList>
{
Object.keys(kickboardDataKey).map(key => {
return <KickboardData>{kickboardDataKey[key]} : {key}</KickboardData>
})
}
</KickboardDataList>
</Row>
}
>
</Card>
);
};
export default KickboardStatusCard;
\ No newline at end of file
import React from "react";
import styled from "styled-components";
const SearchButtonWrapper = styled.div`
display: flex;
flex-direction: row;
justify-content: space-between;
`;
const SearchInput = styled.input`
width: 80%;
`;
const ApplyButton = styled.div`
width: 17%;
background-color: #e7e7e7;
border-radius: 4px;
color: #565656;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
&:hover {
background-color: #565656;
color: white;
cursor: pointer;
`;
const SearchButton = () => {
return (
<SearchButtonWrapper>
<SearchInput type="text" className="form-control" placeholder={"킥보드 번호로 검색하기"}/>
<ApplyButton><span>검색</span></ApplyButton>
</SearchButtonWrapper>
);
};
export default SearchButton;
......@@ -268,12 +268,12 @@ var style = {
//
const thArray = ["ID", "Name", "Salary", "Country", "City"];
const tdArray = [
["1", "Dakota Rice", "$36,738", "Niger", "Oud-Turnhout"],
["2", "Minerva Hooper", "$23,789", "Curaçao", "Sinaai-Waas"],
["3", "Sage Rodriguez", "$56,142", "Netherlands", "Baileux"],
["4", "Philip Chaney", "$38,735", "Korea, South", "Overland Park"],
["5", "Doris Greene", "$63,542", "Malawi", "Feldkirchen in Kärnten"],
["6", "Mason Porter", "$78,615", "Chile", "Gloucester"]
["1", "Dakota Rice", "$36,738", "Niger", "Oud-Turnhout", '1'],
["2", "Minerva Hooper", "$23,789", "Curaçao", "Sinaai-Waas", '1'],
["3", "Sage Rodriguez", "$56,142", "Netherlands", "Baileux", '1'],
["4", "Philip Chaney", "$38,735", "Korea, South", "Overland Park", '1'],
["5", "Doris Greene", "$63,542", "Malawi", "Feldkirchen in Kärnten", '1'],
["6", "Mason Porter", "$78,615", "Chile", "Gloucester", '1']
];
//
......
import React from "react";
import ChartistGraph from "react-chartist";
import {Grid, Row, Col, Table} from "react-bootstrap";
import { Card } from "components/Card/Card.jsx";
import { Tasks } from "components/Tasks/Tasks.jsx";
import {
dataBar,
optionsBar,
responsiveBar,
} from "variables/Variables.jsx";
import { thArray, tdArray } from "variables/Variables.jsx";
import {Grid, Row, Col} from "react-bootstrap";
import GoogleMapCard from '../components/Kickboard/GoogleMapCard';
import KickboardStatusCard from '../components/Kickboard/KickboardStatusCard';
import KickboardHistoryTable from '../components/Kickboard/KickboardHistoryTable';
import SearchButton from '../components/Kickboard/SearchButton';
const Kickboard = () => {
// 여기 API 요청
return (
<div className="content">
<Grid fluid>
<Row>
<Col md={3} mdOffset={9} sm={3} smOffset={9} style={{marginBottom:15}}>
<input type="text" className="form-control" placeholder={"킥보드 번호로 검색하기"}/>
<Col md={4} mdOffset={8} sm={3} smOffset={9} style={{marginBottom:15}}>
<SearchButton/>
</Col>
</Row>
<Row>
<Col md={6}>
<Card
id="chartActivity"
title="2014 Sales"
category="All products including Taxes"
stats="마지막 업데이트 2020/04/20 17:23"
statsIcon="fa fa-check"
content={
<div className="ct-chart">
<ChartistGraph
data={dataBar}
type="Bar"
options={optionsBar}
responsiveOptions={responsiveBar}
/>
</div>
}
/>
<GoogleMapCard/>
</Col>
<Col md={6}>
<Card
title="Tasks"
category="Backend development"
stats="Updated 3 minutes ago"
statsIcon="fa fa-history"
content={
<div className="table-full-width">
<table className="table">
<Tasks />
</table>
</div>
}
/>
<KickboardStatusCard/>
</Col>
</Row>
<Row>
<Col md={12}>
<Card
title="Striped Table with Hover"
category="Here is a subtitle for this table"
ctTableFullWidth
ctTableResponsive
content={
<Table striped>
<thead>
<tr>
{thArray.map((prop, key) => {
return <th key={key}>{prop}</th>;
})}
</tr>
</thead>
<tbody>
{tdArray.map((prop, key) => {
return (
<tr key={key}>
{prop.map((prop, key) => {
return <td key={key}>{prop}</td>;
})}
</tr>
);
})}
</tbody>
</Table>
}
/>
<KickboardHistoryTable/>
</Col>
</Row>
</Grid>
......
......@@ -21,6 +21,11 @@ import { Grid, Row, Col, Alert } from "react-bootstrap";
import Button from "components/CustomButton/CustomButton.jsx";
class Notifications extends Component {
constructor(props) {
super(props);
console.log(this.props);
}
render() {
return (
<div className="content">
......
This diff is collapsed. Click to expand it.