├── README.md ├── src ├── images │ └── avatar.png ├── components │ ├── shop │ │ ├── bbt.png │ │ ├── kfc.png │ │ ├── starbucks.png │ │ ├── QQ20151212-0.png │ │ ├── index.js │ │ └── index.scss │ ├── person │ │ ├── girl1.png │ │ ├── girl2.png │ │ ├── girl3.png │ │ ├── jalon.jpg │ │ ├── kawayi.png │ │ ├── index.js │ │ └── index.scss │ ├── tab │ │ ├── QQ20151212-0.png │ │ ├── index.js │ │ └── index.scss │ ├── album │ │ ├── QQ20151212-0.png │ │ ├── index.scss │ │ └── index.js │ ├── self-tab │ │ ├── QQ20151212-0.png │ │ ├── index.js │ │ └── index.scss │ ├── chart │ │ ├── index.scss │ │ └── index.js │ ├── title-bar │ │ ├── index.scss │ │ └── index.js │ ├── modal │ │ ├── index.js │ │ └── index.scss │ └── tab-bar │ │ ├── index.scss │ │ └── index.js ├── reset.scss ├── dispacher.js ├── mixin.scss ├── chartGroup │ ├── index.scss │ └── index.js ├── chatPersion │ ├── index.scss │ └── index.js ├── homepage │ ├── index.scss │ └── index.js ├── near-by │ ├── index.scss │ └── index.js ├── self │ ├── index.scss │ └── index.js ├── fans │ ├── index.js │ └── index.scss ├── index.js ├── routes.js ├── mock.js ├── business │ ├── index.scss │ └── index.js └── home │ ├── index.js │ └── index.scss ├── output └── img │ ├── 04c03bfd.bbt.png │ ├── 723e070b.kfc.png │ ├── 93d8dbce.jalon.jpg │ ├── 316f66d4.avatar.png │ ├── 32b5c6d4.kawayi.png │ ├── 83cfe126.starbucks.png │ └── f51ce880.QQ20151212-0.png ├── index.html ├── html.js ├── .gitignore ├── server.js ├── webpack.js ├── webpack.config.js ├── webpack.config.dev.js └── package.json /README.md: -------------------------------------------------------------------------------- 1 | # shopChat 2 | 到店聊 3 | -------------------------------------------------------------------------------- /src/images/avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andycall/shopChat/master/src/images/avatar.png -------------------------------------------------------------------------------- /output/img/04c03bfd.bbt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andycall/shopChat/master/output/img/04c03bfd.bbt.png -------------------------------------------------------------------------------- /output/img/723e070b.kfc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andycall/shopChat/master/output/img/723e070b.kfc.png -------------------------------------------------------------------------------- /output/img/93d8dbce.jalon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andycall/shopChat/master/output/img/93d8dbce.jalon.jpg -------------------------------------------------------------------------------- /src/components/shop/bbt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andycall/shopChat/master/src/components/shop/bbt.png -------------------------------------------------------------------------------- /src/components/shop/kfc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andycall/shopChat/master/src/components/shop/kfc.png -------------------------------------------------------------------------------- /output/img/316f66d4.avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andycall/shopChat/master/output/img/316f66d4.avatar.png -------------------------------------------------------------------------------- /output/img/32b5c6d4.kawayi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andycall/shopChat/master/output/img/32b5c6d4.kawayi.png -------------------------------------------------------------------------------- /src/components/person/girl1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andycall/shopChat/master/src/components/person/girl1.png -------------------------------------------------------------------------------- /src/components/person/girl2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andycall/shopChat/master/src/components/person/girl2.png -------------------------------------------------------------------------------- /src/components/person/girl3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andycall/shopChat/master/src/components/person/girl3.png -------------------------------------------------------------------------------- /src/components/person/jalon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andycall/shopChat/master/src/components/person/jalon.jpg -------------------------------------------------------------------------------- /src/reset.scss: -------------------------------------------------------------------------------- 1 | html, body { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | * { 7 | box-sizing: border-box; 8 | } -------------------------------------------------------------------------------- /output/img/83cfe126.starbucks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andycall/shopChat/master/output/img/83cfe126.starbucks.png -------------------------------------------------------------------------------- /src/components/person/kawayi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andycall/shopChat/master/src/components/person/kawayi.png -------------------------------------------------------------------------------- /src/components/shop/starbucks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andycall/shopChat/master/src/components/shop/starbucks.png -------------------------------------------------------------------------------- /output/img/f51ce880.QQ20151212-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andycall/shopChat/master/output/img/f51ce880.QQ20151212-0.png -------------------------------------------------------------------------------- /src/components/shop/QQ20151212-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andycall/shopChat/master/src/components/shop/QQ20151212-0.png -------------------------------------------------------------------------------- /src/components/tab/QQ20151212-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andycall/shopChat/master/src/components/tab/QQ20151212-0.png -------------------------------------------------------------------------------- /src/components/album/QQ20151212-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andycall/shopChat/master/src/components/album/QQ20151212-0.png -------------------------------------------------------------------------------- /src/components/self-tab/QQ20151212-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andycall/shopChat/master/src/components/self-tab/QQ20151212-0.png -------------------------------------------------------------------------------- /src/dispacher.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by andycall on 15/12/12. 3 | */ 4 | import { Dispatcher } from 'flux' 5 | 6 | export default new Dispatcher() -------------------------------------------------------------------------------- /src/mixin.scss: -------------------------------------------------------------------------------- 1 | @function calculateRem($size) { 2 | $remSize: $size / 16; 3 | @return #{$remSize}rem; 4 | } 5 | 6 | @function pxCompare640($px) { 7 | $remSize: $px / 640; 8 | @return #{$remSize}rem; 9 | } -------------------------------------------------------------------------------- /src/components/album/index.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by andycall on 15/12/12. 3 | */ 4 | 5 | & { 6 | width: 92%; 7 | padding: 10px 15px; 8 | display: flex; 9 | margin: 5px 0; 10 | overflow: hidden; 11 | 12 | .image_container { 13 | flex: 1; 14 | display: flex; 15 | justify-content: space-between; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/chartGroup/index.scss: -------------------------------------------------------------------------------- 1 | .input { 2 | position: fixed; 3 | left: auto; 4 | bottom: 0; 5 | width: 400px; 6 | height: 30px; 7 | border: 2px solid #ccc; 8 | } 9 | 10 | .submit-button { 11 | position: fixed; 12 | right: auto; 13 | left: 400px; 14 | bottom: 0; 15 | } 16 | 17 | .main-chat { 18 | overflow-y: auto; 19 | height: 500px; 20 | } -------------------------------------------------------------------------------- /src/chatPersion/index.scss: -------------------------------------------------------------------------------- 1 | .input { 2 | position: fixed; 3 | left: auto; 4 | bottom: 0; 5 | width: 400px; 6 | height: 30px; 7 | border: 2px solid #ccc; 8 | } 9 | 10 | .submit-button { 11 | position: fixed; 12 | right: auto; 13 | left: 400px; 14 | bottom: 0; 15 | } 16 | 17 | .main-chat { 18 | overflow-y: auto; 19 | height: 500px; 20 | } -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 到店聊 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /html.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by andycall on 15/12/12. 3 | */ 4 | module.exports = ` 5 | 6 | 7 | 8 | 9 | 10 | 到店聊 11 | 12 | 13 |
14 | 15 | 16 | 17 | ` -------------------------------------------------------------------------------- /src/components/chart/index.scss: -------------------------------------------------------------------------------- 1 | .chart-content { 2 | display: flex; 3 | align-items: center; 4 | margin-top: 20px; 5 | .content { 6 | background-color: whitesmoke; 7 | padding: 10px 20px; 8 | color: #333; 9 | border-radius: 10px; 10 | margin: 10px; 11 | } 12 | 13 | .img { 14 | width: 40px; 15 | height: 40px; 16 | background-image: url(../../images/avatar.png); 17 | background-size: cover; 18 | margin: 10px; 19 | } 20 | } -------------------------------------------------------------------------------- /src/components/title-bar/index.scss: -------------------------------------------------------------------------------- 1 | & { 2 | padding: 10px 10px; 3 | background: #ee5a44; 4 | color: white; 5 | display: flex; 6 | justify-content: center; 7 | position: relative; 8 | height: 50px; 9 | 10 | span { 11 | display: inline-block; 12 | line-height: 35px; 13 | } 14 | } 15 | 16 | .back { 17 | position: absolute; 18 | left: 5px; 19 | top: 5px; 20 | padding: 5px 20px 5px 10px; 21 | text-align: center; 22 | cursor: pointer; 23 | 24 | i { 25 | font-size: 30px; 26 | } 27 | } -------------------------------------------------------------------------------- /src/homepage/index.scss: -------------------------------------------------------------------------------- 1 | & { 2 | h2 { 3 | margin: 15px 0; 4 | font-size: 16px; 5 | } 6 | 7 | .chat-wrapper { 8 | position: fixed; 9 | bottom: 0; 10 | width: 400px; 11 | height: 50px; 12 | line-height: 50px; 13 | 14 | button { 15 | width: 80%; 16 | display: block; 17 | line-height: 30px; 18 | background: #ee5a44; 19 | color: #fff; 20 | border: 0; 21 | margin: 0 auto; 22 | border-radius: 8px; 23 | font-size: 14px; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/near-by/index.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by andycall on 15/12/12. 3 | */ 4 | 5 | & { 6 | .nav { 7 | padding: 15px; 8 | border-bottom: 1px solid #ececec; 9 | background: #ee5a44; 10 | 11 | h2 { 12 | margin: 0; 13 | font: 16px helvetica; 14 | color: #fff; 15 | 16 | text-align: center; 17 | width: 100%; 18 | height: 100%; 19 | white-space: pre-wrap; 20 | } 21 | } 22 | 23 | ul.person-list { 24 | margin: 0; 25 | padding: 0; 26 | min-height: 700px; 27 | background: whitesmoke; 28 | overflow: hidden; 29 | } 30 | } -------------------------------------------------------------------------------- /src/components/title-bar/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import './index.scss' 3 | 4 | export default class TitleBar extends React.Component { 5 | onClick () { 6 | location.hash = this.props.return_url 7 | } 8 | 9 | render() { 10 | return ( 11 |
12 |
13 | 15 |
16 | {this.props.title} 17 |
18 | ) 19 | } 20 | } -------------------------------------------------------------------------------- /src/components/album/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by andycall on 15/12/12. 3 | */ 4 | import React from 'react' 5 | 6 | import './index.scss' 7 | 8 | import pic from './QQ20151212-0.png' 9 | 10 | export default class AlbumComponent extends React.Component { 11 | render () { 12 | 13 | return ( 14 |
15 |
16 | 17 | 18 | 19 | 20 |
21 |
22 | ) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/self/index.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by andycall on 15/12/12. 3 | */ 4 | 5 | & { 6 | background: whitesmoke; 7 | min-height: 700px; 8 | 9 | .nav { 10 | padding: 15px; 11 | border-bottom: 1px solid #ececec; 12 | background: #ee5a44; 13 | 14 | h2 { 15 | margin: 0; 16 | font: 16px helvetica; 17 | color: #fff; 18 | 19 | text-align: center; 20 | width: 100%; 21 | height: 100%; 22 | white-space: pre-wrap; 23 | } 24 | } 25 | 26 | ul.person-list { 27 | margin: 0; 28 | padding: 0; 29 | min-height: 700px; 30 | background: whitesmoke; 31 | overflow: hidden; 32 | } 33 | 34 | .tabs { 35 | margin-top: 20px; 36 | } 37 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Node template 3 | # Logs 4 | logs 5 | *.log 6 | npm-debug.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | 13 | # Directory for instrumented libs generated by jscoverage/JSCover 14 | lib-cov 15 | 16 | # Coverage directory used by tools like istanbul 17 | coverage 18 | 19 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 20 | .grunt 21 | 22 | # node-waf configuration 23 | .lock-wscript 24 | 25 | # Compiled binary addons (http://nodejs.org/api/addons.html) 26 | build/Release 27 | 28 | # Dependency directory 29 | # https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git 30 | node_modules 31 | 32 | 33 | .idea 34 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | "use strict" 2 | 3 | var koa = require('koa') 4 | var app = koa() 5 | 6 | // 设置静态资源缓存 7 | var staticCache = require('koa-static-cache') 8 | app.use(staticCache('output', { 9 | prefix: '/output', 10 | maxAge: 365 * 24 * 60 * 60, 11 | buffer: true, 12 | gzip: true, 13 | usePrecompiledGzip: true 14 | })) 15 | 16 | // 监听错误 17 | app.on("error", function (err) { 18 | console.log('服务错误', err) 19 | }) 20 | 21 | // 抓住未捕获的错误 22 | process.on('uncaughtException', function (err) { 23 | console.error('未捕获错误', err) 24 | 25 | //打印出错误 26 | console.log(err) 27 | 28 | //打印出错误的调用栈方便调试 29 | console.log(err.stack) 30 | }) 31 | 32 | // 入口文件 33 | var templateHtml = require('./html.js') 34 | app.use(function *() { 35 | this.type = 'text/html; charset=utf-8' 36 | this.body = templateHtml 37 | }) 38 | 39 | module.exports = app.listen(8080) -------------------------------------------------------------------------------- /src/fans/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import TitleBar from '../components/title-bar' 3 | import './index.scss' 4 | 5 | export default class FansComponent extends React.Component { 6 | render() { 7 | return ( 8 |
9 | 10 | 11 |
12 | 13 |
14 |
卡哇伊
15 |
22岁 172cm
16 |
17 |
18 |
聊天
19 |
20 |
21 | 22 |
23 | ) 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /src/fans/index.scss: -------------------------------------------------------------------------------- 1 | .info-container { 2 | display: flex; 3 | padding: 15px 10px; 4 | background: whitesmoke; 5 | .avatar { 6 | background-image: url(../images/avatar.png); 7 | height: 60px; 8 | width: 60px; 9 | background-size: cover; 10 | } 11 | .center { 12 | display: flex; 13 | flex-direction: column; 14 | flex-grow: 1; 15 | padding-left: 20px; 16 | color: #666; 17 | .title { 18 | font-size: 20px; 19 | font-weight: bold; 20 | margin: 5px 0 15px 0; 21 | } 22 | } 23 | .right { 24 | display: flex; 25 | justify-content: center; 26 | align-items: center; 27 | width: 100px; 28 | .watch { 29 | width: 100px; 30 | height: 30px; 31 | line-height: 30px; 32 | text-align: center; 33 | background: #01a0e4; 34 | border-radius: 5px; 35 | color: white; 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/homepage/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import TitleBar from '../components/title-bar' 3 | import SelfTab from '../components/self-tab' 4 | import AlbumComponent from '../components/album' 5 | import Shop from '../components/shop' 6 | 7 | import './index.scss' 8 | 9 | export default class HomepageComponent extends React.Component { 10 | render() { 11 | return ( 12 |
13 | 14 | 15 | 16 | 17 |

相册

18 | 19 | 20 | 21 |

关注的商家

22 | 23 | 24 | 25 |
26 | 27 |
28 |
29 | ) 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /src/components/modal/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by andycall on 15/12/12. 3 | */ 4 | import React from 'react' 5 | import ReactDOM from 'react-dom' 6 | 7 | import './index.scss' 8 | 9 | export default class ModalComponent extends React.Component { 10 | onClick () { 11 | location.hash = '#/business' 12 | } 13 | 14 | onCancel () { 15 | ReactDOM.findDOMNode(this).style.display = 'none' 16 | } 17 | 18 | render () { 19 | return ( 20 |
21 |

{this.props.title}

22 |

{this.props.content}

23 |
24 |
取消
25 |
进入
26 |
27 |
28 | ) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/components/tab-bar/index.scss: -------------------------------------------------------------------------------- 1 | @import "../../mixin"; 2 | 3 | & { 4 | position: fixed; 5 | width: 400px; 6 | bottom: 0; 7 | padding: 0; 8 | margin: 0; 9 | display: flex; 10 | border-top: 1px solid #888888; 11 | } 12 | 13 | li { 14 | box-sizing: border-box; 15 | list-style: none; 16 | flex: 1; 17 | text-align: center; 18 | background: rgb(246, 246, 247); 19 | 20 | &:hover { 21 | background: darken(rgb(246, 246, 247), 10%); 22 | } 23 | 24 | a { 25 | display: inline-block; 26 | text-decoration: none; 27 | margin: auto; 28 | color: rgb(148, 148, 148); 29 | width: 100%; 30 | 31 | &.active { 32 | color: rgb(238, 90, 68); 33 | } 34 | 35 | i { 36 | display: block; 37 | font-size: 20px; 38 | margin: 5px 0; 39 | } 40 | 41 | span { 42 | display: block; 43 | margin-bottom: 5px; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /webpack.js: -------------------------------------------------------------------------------- 1 | // webpack中间件 2 | var webpackDevServer = require('webpack-dev-server') 3 | var webpack = require('webpack') 4 | var webpackConf = require('./webpack.config.dev.js') 5 | 6 | var server = new webpackDevServer(webpack(webpackConf), { 7 | publicPath: webpackConf.output.publicPath, 8 | proxy: { 9 | '*': { 10 | target: 'http://localhost:8080', 11 | secure: false 12 | } 13 | }, 14 | hot: true, 15 | quiet: false, 16 | noInfo: false, 17 | watchOptions: { 18 | aggregateTimeout: 300, 19 | poll: 1000 20 | }, 21 | stats: { 22 | colors: true, 23 | hash: false, 24 | timings: false, 25 | assets: true, 26 | chunks: true, 27 | chunkModules: true, 28 | modules: false, 29 | children: true 30 | } 31 | }) 32 | 33 | server.listen(8090, 'localhost', function () { 34 | }) -------------------------------------------------------------------------------- /src/components/tab/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by andycall on 15/12/12. 3 | */ 4 | 5 | /** 6 | * Created by andycall on 15/12/12. 7 | */ 8 | import React from 'react' 9 | 10 | import './index.scss' 11 | 12 | import pic from './QQ20151212-0.png' 13 | 14 | export default class TabComponent extends React.Component { 15 | render () { 16 | let right = 17 | 18 | return ( 19 |
20 |
21 | 22 |
23 |
24 |

{this.props.order_name}

25 | {this.props.orders} 26 |
27 |
28 | {right} 29 |
30 |
31 | ) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/components/modal/index.scss: -------------------------------------------------------------------------------- 1 | & { 2 | position: absolute; 3 | width: 280px; 4 | height: 135px; 5 | top: 0; 6 | bottom: 0; 7 | left: 0; 8 | right: 0; 9 | margin: auto; 10 | z-index: 100; 11 | text-align: center; 12 | background: rgb(245, 245, 245); 13 | border: 1px solid rgb(199, 199, 199); 14 | border-radius: 8px; 15 | 16 | h2, p { 17 | color: rgb(144, 144, 144); 18 | } 19 | 20 | h2 { 21 | font-size: 18px; 22 | font-weight: normal; 23 | } 24 | 25 | .button { 26 | position: relative; 27 | width: 100%; 28 | display: flex; 29 | justify-content: space-between; 30 | 31 | .cancel, .go { 32 | padding: 15px; 33 | margin: 0 15px; 34 | border-radius: 5px; 35 | font-size: 14px; 36 | cursor: pointer; 37 | } 38 | 39 | .cancel { 40 | flex: 1; 41 | color: #888; 42 | } 43 | 44 | .go { 45 | flex: 1; 46 | background: #ee5a44; 47 | color: #fff; 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /src/components/self-tab/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by andycall on 15/12/12. 3 | */ 4 | import React from 'react' 5 | 6 | import './index.scss' 7 | 8 | import jalon from '../person/jalon.jpg' 9 | 10 | export default class SelfTabComponent extends React.Component { 11 | render () { 12 | let right = 13 | 14 | return ( 15 |
16 |
17 | 18 |
19 |
20 |

Jalon

21 |
22 | 23岁 23 | 24 | 178cm 25 |
26 |
27 |
28 | {right} 29 |
30 |
31 | ) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/components/chart/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import './index.scss' 3 | 4 | export default class TitleBar extends React.Component { 5 | render() { 6 | let chartContentStyle = { 7 | justifyContent: this.props.right ? 'flex-start' : 'flex-end' 8 | } 9 | 10 | let contentStyle = { 11 | order: this.props.left ? 1 : 3 12 | } 13 | 14 | let imgStyle = { 15 | order: 2 16 | } 17 | 18 | return ( 19 |
20 |
22 |
24 | {this.props.content} 25 |
26 | 28 |
29 |
30 | ) 31 | } 32 | } -------------------------------------------------------------------------------- /src/near-by/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by andycall on 15/12/12. 3 | */ 4 | import React from 'react' 5 | import TabBar from '../components/tab-bar' 6 | 7 | import './index.scss' 8 | 9 | import { MOCK_PERSON_DATA } from '../mock' 10 | 11 | import Person from '../components/person' 12 | 13 | export default class NearByComponent extends React.Component { 14 | constructor (props) { 15 | super(props) 16 | } 17 | 18 | render () { 19 | let persons = MOCK_PERSON_DATA.map((item, index) => { 20 | return ( 21 | 22 | ) 23 | }) 24 | 25 | return ( 26 |
27 |
28 |

附近

29 |
30 | 31 | 34 | 35 | 36 |
37 | ) 38 | } 39 | } -------------------------------------------------------------------------------- /src/components/tab/index.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by andycall on 15/12/12. 3 | */ 4 | 5 | & { 6 | width: 100%; 7 | padding: 10px 15px; 8 | display: flex; 9 | margin: 1px 0; 10 | background: #fff; 11 | overflow: hidden; 12 | 13 | .image_container { 14 | flex: 0.6; 15 | 16 | img { 17 | width: 80%; 18 | } 19 | } 20 | 21 | .content { 22 | flex: 3; 23 | display: flex; 24 | overflow: hidden; 25 | 26 | h2 { 27 | margin: 0; 28 | line-height: 35px; 29 | font-size: 16px; 30 | color: #888888; 31 | } 32 | 33 | span { 34 | line-height: 35px; 35 | font-size: 14px; 36 | margin: 0 5px; 37 | color: #ee5a44; 38 | font-weight: bold; 39 | display: inline-block; 40 | } 41 | } 42 | 43 | .right { 44 | flex: 1; 45 | display: flex; 46 | position: relative; 47 | 48 | .fa { 49 | position: absolute; 50 | top: 13px; 51 | right: 20px; 52 | display: block; 53 | color: #ee5a44; 54 | } 55 | 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/self/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by andycall on 15/12/12. 3 | */ 4 | 5 | import React from 'react' 6 | import TabBar from '../components/tab-bar' 7 | import SelfTabComponent from '../components/self-tab' 8 | import TabComponent from '../components/tab' 9 | 10 | import './index.scss' 11 | 12 | export default class SelfComponent extends React.Component { 13 | 14 | render () { 15 | 16 | return ( 17 |
18 |
19 |

我的

20 |
21 | 22 |
23 | 24 |
25 | 26 |
27 | 28 | 29 | 30 |
31 | 32 |
33 | ) 34 | } 35 | } -------------------------------------------------------------------------------- /src/components/self-tab/index.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by andycall on 15/12/12. 3 | */ 4 | 5 | & { 6 | width: 100%; 7 | padding: 10px 15px; 8 | margin: 15px 0; 9 | display: flex; 10 | background: #fff; 11 | overflow: hidden; 12 | 13 | .image_container { 14 | flex: 1; 15 | } 16 | 17 | .content { 18 | flex: 3; 19 | overflow: hidden; 20 | 21 | h2 { 22 | margin: 0; 23 | line-height: 25px; 24 | padding-bottom: 10px; 25 | font-size: 16px; 26 | color: #888888; 27 | } 28 | 29 | .status { 30 | i { 31 | display: inline-block; 32 | margin-right: 3px; 33 | color: #ee5a44; 34 | } 35 | 36 | span { 37 | font-size: 14px; 38 | display: inline-block; 39 | margin-right: 8px; 40 | color: #888888; 41 | } 42 | } 43 | } 44 | 45 | .right { 46 | flex: 1; 47 | display: flex; 48 | 49 | .fa { 50 | display: inline-block; 51 | margin: auto; 52 | color: #ee5a44; 53 | font-size: 25px; 54 | } 55 | 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author dongtiancheng 3 | * @date 15/12/7. 4 | * @email dongtiancheng@baidu.com 5 | */ 6 | 7 | import React from 'react' 8 | import ReactDOM from 'react-dom' 9 | 10 | // font-awesome 11 | import 'font-awesome/css/font-awesome.css' 12 | import './reset.scss' 13 | 14 | import { ReactRouter, Router } from 'react-router' 15 | 16 | import {routes} from './routes' 17 | 18 | 19 | // 设置页面缩放 20 | const WIDTH = 400 21 | const ratio = screen.width / WIDTH 22 | const meta = document.createElement('meta') 23 | meta.setAttribute('name', 'viewport') 24 | meta.setAttribute('content', 'width=' + WIDTH + ',initial-scale=' + ratio + ',maximum-scale=' + ratio + ',minimum-scale=' + ratio + ',user-scalable=no,target-densitydpi=device-dpi,minimal-ui') 25 | document.getElementsByTagName('head')[0].appendChild(meta) 26 | document.getElementById('main').style.width = WIDTH + 'px' 27 | document.getElementById('main').style.margin = '0 auto' 28 | document.getElementById('main').style.position = 'relative' 29 | 30 | ReactDOM.render( 31 | routes, 32 | document.getElementById('main') 33 | ) -------------------------------------------------------------------------------- /src/components/shop/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by andycall on 15/12/12. 3 | */ 4 | import React from 'react' 5 | 6 | import './index.scss' 7 | 8 | export default class ShopComponent extends React.Component { 9 | onClick () { 10 | location.hash = '#/business' 11 | } 12 | 13 | render () { 14 | return ( 15 |
16 |
17 | 18 |
19 |
20 |
21 |

{this.props.shop_name}

22 | {this.props.shop_distance}m 23 |
24 |
25 | 26 | {this.props.shop_count} 27 | 28 | {this.props.shop_discount}折 29 |
30 |
31 |
32 | {this.props.rightButton} 33 |
34 |
35 | ) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/components/person/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by andycall on 15/12/12. 3 | */ 4 | import React from 'react' 5 | 6 | import './index.scss' 7 | 8 | export default class PersonComponent extends React.Component { 9 | onClick () { 10 | location.hash = '#/chat-person' 11 | } 12 | 13 | render () { 14 | return ( 15 |
16 |
17 | 18 |
19 |
20 |
21 |

{this.props.person_name}

22 | {this.props.person_distance}m 23 |
24 |
25 | 26 | {this.props.person_age}岁 27 | 28 | {this.props.person_height}cm 29 |
30 |
31 |
32 | 33 |
34 |
35 | ) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack') 2 | var path = require('path') 3 | 4 | module.exports = { 5 | entry: [ 6 | './src/index.js' 7 | ], 8 | 9 | output: { 10 | path: path.join(__dirname, 'output'), 11 | filename: 'bundle.js', 12 | publicPath: '/output/' 13 | }, 14 | 15 | module: { 16 | loaders: [ 17 | { 18 | test: /\.js?$/, 19 | exclude: /node_modules/, 20 | loaders: ['babel?presets[]=react,presets[]=es2015', 'html-path-loader'] 21 | }, { 22 | test: /\.(scss|css)/, 23 | exclude: /node_modules/, 24 | loaders: ['style', 'css', 'autoprefixer', 'sass', 'css-path-loader'] 25 | }, { 26 | test: /\.(scss|css)/, 27 | include: /node_modules/, 28 | loaders: ['style', 'css', 'autoprefixer', 'sass'] 29 | }, { 30 | test: /\.(png|jpg)$/, 31 | exclude: /node_modules/, 32 | loader: 'url?limit=3000&name=img/[hash:8].[name].[ext]' 33 | }, { 34 | test: /\.(woff|woff2|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, 35 | loader: 'url' 36 | }, { 37 | test: /\.json$/, 38 | loader: 'json-loader' 39 | } 40 | ] 41 | } 42 | } -------------------------------------------------------------------------------- /src/routes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author dongtiancheng 3 | * @date 15/12/7. 4 | * @email dongtiancheng@baidu.com 5 | */ 6 | import React from 'react' 7 | import { Router, Route, IndexRoute, Redirect } from 'react-router' 8 | 9 | import HomeComponent from './home' 10 | import BusinessComponent from './business' 11 | 12 | import ChartGroupComponent from './chartGroup' 13 | import ChatPersionComponent from './chatPersion' 14 | import FansComponent from './fans' 15 | import NearByComponent from './near-by' 16 | import SelfComponent from './self' 17 | import HomepageComponent from './homepage' 18 | 19 | let routes = ( 20 | 21 | 23 | 24 | 26 | 28 | 30 | 32 | 34 | 36 | 38 | 39 | ) 40 | 41 | export {routes} -------------------------------------------------------------------------------- /src/mock.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by andycall on 15/12/12. 3 | */ 4 | 5 | 6 | import KFC from './components/shop/kfc.png' 7 | import STARTBUCKS from './components/shop/starbucks.png' 8 | import BBT from './components/shop/bbt.png' 9 | 10 | import KWY from './components/person/kawayi.png' 11 | import GIRL from './components/person/girl2.png' 12 | 13 | let MOCK_HOME_DATA = [ 14 | { 15 | shop_name: '棒棒糖 KTV', 16 | shop_count: '9213', 17 | shop_discount: '8.5', 18 | shop_url: BBT, 19 | shop_people: 82, 20 | shop_distance: 1233 21 | }, 22 | { 23 | shop_name: 'KFC', 24 | shop_count: '7783', 25 | shop_discount: '9.5', 26 | shop_url: KFC, 27 | shop_people: 22, 28 | shop_distance: 231 29 | }, 30 | { 31 | shop_name: 'Starbucks', 32 | shop_count: '2321', 33 | shop_discount: '9', 34 | shop_url: STARTBUCKS, 35 | shop_people: 13, 36 | shop_distance: 2322 37 | } 38 | ] 39 | 40 | let MOCK_PERSON_DATA = [ 41 | { 42 | person_name: '卡哇伊', 43 | person_distance: 200, 44 | person_age: 22, 45 | person_height: 172, 46 | person_url: KWY 47 | }, 48 | { 49 | person_name: 'Andycall', 50 | person_distance: 120, 51 | person_age: 23, 52 | person_height: 168, 53 | person_url: GIRL 54 | } 55 | ] 56 | 57 | export default MOCK_HOME_DATA 58 | export { MOCK_PERSON_DATA } -------------------------------------------------------------------------------- /src/components/tab-bar/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by andycall on 15/12/11. 3 | */ 4 | 5 | import React from 'react' 6 | import classnames from 'classnames' 7 | 8 | let tabConfig = [ 9 | { 10 | text: '附近', 11 | icon: 'fa-map-marker', 12 | href: '#/' 13 | }, 14 | { 15 | text: '聊过', 16 | icon: 'fa-comment', 17 | href: '#/nearby' 18 | }, 19 | { 20 | text: '我的', 21 | icon: 'fa-user', 22 | href: '#/self' 23 | } 24 | ] 25 | 26 | import './index.scss' 27 | 28 | export default class TabBar extends React.Component { 29 | constructor (props) { 30 | super(props) 31 | this.state = { 32 | active: props.active || '#/' 33 | } 34 | } 35 | 36 | componentWillReceiveProps (props) { 37 | this.setState({ 38 | active: props.active 39 | }) 40 | } 41 | 42 | render () { 43 | 44 | let tabs = tabConfig.map((item, index) => { 45 | 46 | return ( 47 |
  • 48 | 49 | 50 | {item.text} 51 | 52 |
  • 53 | ) 54 | }) 55 | 56 | return ( 57 | 60 | ) 61 | } 62 | } -------------------------------------------------------------------------------- /webpack.config.dev.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author dongtiancheng 3 | * @date 15/12/6. 4 | * @email dongtiancheng@baidu.com 5 | */ 6 | 7 | var webpack = require('webpack') 8 | var path = require('path') 9 | 10 | var config = { 11 | entry: [ 12 | 'webpack-dev-server/client?http://0.0.0.0:8090', 13 | 'webpack/hot/only-dev-server', 14 | './src/index.js' 15 | ], 16 | devtool: 'eval', 17 | output: { 18 | path: path.join(__dirname, 'output'), 19 | filename: 'bundle.js', 20 | publicPath: '/output/' 21 | }, 22 | watch: true, 23 | module: { 24 | loaders: [ 25 | { 26 | test: /\.js?$/, 27 | exclude: /node_modules/, 28 | loaders: ['react-hot-loader', 'babel?presets[]=react,presets[]=es2015', 'html-path-loader'] 29 | }, 30 | { 31 | test: /\.(scss|css)/, 32 | loaders: ['style', 'css', 'autoprefixer', 'sass', 'css-path-loader'] 33 | }, 34 | { 35 | test: /\.(png|jpg)$/, 36 | exclude: /node_modules/, 37 | loader: 'url' 38 | }, 39 | { 40 | test: /\.(woff|woff2|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, 41 | loader: 'url' 42 | }, 43 | { 44 | test: /\.json$/, 45 | loader: 'json-loader' 46 | } 47 | ] 48 | }, 49 | 50 | plugins: [ 51 | new webpack.DefinePlugin({ 52 | 'process.env.NODE_ENV': '"development"' 53 | }), 54 | new webpack.HotModuleReplacementPlugin() 55 | ] 56 | } 57 | 58 | module.exports = config -------------------------------------------------------------------------------- /src/components/shop/index.scss: -------------------------------------------------------------------------------- 1 | .clearfix, 2 | .clearfix:after, 3 | .clearfix:before { 4 | clear: both; 5 | content: ' '; 6 | overflow: hidden; 7 | 8 | } 9 | 10 | & { 11 | width: 100%; 12 | padding: 10px 15px; 13 | display: flex; 14 | margin: 5px 0; 15 | background: whitesmoke; 16 | overflow: hidden; 17 | 18 | &:hover { 19 | cursor: pointer; 20 | } 21 | 22 | .image_container { 23 | flex: 1.2; 24 | 25 | img { 26 | width: 80%; 27 | } 28 | } 29 | 30 | .content { 31 | flex: 3; 32 | overflow: hidden; 33 | position: relative; 34 | 35 | h2 { 36 | float: left; 37 | margin: 0; 38 | line-height: 25px; 39 | padding-bottom: 10px; 40 | font-size: 16px; 41 | color: #888888; 42 | } 43 | 44 | .distance { 45 | float: left; 46 | font-size: 12px; 47 | margin-left: 5px; 48 | margin-top: 8px; 49 | color: lighten(#888888, 10%); 50 | } 51 | 52 | .status { 53 | i { 54 | display: inline-block; 55 | margin-right: 3px; 56 | color: #ee5a44; 57 | } 58 | 59 | span { 60 | font-size: 14px; 61 | display: inline-block; 62 | margin-right: 8px; 63 | color: #888888; 64 | } 65 | } 66 | } 67 | 68 | .right { 69 | flex: 2; 70 | display: flex; 71 | 72 | p.number { 73 | margin: auto; 74 | width: 80px; 75 | display: inline-block; 76 | background: #ee5a44; 77 | color: #fff; 78 | font-size: 12px; 79 | text-align: center; 80 | line-height: 30px; 81 | border-radius: 15px; 82 | 83 | i { 84 | font-size: 14px; 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/business/index.scss: -------------------------------------------------------------------------------- 1 | .info-container { 2 | display: flex; 3 | padding: 15px 10px; 4 | background: whitesmoke; 5 | .avatar { 6 | background-image: url(../images/avatar.png); 7 | height: 60px; 8 | width: 60px; 9 | background-size: cover; 10 | } 11 | .center { 12 | display: flex; 13 | flex-direction: column; 14 | flex-grow: 1; 15 | padding-left: 20px; 16 | color: #666; 17 | .title { 18 | font-size: 20px; 19 | font-weight: bold; 20 | margin: 5px 0 15px 0; 21 | } 22 | } 23 | .right { 24 | display: flex; 25 | justify-content: center; 26 | align-items: center; 27 | width: 100px; 28 | 29 | .watch { 30 | width: 70px; 31 | height: 30px; 32 | line-height: 30px; 33 | text-align: center; 34 | background: #ee5a44; 35 | border-radius: 5px; 36 | color: white; 37 | cursor: pointer; 38 | } 39 | } 40 | } 41 | 42 | .focusd { 43 | color: #888888; 44 | } 45 | 46 | .tab { 47 | display: flex; 48 | justify-content: space-between; 49 | margin-top: 15px; 50 | .item { 51 | display: flex; 52 | justify-content: center; 53 | align-items: center; 54 | color: #999; 55 | width: 120px; 56 | height: 50px; 57 | background-color: whitesmoke; 58 | cursor: pointer; 59 | 60 | .brage { 61 | margin-left: 5px; 62 | display: flex; 63 | justify-content: center; 64 | align-items: center; 65 | background-color: #9c3328; 66 | color: white; 67 | width: 25px; 68 | height: 18px; 69 | font-size: 12px; 70 | border-radius: 10px; 71 | } 72 | } 73 | } 74 | 75 | .online-number { 76 | color: #999; 77 | font-size: 14px; 78 | } -------------------------------------------------------------------------------- /src/components/person/index.scss: -------------------------------------------------------------------------------- 1 | .clearfix, 2 | .clearfix:after, 3 | .clearfix:before { 4 | clear: both; 5 | content: ' '; 6 | overflow: hidden; 7 | 8 | } 9 | 10 | & { 11 | width: 100%; 12 | padding: 10px 15px; 13 | display: flex; 14 | margin: 15px 0; 15 | background: #fff; 16 | overflow: hidden; 17 | 18 | &:hover { 19 | cursor: pointer; 20 | } 21 | 22 | .image_container { 23 | flex: 1.2; 24 | 25 | img { 26 | width: 80%; 27 | } 28 | } 29 | 30 | .content { 31 | flex: 3; 32 | overflow: hidden; 33 | position: relative; 34 | 35 | h2 { 36 | float: left; 37 | margin: 0; 38 | line-height: 25px; 39 | padding-bottom: 10px; 40 | font-size: 16px; 41 | color: #888888; 42 | } 43 | 44 | .distance { 45 | float: left; 46 | font-size: 12px; 47 | margin-left: 5px; 48 | margin-top: 8px; 49 | color: lighten(#888888, 10%); 50 | } 51 | 52 | .status { 53 | i { 54 | display: inline-block; 55 | margin-right: 3px; 56 | color: #ee5a44; 57 | } 58 | 59 | span { 60 | font-size: 14px; 61 | display: inline-block; 62 | margin-right: 8px; 63 | color: #888888; 64 | } 65 | } 66 | } 67 | 68 | .right { 69 | flex: 2; 70 | display: flex; 71 | 72 | button { 73 | border: 0; 74 | margin: auto; 75 | width: 70px; 76 | display: inline-block; 77 | background: #ee5a44; 78 | color: #fff; 79 | font-size: 12px; 80 | text-align: center; 81 | line-height: 30px; 82 | border-radius: 4px; 83 | 84 | i { 85 | font-size: 14px; 86 | } 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/home/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author dongtiancheng 3 | * @date 15/12/7. 4 | * @email dongtiancheng@baidu.com 5 | */ 6 | 7 | import React from 'react' 8 | import TabBar from '../components/tab-bar' 9 | import Shop from '../components/shop' 10 | import Modal from '../components/modal' 11 | 12 | import "./index.scss" 13 | 14 | import MOCK_HOME_DATA from '../mock' 15 | 16 | export default class HomeComponent extends React.Component { 17 | render () { 18 | 19 | let shops = MOCK_HOME_DATA.map((item, index) => { 20 | let rightButton = ( 21 |

    {item.shop_people}人

    22 | ) 23 | return ( 24 | 25 | ) 26 | }) 27 | 28 | return ( 29 |
    30 |
    31 | 附近 32 |
    33 |
    34 | 35 | 36 |
    37 |
    38 |
    39 | 40 |
    41 |

    附近商家

    42 |

    按距离

    43 | 44 | 47 |
    48 | 49 | 50 | 51 | 52 |
    53 | ) 54 | 55 | } 56 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gaea", 3 | "version": "1.0.0", 4 | "description": "shop chat", 5 | "main": "index.js", 6 | "scripts": { 7 | "server": "node server.js", 8 | "webpack-dev": "node webpack.js", 9 | "webpack-dist": "webpack -p --profile --display-modules", 10 | "start": "npm run server & npm run webpack-dev", 11 | "build": "npm run webpack-dist && npm run server", 12 | "render": "babel server/render.js" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/andycall/shopChat.git" 17 | }, 18 | "author": "", 19 | "license": "ISC", 20 | "bugs": { 21 | "url": "https://github.com/andycall/shopChat/issues" 22 | }, 23 | "homepage": "https://github.com/andycall/shopChat#readme", 24 | "dependencies": { 25 | "antd": "^0.10.4", 26 | "classnames": "^2.2.1", 27 | "css-path-loader": "^0.2.10", 28 | "flux": "^2.1.1", 29 | "font-awesome": "^4.5.0", 30 | "history": "^1.13.1", 31 | "html-path-loader": "^0.1.10", 32 | "json-loader": "^0.5.4", 33 | "jquery": "^2.1.4", 34 | "koa-static-cache": "^3.1.3", 35 | "lodash": "^3.10.1", 36 | "react": "^0.14.3", 37 | "react-dom": "^0.14.3", 38 | "react-router": "^1.0.2", 39 | "react-socket": "^0.1.4", 40 | "rem-layout": "^0.1.1" 41 | }, 42 | "devDependencies": { 43 | "autoprefixer-loader": "^3.1.0", 44 | "babel-core": "^6.2.1", 45 | "babel-loader": "^6.2.0", 46 | "babel-preset-es2015": "^6.1.18", 47 | "babel-preset-react": "^6.1.18", 48 | "base64-font-loader": "0.0.2", 49 | "css-loader": "^0.19.0", 50 | "file-loader": "^0.8.4", 51 | "jsx-loader": "^0.13.2", 52 | "koa": "^1.1.2", 53 | "node-sass": "^3.4.2", 54 | "react-addons-perf": "^0.14.3", 55 | "react-hot-loader": "^1.3.0", 56 | "react-router": "^1.0.0", 57 | "sass-loader": "^3.1.2", 58 | "style-loader": "^0.13.0", 59 | "url-loader": "^0.5.7", 60 | "webpack": "^1.12.9", 61 | "webpack-dev-server": "^1.12.1" 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/home/index.scss: -------------------------------------------------------------------------------- 1 | $font-family: sans-serif; 2 | $font-size: 1em; 3 | $font-weight: 400; 4 | 5 | $line-height: 1.5em; 6 | 7 | $color: #282828; 8 | $color-bg: #d8d6d8; 9 | $color-border: #dfdfdf; 10 | 11 | $color-placeholder: #b2b2b2; 12 | 13 | & { 14 | width: 100%; 15 | min-height: 600px; 16 | } 17 | 18 | .nav { 19 | padding: 15px; 20 | display: flex; 21 | border-bottom: 1px solid #ececec; 22 | background: whitesmoke; 23 | 24 | span { 25 | font-size: 14px; 26 | flex: 1; 27 | line-height: 25px; 28 | text-align: center; 29 | } 30 | 31 | .search { 32 | flex: 7; 33 | 34 | .field { 35 | position: relative; 36 | } 37 | 38 | label { 39 | background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAQAAAC1QeVaAAAAxElEQVR4AXXPIUuDcRDA4Zv4AUSwTLEKVoNlySyCYLO98CCsahGrX0AW/QhmBRHEJghLS4JFBBXDgrJi2In78w8v4v3S8XDh4nd0DTxLEzd2RC2EnrH07trQVDrXqbhs7FvfnBDWDKWTigOpL2oWvZpYKPjio1zVHEt7BdOtaLUtHRX8MmqjRjooeCVttPBOWi+4JT1aLaDjVLpU/5ytn840Dj1IaWSpYmi8yVlTF54qh9K8nn27usJK5fC3yvfhPx7a/AE9dYwDEfKrlAAAAABJRU5ErkJggg==) no-repeat 0 50%; 40 | color: $color-placeholder; 41 | left: 50%; 42 | position: absolute; 43 | transform: translate(-50%, -50%); 44 | top: 50%; 45 | transition: left .4s, transform .4s; 46 | padding-left: 20px; 47 | } 48 | 49 | .input-search { 50 | border: 1px solid $color-border; 51 | border-radius: 10px; 52 | display: block; 53 | font-size: 12px; 54 | padding: 5px 0; 55 | padding-left: 25px; 56 | outline: 0; 57 | width: 90%; 58 | 59 | &:focus, 60 | &:valid { 61 | 62 | &+ label { 63 | left: 10px; 64 | transform: translate(0, -50%); 65 | } 66 | 67 | } 68 | 69 | &:valid { 70 | 71 | &+ label { 72 | text-indent: -9999px; 73 | } 74 | 75 | } 76 | 77 | } 78 | 79 | } 80 | } 81 | 82 | .nearby { 83 | position: relative; 84 | background: whitesmoke; 85 | overflow: hidden; 86 | 87 | h4 { 88 | padding: 15px; 89 | margin: 0; 90 | background: #fff; 91 | } 92 | 93 | p.distance { 94 | font-size: 12px; 95 | padding-top: 10px; 96 | position: absolute; 97 | left: 90px; 98 | top: -3px; 99 | } 100 | 101 | ul { 102 | margin: 0; 103 | padding: 0; 104 | display: flex; 105 | flex-direction: column; 106 | background: #fff; 107 | } 108 | } -------------------------------------------------------------------------------- /src/chatPersion/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | import TitleBar from '../components/title-bar' 4 | import Chart from '../components/chart' 5 | import { Socket, Event } from 'react-socket' 6 | import _ from 'lodash' 7 | import $ from 'jquery' 8 | import './index.scss' 9 | 10 | import jalon from '../components/person/jalon.jpg' 11 | import KWY from '../components/person/kawayi.png' 12 | 13 | export default class BusinessComponent extends React.Component { 14 | constructor(props) { 15 | super(props) 16 | this.state = { 17 | text: '', 18 | name: 'Guest_' + Math.floor(Math.random() * 10000), 19 | messages: [] 20 | } 21 | } 22 | 23 | onMessage(root, name, info, message) { 24 | let newMessages = _.cloneDeep(this.state.messages) 25 | newMessages.push({ 26 | name: name, 27 | message: message 28 | }) 29 | 30 | this.setState({ 31 | messages: newMessages 32 | }, ()=> { 33 | let $dom = $('#main-chat-content') 34 | $dom.scrollTop($dom[0].scrollHeight) 35 | }) 36 | } 37 | 38 | handleInputChange(e) { 39 | this.setState({ 40 | text: e.target.value 41 | }) 42 | } 43 | 44 | handleSubmit(e) { 45 | if (e.keyCode !== 13)return 46 | if (this.state.text === '')return 47 | 48 | Socket.socket().emit('room', 'bbt', this.state.text) 49 | this.setState({ 50 | text: '' 51 | }) 52 | } 53 | 54 | componentDidMount() { 55 | Socket.socket().emit('me', this.state.name, {info: null}) 56 | Socket.socket().emit('join', 'bbt') 57 | 58 | let $dom = $('#main-chat-content') 59 | $('#main-chat-content').height($(document).height() - 82) 60 | } 61 | 62 | render() { 63 | let Messages = this.state.messages.map((item, index)=> { 64 | if (item.name === this.state.name) { 65 | return 69 | } else { 70 | return 74 | } 75 | }) 76 | 77 | return ( 78 |
    79 | 80 | 81 |
    {Messages}
    83 | 84 | 88 | 89 | 90 | 92 |
    93 | ) 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/business/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import TitleBar from '../components/title-bar' 3 | import './index.scss' 4 | 5 | import BBT from '../components/shop/bbt.png' 6 | 7 | export default class BusinessComponent extends React.Component { 8 | constructor (props) { 9 | super(props) 10 | this.state = { 11 | focused: this.props.focused, 12 | fansCount: this.props.fansCount || 123 13 | } 14 | } 15 | 16 | goChat () { 17 | location.hash = '#/chat-group' 18 | } 19 | 20 | onFocus () { 21 | 22 | let fansCount = this.state.fansCount + 1; 23 | 24 | this.setState({ 25 | focused: true, 26 | fansCount: fansCount 27 | }) 28 | } 29 | 30 | render() { 31 | 32 | let focus 33 | 34 | if (this.state.focused) { 35 | focus =

    已关注

    36 | } 37 | else { 38 | focus =
    关注
    39 | } 40 | 41 | return ( 42 |
    43 | 44 | 45 |
    46 | 47 |
    48 |
    棒棒糖KTV
    49 |
    粉丝 {this.state.fansCount}
    50 |
    51 |
    52 | {focus} 53 |
    54 |
    55 | 56 |
    57 |
    58 | 进入群聊 59 | 23 60 |
    61 |
    团购套餐
    62 |
    联系商家
    63 |
    64 | 65 |
    66 | 店内在线用户 67 |
    68 | 69 |
    70 | 71 |
    72 |
    卡哇伊
    73 |
    有没有过来一起唱歌的,亲们~~~
    74 |
    75 |
    76 |
    聊天
    77 |
    78 |
    79 | 80 |
    81 | 82 |
    83 |
    kimi
    84 |
    有一起唱歌的吗?888房间哦!
    85 |
    86 |
    87 |
    聊天
    88 |
    89 |
    90 | 91 |
    92 | ) 93 | } 94 | } 95 | 96 | -------------------------------------------------------------------------------- /src/chartGroup/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | import TitleBar from '../components/title-bar' 4 | import Chart from '../components/chart' 5 | import { Socket, Event } from 'react-socket' 6 | import _ from 'lodash' 7 | import $ from 'jquery' 8 | import './index.scss' 9 | 10 | import jalon from '../components/person/jalon.jpg' 11 | 12 | import KWY from '../components/person/kawayi.png' 13 | 14 | import girl1 from '../components/person/girl1.png' 15 | import girl2 from '../components/person/girl2.png' 16 | import girl3 from '../components/person/girl3.png' 17 | 18 | let girMap = { 19 | girl1: girl1, 20 | girl2: girl2, 21 | girl3: girl3 22 | } 23 | 24 | export default class BusinessComponent extends React.Component { 25 | constructor(props) { 26 | super(props) 27 | this.state = { 28 | text: '', 29 | name: 'Guest_' + Math.floor(Math.random() * 10000), 30 | messages: [] 31 | } 32 | } 33 | 34 | onMessage(root, name, info, message) { 35 | let newMessages = _.cloneDeep(this.state.messages) 36 | let random = Math.random() + 0.00001 37 | 38 | newMessages.push({ 39 | name: name, 40 | message: message, 41 | url: girMap['girl' + Math.ceil(random * 3)] 42 | }) 43 | 44 | this.setState({ 45 | messages: newMessages 46 | }, ()=> { 47 | let $dom = $('#main-chat-content') 48 | $dom.scrollTop($dom[0].scrollHeight) 49 | }) 50 | } 51 | 52 | handleInputChange(e) { 53 | this.setState({ 54 | text: e.target.value 55 | }) 56 | } 57 | 58 | handleSubmit(e) { 59 | if (e.keyCode !== 13)return 60 | if (this.state.text === '')return 61 | 62 | Socket.socket().emit('room', 'bbt', this.state.text) 63 | this.setState({ 64 | text: '' 65 | }) 66 | } 67 | 68 | componentDidMount() { 69 | Socket.socket().emit('me', this.state.name, {info: null}) 70 | Socket.socket().emit('join', 'bbt') 71 | 72 | let $dom = $('#main-chat-content') 73 | $('#main-chat-content').height($(document).height() - 82) 74 | } 75 | 76 | render() { 77 | let Messages = this.state.messages.map((item, index)=> { 78 | if (item.name === this.state.name) { 79 | return 83 | } else { 84 | return 88 | } 89 | }) 90 | 91 | return ( 92 |
    93 | 94 | 95 |
    {Messages}
    97 | 98 | 102 | 103 | 104 | 106 |
    107 | ) 108 | } 109 | } 110 | --------------------------------------------------------------------------------