Add settings page.

This commit is contained in:
Yang Luo 2020-06-07 23:55:20 +08:00
parent 1f28297ca4
commit fa64e4ca6d
4 changed files with 185 additions and 13 deletions

View File

@ -15,19 +15,22 @@
package object
type Member struct {
Id string `xorm:"varchar(100) notnull pk" json:"id"`
No int `json:"no"`
CreatedTime string `xorm:"varchar(100)" json:"createdTime"`
Tagline string `xorm:"varchar(100)" json:"tagline"`
Company string `xorm:"varchar(100)" json:"company"`
CompanyTitle string `xorm:"varchar(100)" json:"companyTitle"`
Ranking int `json:"ranking"`
GoldCount int `json:"goldCount"`
SilverCount int `json:"silverCount"`
BronzeCount int `json:"bronzeCount"`
Bio string `xorm:"varchar(100)" json:"bio"`
Website string `xorm:"varchar(100)" json:"website"`
Location string `xorm:"varchar(100)" json:"location"`
Id string `xorm:"varchar(100) notnull pk" json:"id"`
No int `json:"no"`
CreatedTime string `xorm:"varchar(100)" json:"createdTime"`
Phone string `xorm:"varchar(100)" json:"phone"`
Email string `xorm:"varchar(100)" json:"email"`
EmailVerifiedTime string `xorm:"varchar(100)" json:"emailVerifiedTime"`
Tagline string `xorm:"varchar(100)" json:"tagline"`
Company string `xorm:"varchar(100)" json:"company"`
CompanyTitle string `xorm:"varchar(100)" json:"companyTitle"`
Ranking int `json:"ranking"`
GoldCount int `json:"goldCount"`
SilverCount int `json:"silverCount"`
BronzeCount int `json:"bronzeCount"`
Bio string `xorm:"varchar(100)" json:"bio"`
Website string `xorm:"varchar(100)" json:"website"`
Location string `xorm:"varchar(100)" json:"location"`
}
func GetMembers() []*Member {

View File

@ -29,6 +29,7 @@ import SigninBox from "./main/SigninBox";
import TopicBox from "./main/TopicBox";
import ReplyBox from "./main/ReplyBox";
import MemberBox from "./main/MemberBox";
import SettingsBox from "./main/SettingsBox";
class App extends Component {
constructor(props) {
@ -86,6 +87,12 @@ class App extends Component {
<MemberBox />
</div>
}/>
<Route exact path="/settings" component={() =>
<div id="Main">
<div className="sep20" />
<SettingsBox />
</div>
}/>
</Switch>
)
}

View File

@ -24,6 +24,12 @@ class Avatar extends React.Component {
}
render() {
if (this.props.size === "small") {
return (
<img src={Setting.getUserAvatar(this.props.username)} className="avatar" border="0" align="default" style={{"maxWidth": "24px", "maxHeight": "24px"}} alt={this.props.username} />
)
}
return (
<a href={`/member/${this.props.username}`}>
<img src={Setting.getUserAvatar(this.props.username, this.props.isLarge)} className="avatar" border="0" align="default" alt={this.props.username} />

156
web/src/main/SettingsBox.js Normal file
View File

@ -0,0 +1,156 @@
// Copyright 2020 The casbin Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import React from "react";
import * as Setting from "../Setting";
import Header from "./Header";
import Avatar from "../Avatar";
import * as MemberBackend from "../backend/MemberBackend";
class SettingsBox extends React.Component {
constructor(props) {
super(props);
this.state = {
classes: props,
memberId: "alice",
member: null,
};
}
componentDidMount() {
this.getMember();
}
getMember() {
MemberBackend.getMember(this.state.memberId)
.then((res) => {
this.setState({
member: res,
});
});
}
render() {
return (
<div className="box">
<Header item="Settings" />
<div className="inner" data-select2-id="11">
<form method="post" action="/settings" data-select2-id="10">
<table cellPadding="5" cellSpacing="0" border="0" width="100%" data-select2-id="9">
<tbody data-select2-id="8">
<tr>
<td width="120" align="right">
<Avatar username={this.state.member?.id} size="small" />
</td>
<td width="auto" align="left">
{Setting.getForumName()} No. {this.state.member?.no} member
</td>
</tr>
<tr>
<td width="120" align="right">
Username
</td>
<td width="auto" align="left">
{this.state.member?.id}
</td>
</tr>
<tr>
<td width="120" align="right">
Phone
</td>
<td width="auto" align="left">
<code>
{this.state.member?.phone}
</code>
</td>
</tr>
<tr>
<td width="120" align="right" />
<td width="auto" align="left">
<a href="/settings/phone">
Modify phone
</a>
</td>
</tr>
<tr>
<td width="120" align="right">
Email
</td>
<td width="auto" align="left">
<code>
{this.state.member?.email}
</code>
</td>
</tr>
<tr>
<td width="120" align="right" />
<td width="auto" align="left">
<a href="/settings/email">
Modify Email
</a>
</td>
</tr>
<tr>
<td width="120" align="right">
Email Verification
</td>
<td width="auto" align="left">
<span className="green">
Verified on {Setting.getFormattedDate(this.state.member?.emailVerifiedTime)}
</span>
</td>
</tr>
<tr>
<td width="120" align="right">
Website
</td>
<td width="auto" align="left">
<input type="text" className="sl" name="website" value={this.state.member?.website} autoComplete="off" />
</td>
</tr>
<tr>
<td width="120" align="right">
Company
</td>
<td width="auto" align="left">
<input type="text" className="sl" name="company" value={this.state.member?.company} maxLength="32" autoComplete="off" />
</td>
</tr>
<tr>
<td width="120" align="right">
Bio
</td>
<td width="auto" align="left">
<textarea className="ml" name="bio">
{this.state.member?.bio}
</textarea>
</td>
</tr>
<tr>
<td width="120" align="right" />
<td width="auto" align="left">
<input type="hidden" value="26304" name="once" />
<input type="submit" className="super normal button" value="Save Settings" />
</td>
</tr>
</tbody>
</table>
</form>
</div>
</div>
);
}
}
export default SettingsBox;