1
0
mirror of https://github.com/mgerb/classic-wow-forums synced 2026-01-10 09:02:50 +00:00

client - forum nav should be working

This commit is contained in:
2018-01-13 19:44:23 -06:00
parent 58b913f5b8
commit 269c8a2f50
13 changed files with 213 additions and 59 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@@ -1,6 +1,15 @@
.forum-nav {
display: inline-block;
display: flex;
flex-direction: column;
padding-left: 5px;
position: relative;
bottom: 10;
background-image: url('../../assets/forum-nav-header-bg.gif');
background-repeat: no-repeat;
height: 51px;
width: 300px;
overflow: hidden;
&__title {
height: 27px;
line-height: 27px;
}
}

View File

@@ -1,20 +1,125 @@
import React from 'react';
import { get, find, reject } from 'lodash';
import { RouteComponentProps } from 'react-router-dom';
import { CategoryService } from '../../services';
import { CategoryModel } from '../../model';
import './forum-nav.scss';
interface Props {}
interface Props extends RouteComponentProps<any> {
categoryId: number;
}
interface State {}
interface State {
categoryList: CategoryModel[];
selectedCategory?: CategoryModel;
}
export class ForumNav extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
categoryList: [],
};
}
async componentDidMount() {
const categoryList = await CategoryService.getCategories();
this.setState({ categoryList });
this.setSelectedCategory(categoryList, this.props.categoryId!);
}
componentWillReceiveProps(nextProps: Props) {
if (this.props.categoryId !== nextProps.categoryId) {
this.setSelectedCategory(this.state.categoryList, nextProps.categoryId!);
}
}
setSelectedCategory(categoryList: CategoryModel[], categoryId: number) {
const selectedCategory = find(categoryList, { id: categoryId });
this.setState({ selectedCategory });
}
getImageSrc(): string {
if (this.state.selectedCategory!.category === 'realm') {
return topicIcons['Realm Forums'];
}
return topicIcons[this.state.selectedCategory!.title];
}
renderDropDown() {
let categories: any = reject(this.state.categoryList, { category: 'realm' });
categories = [{ id: -1, title: 'Realm Forums' }, ...categories];
return categories.map((val: any, index: number) => {
return <option key={index} value={val.id}>{val.title}</option>;
});
}
getSelectedCategoryId(): number {
const { selectedCategory } = this.state;
if (!selectedCategory) {
return 0;
}
if (selectedCategory.category === 'realm') {
return -1;
}
return selectedCategory.id;
}
onSelect(event: any) {
const route = event.target.value === '-1' ? '/realms' : `/f/${event.target.value}`;
this.props.history.push(route);
}
render() {
const { selectedCategory } = this.state;
const imageSrc = selectedCategory ? this.getImageSrc() : undefined;
return (
<div>
<img src={require('../../assets/wow-base-general.gif')}/>
<div className="flex">
<img src={imageSrc} />
<div className="forum-nav">
<small>Forum Nav:</small><select style={{ minWidth: '194px' }}></select>
<div className="forum-nav__title">
<b>{get(selectedCategory, 'title')}</b>
</div>
<div className="flex flex--center">
<small>Forum Nav:</small>
<select style={{ minWidth: '194px', height: '19px' }}
value={this.getSelectedCategoryId()}
onChange={event => this.onSelect(event)}>
{this.state.categoryList && this.renderDropDown()}
</select>
</div>
</div>
</div>
);
}
}
const topicIcons: {[key: string]: string} = {
['Bug Report Forum']: require('../../assets/wow-base-bugs.gif'),
['Druid']: require('../../assets/wow-base-druid.gif'),
['Raid and Dungeon Discussion']: require('../../assets/wow-base-dungeons.gif'),
['General Discussion']: require('../../assets/wow-base-general.gif'),
['Hunter']: require('../../assets/wow-base-hunter.gif'),
['Mage']: require('../../assets/wow-base-mage.gif'),
['Off-topic']: require('../../assets/wow-base-offtopic.gif'),
['Paladin']: require('../../assets/wow-base-paladin.gif'),
['Priest']: require('../../assets/wow-base-priest.gif'),
['Professions']: require('../../assets/wow-base-professions.gif'),
['PvP Discussion']: require('../../assets/wow-base-pvp.gif'),
['Quest Discussion']: require('../../assets/wow-base-quests.gif'),
['Realm Forums']: require('../../assets/wow-base-realms.gif'),
['Rogue']: require('../../assets/wow-base-rogue.gif'),
['Shaman']: require('../../assets/wow-base-shaman.gif'),
['Suggestions']: require('../../assets/wow-base-suggestions.gif'),
['Site Suggestions']: require('../../assets/wow-base-support.gif'),
['UI & Macros Forum']: require('../../assets/wow-base-uicustomizations.gif'),
['Warlock']: require('../../assets/wow-base-warlock.gif'),
['Warrior']: require('../../assets/wow-base-warrior.gif'),
['Guild Recruitment']: require('../../assets/wow-base-guild.gif'),
['Role-Playing']: require('../../assets/wow-base-roleplaying.gif'),
};

