mirror of
https://github.com/mgerb/classic-wow-forums
synced 2026-01-11 17:42:48 +00:00
client - user account page done
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
transition: all 0.1s ease-in-out;
|
||||
top: 0;
|
||||
|
||||
&:hover, &__selected {
|
||||
&:hover, &--selected {
|
||||
top: -1px;
|
||||
box-shadow: 0 0 10px #00C0FF;
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import { RouteComponentProps } from 'react-router-dom';
|
||||
import { get, groupBy, map } from 'lodash';
|
||||
import { ContentContainer, Portrait, ScrollToTop } from '../../components';
|
||||
import { UserStore } from '../../stores/user-store';
|
||||
import { UserService } from '../../services';
|
||||
import { AvatarList, CharacterModel } from '../../model';
|
||||
import { CharacterService, UserService } from '../../services';
|
||||
import { CharacterModel } from '../../model';
|
||||
import './user-account.scss';
|
||||
|
||||
interface Props extends RouteComponentProps<any> {
|
||||
@@ -16,6 +16,9 @@ interface State {
|
||||
characters: {[realm: string]: CharacterModel[]};
|
||||
selectedRealm?: string;
|
||||
selectedCharIndex: number;
|
||||
selectedAvatarIndex: number;
|
||||
insufficientScope?: boolean;
|
||||
noCharacters: boolean;
|
||||
}
|
||||
|
||||
@inject('userStore')
|
||||
@@ -25,7 +28,9 @@ export class UserAccount extends React.Component<Props, State> {
|
||||
super(props);
|
||||
this.state = {
|
||||
characters: {},
|
||||
noCharacters: false,
|
||||
selectedCharIndex: 0,
|
||||
selectedAvatarIndex: 0,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -42,22 +47,43 @@ export class UserAccount extends React.Component<Props, State> {
|
||||
async getCharacters() {
|
||||
try {
|
||||
const res = await UserService.getCharacters() as any;
|
||||
const characters = groupBy(res, 'realm');
|
||||
this.setState({
|
||||
characters,
|
||||
selectedRealm: res[0].realm,
|
||||
});
|
||||
if (res.characters) {
|
||||
if (res.characters.length === 0) {
|
||||
this.setState({ noCharacters: true });
|
||||
return;
|
||||
}
|
||||
// remove classes that weren't in vanilla
|
||||
const characters = groupBy(res.characters, 'realm');
|
||||
this.setState({
|
||||
characters,
|
||||
selectedRealm: res.characters[0].realm,
|
||||
insufficientScope: false,
|
||||
});
|
||||
} else {
|
||||
this.setState({ insufficientScope: true });
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
onRealmSelect(event: any) {
|
||||
this.setState({ selectedRealm: event.target.value, selectedCharIndex: 0 });
|
||||
this.setState({
|
||||
selectedRealm: event.target.value,
|
||||
selectedCharIndex: 0,
|
||||
selectedAvatarIndex: 0,
|
||||
});
|
||||
}
|
||||
|
||||
onCharSelect(event: any) {
|
||||
this.setState({ selectedCharIndex: event.target.value as any });
|
||||
this.setState({
|
||||
selectedCharIndex: event.target.value as any,
|
||||
selectedAvatarIndex: 0,
|
||||
});
|
||||
}
|
||||
|
||||
onAvatarSelect(selectedAvatarIndex: number) {
|
||||
this.setState({ selectedAvatarIndex });
|
||||
}
|
||||
|
||||
renderDropDowns() {
|
||||
@@ -65,24 +91,29 @@ export class UserAccount extends React.Component<Props, State> {
|
||||
return <div></div>;
|
||||
}
|
||||
return (
|
||||
<div style={{ marginBottom: '10px' }}>
|
||||
<select value={this.selectedCharacter().realm}
|
||||
onChange={event => this.onRealmSelect(event)}>
|
||||
{map(this.state.characters, (_, realm: string) => {
|
||||
return <option key={`realm${realm}`}>{realm}</option>;
|
||||
})}
|
||||
</select>
|
||||
<select style={{ marginLeft: '5px' }}
|
||||
onChange={event => this.onCharSelect(event)}>
|
||||
{map(this.state.characters[this.state.selectedRealm!], (value, index) => {
|
||||
return <option key={this.state.selectedRealm! + index} value={index}>{value.name}</option>;
|
||||
})}
|
||||
</select>
|
||||
<div>
|
||||
<h2>Set your default character</h2>
|
||||
<div style={{ margin: '0 10px 10px 0', display: 'inline-block' }}>
|
||||
<select value={this.selectedCharacter().realm}
|
||||
onChange={event => this.onRealmSelect(event)}>
|
||||
{map(this.state.characters, (_, realm: string) => {
|
||||
return <option key={`realm${realm}`}>{realm}</option>;
|
||||
})}
|
||||
</select>
|
||||
<select style={{ marginLeft: '5px' }}
|
||||
onChange={event => this.onCharSelect(event)}>
|
||||
{map(this.state.characters[this.state.selectedRealm!], (value, index) => {
|
||||
return <option key={this.state.selectedRealm! + index} value={index}>{value.name}</option>;
|
||||
})}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<a onClick={() => this.onSave()}>Save</a>
|
||||
<div className="avatar-list">
|
||||
{AvatarList.map((val, index) => {
|
||||
{this.selectedCharacter().avatarList!.map((val, index) => {
|
||||
const avatarClass = this.state.selectedAvatarIndex === index ? 'avatar-list__item--selected' : '';
|
||||
return (
|
||||
<div key={index} className="avatar-list__item">
|
||||
<div key={index} className={`avatar-list__item ${avatarClass}`} onClick={() => this.onAvatarSelect(index)}>
|
||||
<img src={val.imageSrc}/>
|
||||
</div>
|
||||
);
|
||||
@@ -94,25 +125,61 @@ export class UserAccount extends React.Component<Props, State> {
|
||||
|
||||
private async onSave() {
|
||||
const { name, guild, realm } = this.selectedCharacter();
|
||||
const selectedAvatar = this.selectedCharacter().avatarList![this.state.selectedAvatarIndex].title;
|
||||
const charClass = CharacterService.getClass(this.selectedCharacter().class);
|
||||
const data = {
|
||||
character_name: name,
|
||||
character_class: 'Rogue', // todo get class from number
|
||||
character_class: charClass.name,
|
||||
character_guild: guild,
|
||||
character_realm: realm,
|
||||
character_avatar: 'Avatar', // TODO:
|
||||
character_avatar: selectedAvatar,
|
||||
};
|
||||
|
||||
await UserService.saveCharacter(data);
|
||||
}
|
||||
|
||||
private logout() {
|
||||
this.props.userStore!.resetUser();
|
||||
window.location.pathname = '/';
|
||||
}
|
||||
|
||||
private renderScopeError() {
|
||||
return (
|
||||
<div>
|
||||
<p>
|
||||
To set your default character
|
||||
we need access to your WoW profile.
|
||||
</p>
|
||||
<ul>
|
||||
<li><a href="https://us.battle.net/account/management/authorizations.html"
|
||||
target="_blank">Navigate to your Battle.net Authorized Applications</a></li>
|
||||
<li>Remove Classic WoW Forums</li>
|
||||
<li>Log out and back into Classic WoW Forums</li>
|
||||
<li>Grant Classic WoW Forums access to your WoW profile</li>
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { battletag, character_name, character_class, character_guild, character_realm } = this.props.userStore!.user!;
|
||||
|
||||
if (this.state.noCharacters) {
|
||||
return <div>You have no WoW characters in your account.</div>;
|
||||
}
|
||||
|
||||
// user must be logged in to view this page
|
||||
if (!this.props.userStore!.user) {
|
||||
return <div></div>;
|
||||
}
|
||||
|
||||
const { battletag, character_name, character_class, character_guild, character_realm, character_avatar } = this.props.userStore!.user!;
|
||||
const { insufficientScope } = this.state;
|
||||
|
||||
return (
|
||||
<ScrollToTop>
|
||||
<ContentContainer style={{ minHeight: '500px' }}>
|
||||
<ContentContainer style={{ minHeight: '500px', paddingTop: '40px' }}>
|
||||
<div className="flex">
|
||||
<Portrait imageSrc={require('../../assets/Tyren.gif')}/>
|
||||
{character_avatar && <Portrait imageSrc={CharacterService.getAvatar(character_avatar!)}/>}
|
||||
<div style={{ paddingLeft: '10px' }}>
|
||||
{battletag && <div><b>Battletag: </b>{battletag}</div>}
|
||||
{character_name && <div><b>Character: </b>{character_name}</div>}
|
||||
@@ -120,12 +187,13 @@ export class UserAccount extends React.Component<Props, State> {
|
||||
{character_guild && <div><b>Guild: </b>{character_guild}</div>}
|
||||
{character_realm && <div><b>Realm: </b>{character_realm}</div>}
|
||||
</div>
|
||||
<div className="flex-1" style={{ textAlign: 'right' }}>
|
||||
<a onClick={() => this.logout()}>Logout</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2>Set a new default character</h2>
|
||||
{this.renderDropDowns()}
|
||||
<a onClick={() => this.onSave()}>Save</a>
|
||||
{insufficientScope === true ? this.renderScopeError() : this.renderDropDowns()}
|
||||
</div>
|
||||
|
||||
</ContentContainer>
|
||||
|
||||
Reference in New Issue
Block a user