diff --git a/src/app.config.js b/src/app.config.js index 9453080..e1538b6 100644 --- a/src/app.config.js +++ b/src/app.config.js @@ -1,8 +1,8 @@ export default { pages: [ + 'pages/lobby/lobby', 'pages/index/index', 'pages/login/login', - 'pages/lobby/lobby', 'pages/new_table/new_table', 'pages/table/table', ], diff --git a/src/assets/coin-1.png b/src/assets/coin-1.png new file mode 100644 index 0000000..8ae57c6 Binary files /dev/null and b/src/assets/coin-1.png differ diff --git a/src/assets/icon/close-1.svg b/src/assets/icon/close-1.svg new file mode 100644 index 0000000..146d5d6 --- /dev/null +++ b/src/assets/icon/close-1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icon/left-1.svg b/src/assets/icon/left-1.svg new file mode 100644 index 0000000..e3417af --- /dev/null +++ b/src/assets/icon/left-1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icon/user-2.svg b/src/assets/icon/user-2.svg new file mode 100644 index 0000000..c6c2b1f --- /dev/null +++ b/src/assets/icon/user-2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/tab-question.svg b/src/assets/tab-question.svg new file mode 100644 index 0000000..ef5ae14 --- /dev/null +++ b/src/assets/tab-question.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/tab-x.svg b/src/assets/tab-x.svg new file mode 100644 index 0000000..dfc3014 --- /dev/null +++ b/src/assets/tab-x.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/style/title.scss b/src/components/style/title.scss index d38fc40..9b50459 100644 --- a/src/components/style/title.scss +++ b/src/components/style/title.scss @@ -1,46 +1,56 @@ -.page-top{ +.page-top { + width: 100%; + position: fixed; + z-index: 9999; + top: 0; + left: 0; + box-shadow: 0px 4px 10px rgba($color: #000000, $alpha: 0.3); + + .topHeight { width: 100%; - position: fixed; - z-index: 9999; - top: 0; - left: 0; - .topHeight{ - width: 100%; - height: 88px; + height: 46px; + } + + .page-title { + padding: 0 32px; + height: 46px; + display: flex; + justify-content: space-between; + align-items: center; + font-weight: bold; + + .icon { + width: 34px; + height: 30px; + // font-size: 40px; + } + + .title { + font-size: 18px; + color: #ffffff; } - .page-title{ - padding: 0 32px; - height: 88px; - display: flex; - justify-content: space-between; - align-items: center; - font-weight: bold; - .icon{ - width: 40px; - height: 40px; - font-size: 40px; - } - .title{ - font-size: 34px; - color: #ffffff; - } - .title1{ - font-size: 34px; - color: #000000; - } - .blank{ - width: 48px; - height: 48px; - } + + .avatar { + width: 41px; + height: 41px; + border-radius: 50%; + margin-top: 2px; + } + + .blank { + width: 48px; + height: 48px; } + } } -.hidden{ - height: 88px; //176px; - width: 100%; - opacity: 0; - // background: pink; + +.hidden { + height: 46px; //176px; + width: 100%; + opacity: 0; + // background: pink; } -.bgc{ - background-color: #fff; +.bgc { + background-color: #fff; } diff --git a/src/components/title.jsx b/src/components/title.jsx index ca1d347..31d181f 100644 --- a/src/components/title.jsx +++ b/src/components/title.jsx @@ -1,23 +1,23 @@ import React from 'react' -import { View } from '@tarojs/components' +import { View, Text, Image } from '@tarojs/components' // import { AtIcon } from 'taro-ui' import { Icon } from '@nutui/nutui-react-taro'; import { navigateBack } from '@/utils/application' +import left from '@/assets/icon/left-1.svg' import './style/title.scss' +import { useSelector } from 'react-redux' + function Title(props) { + const {username, nickname, avatar} = useSelector(state => state.user); return ( {/* */} - { - props.nullBank ? - : - navigateBack()} className='icon' name='rect-left' color={props.colorStyle ? "#ffffff" : "#000000"} /> - } - {props.title} - + navigateBack()} /> + {props.title} + {props.topNull ? '' : } diff --git a/src/pages/lobby/lobby.jsx b/src/pages/lobby/lobby.jsx index 6d9eb5a..ad7a9df 100644 --- a/src/pages/lobby/lobby.jsx +++ b/src/pages/lobby/lobby.jsx @@ -1,5 +1,6 @@ import React, { Component, useState } from 'react' -import { View, Text, Button } from '@tarojs/components' +import { View, Text, Button, Image } from '@tarojs/components' +import Taro from '@tarojs/taro' import { useSelector, useDispatch } from 'react-redux' @@ -7,34 +8,97 @@ import './lobby.scss' import { increment } from '@/store/index' import { fetchOpMap } from '@/api/api' import Title from '@/components/title' - -// class Lobby extends Component { -// constructor(props) { -// super(props) -// console.log('lobby', props) -// } -// render() { -// return ( -// -// Lobby!! -// -// -// ) -// } -// } +import coin1 from '@/assets/coin-1.png' +import tabQuestion from '@/assets/tab-question.svg' +import tabX from '@/assets/tab-x.svg' function Lobby() { const count = useSelector((state) => state.counter.value) + const user = useSelector((state) => state.user) + console.log(user) const dispatch = useDispatch() fetchOpMap() .then(res => { console.log(res) }) .catch(err => console.log(err)) + const avatar = "https://img0.baidu.com/it/u=2477829979,2171947490&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500"; + + const circleEle = [1,2,3,4,5,6,7]; + const circleElePos = [{x:16,y:8},{x:70,y:-3},{x:110,y:28},{x:115,y:70},{x:80,y:105},{x:20,y:100},{x:-2,y:60}]; + return ( - - <Text>Lobby!! {count}</Text> - <Button type="primary" onClick={() => dispatch(increment())}>increment</Button> + <Title title={"Lobby!!" + count} bgColor={true} /> + <View className="celling"></View> + <View className="tab"> + <View className="tab-wrap"> + <View className="circle-wrap"> + <View className="circle-inner"><Image className="inner-coin" src={coin1} /></View> + { + circleEle.map((_, idx) => ( + <View key={idx} className="circle-item" style={{ + position: 'absolute', + left: Taro.pxTransform(circleElePos[idx].x), + top: Taro.pxTransform(circleElePos[idx].y) + }}> + <Image className="circle-avatar" src={idx === 5 ? tabQuestion : idx === 6 ? tabX : avatar} /> + </View> + )) + } + </View> + <View className="tab-no-wrap"> + <View className="tab-no">#10013</View> + <View className="tab-sc">5/7</View> + </View> + </View> + + <View className="tab-wrap"> + <View className="circle-wrap"> + <View className="circle-inner"><Image className="inner-coin" src={coin1} /></View> + { + circleEle.map((_, idx) => ( + <View key={idx} className="circle-item" style={{ + position: 'absolute', + left: Taro.pxTransform(circleElePos[idx].x), + top: Taro.pxTransform(circleElePos[idx].y) + }}> + <Image className="circle-avatar" src={idx === 5 ? tabQuestion : idx === 6 ? tabX : avatar} /> + </View> + )) + } + </View> + <View className="tab-no-wrap"> + <View className="tab-no">#10013</View> + <View className="tab-sc">5/7</View> + </View> + </View> + + <View className="tab-wrap"> + <View className="circle-wrap"> + <View className="circle-inner"><Image className="inner-coin" src={coin1} /></View> + { + circleEle.map((_, idx) => ( + <View key={idx} className="circle-item" style={{ + position: 'absolute', + left: Taro.pxTransform(circleElePos[idx].x), + top: Taro.pxTransform(circleElePos[idx].y) + }}> + <Image className="circle-avatar" src={idx === 5 ? tabQuestion : idx === 6 ? tabX : avatar} /> + </View> + )) + } + </View> + <View className="tab-no-wrap"> + <View className="tab-no">#10013</View> + <View className="tab-sc">5/7</View> + </View> + </View> + + <View className="tab-wrap"></View> + </View> + <View className="bottom-btn-wrap"> + <Button className="bottom-btn" onClick={() => dispatch(increment())}>Create New Table</Button> + </View> </View> ) } diff --git a/src/pages/lobby/lobby.scss b/src/pages/lobby/lobby.scss index e69de29..5767053 100644 --- a/src/pages/lobby/lobby.scss +++ b/src/pages/lobby/lobby.scss @@ -0,0 +1,80 @@ + +.celling { + height: 43px; +} +.tab { + // padding: 0 0 0 21px; + display: flex; + justify-content: space-evenly; + flex-wrap:wrap; + + .tab-wrap { + width: 150px; + margin: 20px 10px; + } + .circle-wrap { + height: 140px; + width: 140px; + // background-color: yellowgreen; + border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; + position: relative; + } + .circle-inner { + + } + .inner-coin { + height: 80px; + width: 80px; + border-radius: 50%; + } + .circle-avatar { + height: 29px; + width: 29px; + border-radius: 50%; + } + +} +.bottom-btn-wrap { + position: fixed; + bottom: 0; + width: 100%; + height: 80px; + background-color: #E8E8E8; + display: flex; + justify-content: center; + align-items: center; +} + +.bottom-btn { + width: 360px; + background-color: #EE914E; + border-radius: 16px; + text-align: center; + height: 42px; + color: #fff; + font-size: 18px; +} + +.tab-no-wrap { + display: flex; + justify-content: center; +} + +.tab-no,.tab-sc { + width: 71px; + height: 20px; + background-color: #EE914E; + border-radius: 16px; + font-size: 12px; + color: #FFF; + text-align: center; + line-height: 20px; +} + +.tab-sc { + width: 57px; + margin-left: 5px; +} diff --git a/src/pages/login/login.jsx b/src/pages/login/login.jsx index e8589a3..5f8a367 100644 --- a/src/pages/login/login.jsx +++ b/src/pages/login/login.jsx @@ -1,5 +1,5 @@ import React, { Component, useState } from 'react' -import { View, Text, Input, Image, Button } from '@tarojs/components' +import { View, Text, Input, Image, Button, Label } from '@tarojs/components' import Taro from '@tarojs/taro'; //import { Progress } from '@nutui/nutui-react-taro'; //import { Form, Input, TextArea, Cell, Button, Row, Col, Image } from '@nutui/nutui-react-taro'; @@ -8,6 +8,7 @@ import './login.scss' import { fetchOpMap } from '@/api/api' import iconUser from '@/assets/icon/user-3-fill.svg' import iconLock from '@/assets/icon/lock-2-fill.svg' +import abIcon from '@/assets/icon/a-b.svg' /* 登录 -> 大厅 -> 新桌面 -> 进桌面 -> profile(弹窗) @@ -25,9 +26,9 @@ function Login(props, ref) { password: '', captcha: '', }); - const [capatcha, setCapatcha] = useState({ - origin: "http://localhost:9999/api/auth/captcha", - src: "http://localhost:9999/api/auth/captcha", + const [captcha, setCaptcha] = useState({ + origin: "/api/auth/captcha", // http://localhost:9999 + src: "/api/auth/captcha", }) const usernameChange = (username, e) => { if (!e) return; @@ -60,19 +61,26 @@ function Login(props, ref) { <View className='title-line'><Text className='title-2'>Easily add new account or login the current one.</Text></View> {/* <Progress percentage="33" /> */} <View className='input-wrap'> - <Image className='input-icon' src={iconUser} /> - <Input className="input-1" name="username" type="text" defaultValue={state.username} placeholder="account" leftIcon="dongdong" + <Label for="username"><Image className='input-icon' src={iconUser} /></Label> + <Input className="input-1" id="username" name="username" type="text" defaultValue={state.username} placeholder="account" leftIcon="dongdong" onChange={usernameChange}/> </View> <View className='input-wrap'> <Image className='input-icon' src={iconLock} /> - <Input className='input-1' name="password" type="password" defaultValue={state.password} placeholder="password" + <Input className='input-1' name="password" type="password" password={true} defaultValue={state.password} placeholder="password" onChange={passwordChange}/> </View> - <View > - <Image src={capatcha.src} width="107" height="36" onClick={() => setCapatcha({...capatcha, src: capatcha.origin + '?t=' + Math.random()})} /> + <View className='input-wrap'> + <Image className='input-icon' src={abIcon} /> + <Input className='input-2' name="captcha" type="text" defaultValue={state.password} placeholder="captcha" + onChange={() => {}}/> + <Image className='captcha' src={captcha.src} width="107" height="36" + onClick={() => setCaptcha({...captcha, src: captcha.origin + '?t=' + Math.random()})} /> </View> <View> + <Button className='submit-btn'>START</Button> + </View> + <View style={{display: 'none'}}> <Button type="primary" style={{width: '160px'}} onClick={handleSubmit}>提交</Button> <Button type="primary" style={{width: '160px'}} onClick={() => {Taro.navigateTo({url:'/pages/lobby/lobby'})}}>跳转</Button> </View> diff --git a/src/pages/login/login.scss b/src/pages/login/login.scss index d48ae83..b9ea91b 100644 --- a/src/pages/login/login.scss +++ b/src/pages/login/login.scss @@ -1,42 +1,75 @@ .login { - height: 100vh; - background-color:#fff; - - .ceiling { - height: 75px; - } - .title-line { - padding: 6px 39px; - } - .title-1 { - font-size: 36px; - color: #EE914E; - font-weight: bold; - } - .title-2 { - font-size: 14px; - } - - .input-wrap { - display: flex; - justify-content: center; - // align-items: center; - margin: 37.5px 0; - } - .input-icon { - margin-right: 16px; - height: 36px; - width: 36px; - padding: 4px 0; - } - .input-1 { - box-sizing: border-box; - width: 307px; - height: 42px; - border-radius: 16px; - border: 1px solid #000; - font-size: 18px; - padding: 5px 20px; - box-shadow: 0px 4px 10px rgba($color: #000000, $alpha: 0.3); - } -} \ No newline at end of file + height: 100vh; + background-color: #fff; + + .ceiling { + height: 75px; + } + + .title-line { + //padding: 6px 39px; + width: 359px; + margin: 0 auto; + } + + .title-1 { + font-size: 36px; + color: #EE914E; + font-weight: bold; + } + + .title-2 { + font-size: 14px; + } + + .input-wrap { + display: flex; + justify-content: center; + // align-items: center; + margin: 37.5px 0; + } + + .input-icon { + margin-right: 16px; + height: 36px; + width: 36px; + padding: 4px 0; + } + + .input-1, + .input-2, + .captcha { + box-sizing: border-box; + width: 307px; + height: 42px; + border-radius: 16px; + border: 1px solid #000; + font-size: 18px; + padding: 5px 20px; + box-shadow: 0px 4px 10px rgba($color: #000000, $alpha: 0.3); + } + + .input-2 { + width: 165px; + } + + .captcha { + width: 125px; + box-shadow: none; + padding: 0 0; + margin-left: 14px; + } + + .submit-btn { + width: 360px; + height: 42px; + border-radius: 16px; + box-shadow: 0px 4px 10px rgba($color: #000000, $alpha: 0.3); + background-color: #EE914E; + color: #fff; + font-size: 16px; + text-align: center; + line-height: 42px; + font-weight: bold; + } +} diff --git a/src/pages/new_table/new_table.jsx b/src/pages/new_table/new_table.jsx index 80ebc47..78c9f51 100644 --- a/src/pages/new_table/new_table.jsx +++ b/src/pages/new_table/new_table.jsx @@ -1,15 +1,59 @@ import React, { Component, useState } from 'react' -import {View, Text} from '@tarojs/components' +import { View, Text, Image, Button } from '@tarojs/components' +import { useSelector } from 'react-redux' import './new_table.scss' +import Title from '@/components/title' +import userIcon from '@/assets/icon/user-2.svg' +import closeIcon from '@/assets/icon/close-1.svg' function NewTable() { + const {username, nickname, avatar} = useSelector(state => state.user); - return ( + const players = [1,2,3,4,5,6]; + const playerRows = players.reduce((arr, item, idx) => { + const row = parseInt(idx / 2); + let rowArr = arr[row] || []; + rowArr[idx % 2] = {index: idx, item}; + arr[row] = rowArr; + parseInt() + return arr; + }, []); + + return ( + <View className="nt"> + <Title title={"Create New Table"} /> + <View className="nt-wrap"> + { + playerRows.map((row, i) => ( + <View key={i} className="playerRow"> + { + row.map((player, j) => ( + <View key={j} className="player-wrap"> + <View className="player-icon"><Image className="player-icon-img" src={userIcon} /></View> + <View className="close-icon"><Image className="close-icon-img" src={closeIcon} /></View> + <View className="player"> + <Text className="player-name">Player{player.item}</Text> + </View> + </View> + )) + } + </View> + )) + } + + <View className="self-wrap"> + <View className="self"> + <View className="avatar-wrap"><Image className="avatar" src={avatar} /></View> + <View className="nickname"><Text>{nickname}</Text></View> + </View> + </View> <View> - <Text>创建新桌面NewTable!!</Text> + <Button>CREATE</Button> </View> - ) + </View> + </View> + ) } -export default NewTable \ No newline at end of file +export default NewTable diff --git a/src/pages/new_table/new_table.scss b/src/pages/new_table/new_table.scss index e69de29..7219fbf 100644 --- a/src/pages/new_table/new_table.scss +++ b/src/pages/new_table/new_table.scss @@ -0,0 +1,70 @@ +.nt { + .nt-wrap { + padding: 0 11px 0 11px; + } + .playerRow { + display: flex; + justify-content: space-between; + // align-content: space-around; + flex-flow: row wrap; + width: 405px; + margin: 46px auto 0 auto; + } + .player-wrap { + // flex: 0 0 50%; + position: relative; + } + .player { + width: 159px; + height: 101px; + background-color: #EE914E; + text-align: center; + line-height: 101px; + } + .player-icon { + height: 50px; + width: 50px; + background-color: #EE914E; + position: absolute; + top: -14px; + } + .player-icon-img { + width: 30px; + height: 30px; + padding: 10px; + } + .close-icon { + position: absolute; + top: 8px; + left: 127px; + } + .close-icon-img { + width: 24px; + height: 24px; + } + .player-name { + font-size: 26px; + color: #fff; + font-weight: bold; + } + + .self-wrap { + margin-top: 38px; + display: flex; + justify-content: center; + } + .self { + width: 405px; + height: 83px; + background-color: #EE914E; + } + + .avatar-wrap { + + } + .avatar { + margin: 9px 0 0 9px; + width: 66px; + height: 66px; + } +} diff --git a/src/store/index.js b/src/store/index.js index db06460..95661d3 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1,6 +1,7 @@ -import { configureStore, combineReducers, createSlice } from '@reduxjs/toolkit' +import { configureStore, createSlice } from '@reduxjs/toolkit' import connSlice from '@/store/conn' +import userSlice from '@/store/user' const counterSlice = createSlice({ name: 'counter', @@ -20,6 +21,7 @@ const store = configureStore({ reducer: { counter: counterSlice.reducer, conn: connSlice.reducer, + user: userSlice.reducer, } }) diff --git a/src/store/user.js b/src/store/user.js new file mode 100644 index 0000000..26350f0 --- /dev/null +++ b/src/store/user.js @@ -0,0 +1,19 @@ +import { createSlice } from '@reduxjs/toolkit'; + +const userSlice = createSlice({ + name: 'user', + initialState: { + username: 'Prometheus', + nickname: 'PrometheusNick', + avatar: 'https://img0.baidu.com/it/u=2477829979,2171947490&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500', + }, + reducers: { + setUserInfo(state, action) { + return {...state, ...action.payload} + } + } +}) + +export default userSlice + +export const { setUserInfo } = userSlice.actions