View File

@@ -35,6 +35,7 @@ export class LoginButton extends React.Component<Props, State> {
</div>
<div style={{ textAlign: 'center' }}>
{!avatarSrc && <p><a onClick={() => this.props.onNavigate('/user-account')}>Account</a></p>}
<div><b>{this.props.userStore!.user!.battletag}</b></div>
<div><b>{this.props.userStore!.user!.character_name}</b></div>
</div>
</div>

View File

@@ -21,18 +21,25 @@ export class Forum extends React.Component<Props, State> {
}
componentDidMount() {
this.getThreads();
this.getThreads(this.props.match.params['id']);
}
private async getThreads() {
const threads = await ThreadService.getCategoryThreads(this.props.match.params['id']);
// update the page if the route params change
componentWillReceiveProps(nextProps: Props) {
if (this.props.match.params !== nextProps.match.params) {
this.getThreads(nextProps.match.params['id']);
}
}
private async getThreads(categoryId: string) {
const threads = await ThreadService.getCategoryThreads(categoryId);
this.setState({ threads });
}
renderHeader() {
return (
<div className="forum-header">
<ForumNav />
<ForumNav categoryId={parseInt(this.props.match.params['id'], 10)} {...this.props}/>
<div style={{ height: '100%' }}>
<LoginButton onNavigate={dest => this.props.history.push(dest)}/>
</div>
@@ -68,11 +75,12 @@ export class Forum extends React.Component<Props, State> {
}
renderThreadRows() {
const categoryId = this.props.match.params['id'];
return this.state.threads.map((thread, index) => {
return (
<div className={`forum-row ${index % 2 === 0 && 'forum-row--dark'}`} key={index}>
{this.renderCell('flag', { maxWidth: '50px' })}
{this.renderCell(<Link to={`/thread/${thread.id}`}>{thread.title}</Link>, { minWidth: '200px' })}
{this.renderCell(<Link to={`/f/${categoryId}/${thread.id}`}>{thread.title}</Link>, { minWidth: '200px' })}
{this.renderCell(<b>{thread.user.battletag}</b>, { maxWidth: '150px' })}
{this.renderCell(<b>{thread.reply_count}</b>, { maxWidth: '150px' }, true)}
{this.renderCell(<b>{thread.view_count}</b>, { maxWidth: '150px' }, true)}
@@ -88,7 +96,7 @@ export class Forum extends React.Component<Props, State> {
<div className="forum-table">
<div className="forum-row forum-row--header">
<div className="forum-cell forum-cell--header flex-1">Test</div>
<div className="forum-cell forum-cell--header flex-1">TODO:</div>
</div>
<div className="forum-row forum-row--header">

View File

@@ -6,7 +6,7 @@ import './home.scss';
import header_forms from '../../assets/header-forums.gif';
import support from '../../assets/support.gif';
import serverstatus from '../../assets/serverstatus.gif';
// import serverstatus from '../../assets/serverstatus.gif';
import uicustomizations from '../../assets/uicustomizations.gif';
import bugs from '../../assets/bugs.gif';
import realms from '../../assets/realms.gif';
@@ -42,23 +42,23 @@ export class Home extends React.Component<Props, State> {
super(props);
}
private renderTopic(link: string, title: string, icon: any, text: string): any {
private renderTopic(topicId: number | string, title: string, icon: any, text: string): any {
return (
<div className="topic-item">
<img className="topic-item-icon" src={icon}/>
<img className="topic-item-icon" src={icon} />
<div>
<Link to={link}>{title}</Link>
<Link to={typeof topicId === 'number' ? `/f/${topicId}` : topicId}>{title}</Link>
<div>{text}</div>
</div>
</div>
);
}
private renderClass(title: string, url: string, icon: any): any {
private renderClass(title: string, topicId: number, icon: any): any {
return (
<div className="flex flex--center" style={{ flex: 1 }}>
<img className="topic-item-icon" src={icon}/>
<a href={url}>{title}</a>
<img className="topic-item-icon" src={icon} />
<Link to={`/f/${topicId}`}>{title}</Link>
</div>
);
}
@@ -67,19 +67,19 @@ export class Home extends React.Component<Props, State> {
return (
<div className="classes-container">
<div className="item-row item-row__class">
{this.renderClass('Druid', '#', druid)}
{this.renderClass('Rogue', '#', rogue)}
{this.renderClass('Priest', '#', priest)}
{this.renderClass('Druid', 0, druid)}
{this.renderClass('Rogue', 1, rogue)}
{this.renderClass('Priest', 2, priest)}
</div>
<div className="item-row item-row__class">
{this.renderClass('Hunter', '#', hunter)}
{this.renderClass('Shaman', '#', shaman)}
{this.renderClass('Warrior', '#', warrior)}
{this.renderClass('Hunter', 3, hunter)}
{this.renderClass('Shaman', 4, shaman)}
{this.renderClass('Warrior', 5, warrior)}
</div>
<div className="item-row item-row__class">
{this.renderClass('Mage', '#', mage)}
{this.renderClass('Paladin', '#', paladin)}
{this.renderClass('Warlock', '#', warlock)}
{this.renderClass('Mage', 6, mage)}
{this.renderClass('Paladin', 7, paladin)}
{this.renderClass('Warlock', 8, warlock)}
</div>
</div>
);
@@ -98,23 +98,36 @@ export class Home extends React.Component<Props, State> {
the World of Warcraft community forums requires a World of Warcraft account. Only customers are allowed to post on these forums,
but anyone can read them. Please note that you must adhere to the Forum Guidelines if you wish to post on the forums.
</p>
<div className="topic-container">
<div className="topic-row">
{this.renderTopic('#', 'Technical Support', support, `If you're experiencing technical problems playing World of Warcraft, post here for assistance.`)}
{this.renderTopic('#', 'Realm Status', serverstatus, `Collection of important messages regarding the status of the Realms.`)}
{this.renderTopic(
137,
'Site Suggestions',
support,
`Have a suggestion for this site? Please post it here.`,
)}
{ /* maybe add realm status in the future */
/* {this.renderTopic(
'#', 'Realm Status', serverstatus,
`Collection of important messages regarding the status of the Realms.`)} */}
</div>
<div className="topic-row">
{this.renderTopic('#', 'UI & Macros Forum', uicustomizations, `Work with other players to create your own special custom interfaces and macros.`)}
{this.renderTopic('#', 'Bug Report Forum', bugs, `Found a bug in the game? Help us squash it by reporting it here!`)}
{this.renderTopic(
138,
'UI & Macros Forum',
uicustomizations,
`Work with other players to create your own special custom interfaces and macros.`,
)}
{this.renderTopic(139, 'Bug Report Forum', bugs, `Found a bug on this site? Help us squash it by reporting it here!`)}
</div>
<hr/>
<hr />
<div className="topic-row topic-row__classes">
<div className="topic-item topic-item__classes">
<div className="flex" style={{ marginBottom: '10px' }}>
<img className="topic-item-icon" src={bullet}/>
<img className="topic-item-icon" src={bullet} />
<div>
<b>Classes</b>
<div>Discuss your favorite class:</div>
@@ -125,50 +138,62 @@ export class Home extends React.Component<Props, State> {
<div className="topic-item topic-item__classes">
<div className="item-row" style={{ minWidth: '250px' }}>
<img className="topic-item-icon" src={professions}/>
<img className="topic-item-icon" src={professions} />
<div>
<a href="#">Professions</a>
<Link to="/f/140">Professions</Link>
<div>Discuss professions in detail.</div>
</div>
</div>
<div className="item-row">
<img className="topic-item-icon" src={pvp}/>
<img className="topic-item-icon" src={pvp} />
<div>
<a href="#">PvP Discussion</a>
<Link to="/f/141">PvP Discussion</Link>
<div>Discuss player versus player combat.</div>
</div>
</div>
<div className="item-row">
<img className="topic-item-icon" src={quests}/>
<img className="topic-item-icon" src={quests} />
<div>
<a href="#">Quest Discussion</a>
<Link to="/f/142">Quest Discussion</Link>
<div>Talk about and get help with the countless quests in World of Warcraft.</div>
</div>
</div>
</div>
</div>
<div className="topic-row">
{this.renderTopic('/realms', 'Realm Forums', realms, `Discuss topics related to World of Warcraft with players on your specific Realm.`)}
{this.renderTopic('#', 'Off-topic', offtopic, `Off-topic posts of interest to the World of Warcraft community.`)}
{this.renderTopic(
'/realms',
'Realm Forums',
realms,
`Discuss topics related to World of Warcraft with players on your specific Realm.`,
)}
{this.renderTopic(131, 'Off-topic', offtopic, `Off-topic posts of interest to the World of Warcraft community.`)}
</div>
<div className="topic-row">
{this.renderTopic('#', 'Suggestions', suggestions, `Have a suggestion for World of Warcraft? Please post it here.`)}
{this.renderTopic('#', 'Guild Recruitment', guilds, `Searching for a guild, or do you want to advertise your guild?`)}
{this.renderTopic(134, 'Suggestions', suggestions, `Have a suggestion for World of Warcraft? Please post it here.`)}
{this.renderTopic(132, 'Guild Recruitment', guilds, `Searching for a guild, or do you want to advertise your guild?`)}
</div>
<div className="topic-row">
{this.renderTopic('#', 'Role-Playing', roleplaying, `Pull up a chair, drink a mug of ale, meet new friends, tell stories, and role-play in this forum.`)}
{this.renderTopic('#', 'General Discussion.', general, `Discuss World of Warcraft.`)}
{this.renderTopic(
135,
'Role-Playing',
roleplaying,
`Pull up a chair, drink a mug of ale, meet new friends, tell stories, and role-play in this forum.`,
)}
{this.renderTopic(133, 'General Discussion.', general, `Discuss World of Warcraft.`)}
</div>
<div className="topic-row">
{this.renderTopic('#', 'Raid and Dungeon Discussion', dungeons, `Discuss the instance dungeons and end-game raid encounters in World of Warcraft.`)}
{this.renderTopic(
136,
'Raid and Dungeon Discussion',
dungeons,
`Discuss the instance dungeons and end-game raid encounters in World of Warcraft.`,
)}
</div>
</div>
<hr/>
<hr />
</ContentContainer>
</ScrollToTop>
);

View File

@@ -24,7 +24,7 @@ export class Thread extends React.Component<Props, State> {
}
private async getThreads() {
const thread = await ThreadService.getThread(this.props.match.params['id']);
const thread = await ThreadService.getThread(this.props.match.params['threadId']);
thread.replies = [thread as any, ...thread.replies]; // add the thread topic to the front of the list
this.setState({ thread });
}
@@ -71,7 +71,8 @@ export class Thread extends React.Component<Props, State> {
<ScrollToTop {...this.props}>
<div style={{ padding: '16px 0 12px 0' }}>
<ForumNav/>
{/* todo: */}
<ForumNav categoryId={parseInt(this.props.match.params['categoryId'], 10)} {...this.props}/>
</div>
<div className="topic-bg">

View File

@@ -52,7 +52,6 @@ export class UserAccount extends React.Component<Props, State> {
this.setState({ noCharacters: true });
return;
}
// remove classes that weren't in vanilla
const characters = groupBy(res.characters, 'realm');
this.setState({
characters,

View File

@@ -45,9 +45,9 @@ export class Routes extends React.Component<Props, State> {
<Route exact path="/" component={Home} />
<Route exact path="/realms" component={Realms} />
<Route exact path="/f/:id" component={Forum} />
<Route exact path="/f/:categoryId/:threadId" component={Thread} />
<Route exact path="/oauth" component={Oauth} />
<Route exact path="/user-account" component={UserAccount} />
<Route exact path="/thread/:id" component={Thread} />
<Route component={NotFound} />
</Switch>
<Footer />

View File

@@ -165,12 +165,18 @@ defmodule Category do
defp get_other() do
[
%{"id" => 131, "category" => "other", "title" => "Off-Topic"},
%{"id" => 131, "category" => "other", "title" => "Off-topic"},
%{"id" => 132, "category" => "other", "title" => "Guild Recruitment"},
%{"id" => 133, "category" => "other", "title" => "General Discussion"},
%{"id" => 134, "category" => "other", "title" => "Suggestions"},
%{"id" => 135, "category" => "other", "title" => "Role-Playing"},
%{"id" => 136, "category" => "other", "title" => "Raid and Dungeon Discussion"},
%{"id" => 137, "category" => "other", "title" => "Site Suggestions"},
%{"id" => 138, "category" => "other", "title" => "UI & Macros Forum"},
%{"id" => 139, "category" => "other", "title" => "Bug Report Forum"},
%{"id" => 140, "category" => "other", "title" => "Professions"},
%{"id" => 141, "category" => "other", "title" => "PvP Discussion"},
%{"id" => 142, "category" => "other", "title" => "Quest Discussion"},
]
end