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>
);
@@ -101,20 +101,33 @@ export class Home extends React.Component<Props, State> {
<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