diff --git a/client/app/assets/Tyren.gif b/client/app/assets/Tyren.gif new file mode 100644 index 0000000..e44a35e Binary files /dev/null and b/client/app/assets/Tyren.gif differ diff --git a/client/app/assets/avatars/Blood_elf_female.gif b/client/app/assets/avatars/Blood_elf_female.gif new file mode 100644 index 0000000..2875f28 Binary files /dev/null and b/client/app/assets/avatars/Blood_elf_female.gif differ diff --git a/client/app/assets/avatars/Blood_elf_male.gif b/client/app/assets/avatars/Blood_elf_male.gif new file mode 100644 index 0000000..49593a1 Binary files /dev/null and b/client/app/assets/avatars/Blood_elf_male.gif differ diff --git a/client/app/assets/avatars/Draenei_female.gif b/client/app/assets/avatars/Draenei_female.gif new file mode 100644 index 0000000..f8de32f Binary files /dev/null and b/client/app/assets/avatars/Draenei_female.gif differ diff --git a/client/app/assets/avatars/Draenei_male.gif b/client/app/assets/avatars/Draenei_male.gif new file mode 100644 index 0000000..1a02528 Binary files /dev/null and b/client/app/assets/avatars/Draenei_male.gif differ diff --git a/client/app/assets/avatars/Dwarf_female.gif b/client/app/assets/avatars/Dwarf_female.gif new file mode 100644 index 0000000..6137d2d Binary files /dev/null and b/client/app/assets/avatars/Dwarf_female.gif differ diff --git a/client/app/assets/avatars/Dwarf_male.gif b/client/app/assets/avatars/Dwarf_male.gif new file mode 100644 index 0000000..6d8ba7a Binary files /dev/null and b/client/app/assets/avatars/Dwarf_male.gif differ diff --git a/client/app/assets/avatars/Gnome_female.gif b/client/app/assets/avatars/Gnome_female.gif new file mode 100644 index 0000000..43c2006 Binary files /dev/null and b/client/app/assets/avatars/Gnome_female.gif differ diff --git a/client/app/assets/avatars/Gnome_male.gif b/client/app/assets/avatars/Gnome_male.gif new file mode 100644 index 0000000..0f5a47d Binary files /dev/null and b/client/app/assets/avatars/Gnome_male.gif differ diff --git a/client/app/assets/avatars/Human_female.gif b/client/app/assets/avatars/Human_female.gif new file mode 100644 index 0000000..b898445 Binary files /dev/null and b/client/app/assets/avatars/Human_female.gif differ diff --git a/client/app/assets/avatars/Human_male.gif b/client/app/assets/avatars/Human_male.gif new file mode 100644 index 0000000..d3e1128 Binary files /dev/null and b/client/app/assets/avatars/Human_male.gif differ diff --git a/client/app/assets/avatars/Night_elf_female.gif b/client/app/assets/avatars/Night_elf_female.gif new file mode 100644 index 0000000..e14f5cf Binary files /dev/null and b/client/app/assets/avatars/Night_elf_female.gif differ diff --git a/client/app/assets/avatars/Night_elf_male.gif b/client/app/assets/avatars/Night_elf_male.gif new file mode 100644 index 0000000..79a0643 Binary files /dev/null and b/client/app/assets/avatars/Night_elf_male.gif differ diff --git a/client/app/assets/avatars/Orc_female.gif b/client/app/assets/avatars/Orc_female.gif new file mode 100644 index 0000000..474ec86 Binary files /dev/null and b/client/app/assets/avatars/Orc_female.gif differ diff --git a/client/app/assets/avatars/Orc_male.gif b/client/app/assets/avatars/Orc_male.gif new file mode 100644 index 0000000..f19434a Binary files /dev/null and b/client/app/assets/avatars/Orc_male.gif differ diff --git a/client/app/assets/avatars/Tauren_female.gif b/client/app/assets/avatars/Tauren_female.gif new file mode 100644 index 0000000..0d05ad6 Binary files /dev/null and b/client/app/assets/avatars/Tauren_female.gif differ diff --git a/client/app/assets/avatars/Tauren_male.gif b/client/app/assets/avatars/Tauren_male.gif new file mode 100644 index 0000000..a4e192b Binary files /dev/null and b/client/app/assets/avatars/Tauren_male.gif differ diff --git a/client/app/assets/avatars/Troll_female.gif b/client/app/assets/avatars/Troll_female.gif new file mode 100644 index 0000000..d2cddfd Binary files /dev/null and b/client/app/assets/avatars/Troll_female.gif differ diff --git a/client/app/assets/avatars/Troll_male.gif b/client/app/assets/avatars/Troll_male.gif new file mode 100644 index 0000000..9c994db Binary files /dev/null and b/client/app/assets/avatars/Troll_male.gif differ diff --git a/client/app/assets/avatars/Undead_female.gif b/client/app/assets/avatars/Undead_female.gif new file mode 100644 index 0000000..90fac96 Binary files /dev/null and b/client/app/assets/avatars/Undead_female.gif differ diff --git a/client/app/assets/avatars/Undead_male.gif b/client/app/assets/avatars/Undead_male.gif new file mode 100644 index 0000000..97f996f Binary files /dev/null and b/client/app/assets/avatars/Undead_male.gif differ diff --git a/client/app/assets/blizz.gif b/client/app/assets/blizz.gif new file mode 100644 index 0000000..fec0d35 Binary files /dev/null and b/client/app/assets/blizz.gif differ diff --git a/client/app/assets/forum-index-bot.gif b/client/app/assets/forum-index-bot.gif new file mode 100644 index 0000000..4f42618 Binary files /dev/null and b/client/app/assets/forum-index-bot.gif differ diff --git a/client/app/assets/forum-index.gif b/client/app/assets/forum-index.gif new file mode 100644 index 0000000..8f074c1 Binary files /dev/null and b/client/app/assets/forum-index.gif differ diff --git a/client/app/assets/level-circle.gif b/client/app/assets/level-circle.gif new file mode 100644 index 0000000..67b1c7b Binary files /dev/null and b/client/app/assets/level-circle.gif differ diff --git a/client/app/assets/paging-bg.gif b/client/app/assets/paging-bg.gif new file mode 100644 index 0000000..25b6fba Binary files /dev/null and b/client/app/assets/paging-bg.gif differ diff --git a/client/app/assets/portrait-bot.gif b/client/app/assets/portrait-bot.gif new file mode 100644 index 0000000..8a3eaa5 Binary files /dev/null and b/client/app/assets/portrait-bot.gif differ diff --git a/client/app/assets/portrait-left.gif b/client/app/assets/portrait-left.gif new file mode 100644 index 0000000..1aff99b Binary files /dev/null and b/client/app/assets/portrait-left.gif differ diff --git a/client/app/assets/portrait-right.gif b/client/app/assets/portrait-right.gif new file mode 100644 index 0000000..5182915 Binary files /dev/null and b/client/app/assets/portrait-right.gif differ diff --git a/client/app/assets/portrait-top.gif b/client/app/assets/portrait-top.gif new file mode 100644 index 0000000..313e409 Binary files /dev/null and b/client/app/assets/portrait-top.gif differ diff --git a/client/app/assets/quote-button.gif b/client/app/assets/quote-button.gif new file mode 100644 index 0000000..623e7ae Binary files /dev/null and b/client/app/assets/quote-button.gif differ diff --git a/client/app/assets/reply-button.gif b/client/app/assets/reply-button.gif new file mode 100644 index 0000000..78f9283 Binary files /dev/null and b/client/app/assets/reply-button.gif differ diff --git a/client/app/assets/topic-bg.gif b/client/app/assets/topic-bg.gif new file mode 100644 index 0000000..c8a1871 Binary files /dev/null and b/client/app/assets/topic-bg.gif differ diff --git a/client/app/components/forum-nav/forum-nav.scss b/client/app/components/forum-nav/forum-nav.scss new file mode 100644 index 0000000..1f158e2 --- /dev/null +++ b/client/app/components/forum-nav/forum-nav.scss @@ -0,0 +1,6 @@ +.forum-nav { + display: inline-block; + padding-left: 5px; + position: relative; + bottom: 10; +} diff --git a/client/app/components/forum-nav/forum-nav.tsx b/client/app/components/forum-nav/forum-nav.tsx new file mode 100644 index 0000000..e048e26 --- /dev/null +++ b/client/app/components/forum-nav/forum-nav.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import './forum-nav.scss'; + +interface Props {} + +interface State {} + +export class ForumNav extends React.Component { + + render() { + return ( +
+ +
+ Forum Nav: +
+
+ ); + } +} diff --git a/client/app/components/index.ts b/client/app/components/index.ts index a9e7877..55b12c5 100644 --- a/client/app/components/index.ts +++ b/client/app/components/index.ts @@ -1,4 +1,7 @@ export * from './content-container/content-container'; export * from './footer/footer'; +export * from './forum-nav/forum-nav'; export * from './header/header'; export * from './login-button/login-button'; +export * from './portrait/portrait'; +export * from './scroll-to-top/scroll-to-top'; diff --git a/client/app/components/portrait/portrait.scss b/client/app/components/portrait/portrait.scss new file mode 100644 index 0000000..cdc1c37 --- /dev/null +++ b/client/app/components/portrait/portrait.scss @@ -0,0 +1,9 @@ +.portrait { + position: relative; + + &__level-circle { + position: absolute; + top: 8px; + left: 8px; + } +} diff --git a/client/app/components/portrait/portrait.tsx b/client/app/components/portrait/portrait.tsx new file mode 100644 index 0000000..453bb08 --- /dev/null +++ b/client/app/components/portrait/portrait.tsx @@ -0,0 +1,29 @@ +import React from 'react'; +import './portrait.scss'; + +interface Props { + imageSrc: any; +} + +interface State { +} + +export class Portrait extends React.Component { + + componentDidMount() {} + + render() { + return ( +
+ +
+ + + + +
+ +
+ ); + } +} diff --git a/client/app/components/scroll-to-top/scroll-to-top.tsx b/client/app/components/scroll-to-top/scroll-to-top.tsx new file mode 100644 index 0000000..fd3c859 --- /dev/null +++ b/client/app/components/scroll-to-top/scroll-to-top.tsx @@ -0,0 +1,15 @@ +import React from 'react'; + +export class ScrollToTop extends React.Component { + constructor(props: any) { + super(props); + } + + componentDidMount() { + window.scrollTo(0, 0); + } + + render() { + return this.props.children; + } +} diff --git a/client/app/pages/forum/forum.scss b/client/app/pages/forum/forum.scss index 9ff888e..4558c8d 100644 --- a/client/app/pages/forum/forum.scss +++ b/client/app/pages/forum/forum.scss @@ -8,13 +8,6 @@ $grey2: #161616; justify-content: space-between; } -.forum-nav { - display: inline-block; - padding-left: 5px; - position: relative; - bottom: 10; -} - .forum-body { min-height: 500px; margin-bottom: 100px; diff --git a/client/app/pages/forum/forum.tsx b/client/app/pages/forum/forum.tsx index 1b3923f..197d832 100644 --- a/client/app/pages/forum/forum.tsx +++ b/client/app/pages/forum/forum.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { Link, RouteComponentProps } from 'react-router-dom'; import { get } from 'lodash'; import { ThreadService } from '../../services'; -import { LoginButton } from '../../components'; +import { ForumNav, LoginButton, ScrollToTop } from '../../components'; import { ThreadModel } from '../../model'; import './forum.scss'; @@ -32,12 +32,7 @@ export class Forum extends React.Component { renderHeader() { return (
-
- -
- Forum Nav: -
-
+
@@ -115,10 +110,10 @@ export class Forum extends React.Component { render() { return ( -
+ {this.renderHeader()} {this.renderBody()} -
+ ); } diff --git a/client/app/pages/home/home.tsx b/client/app/pages/home/home.tsx index 19f89dc..c9e937c 100644 --- a/client/app/pages/home/home.tsx +++ b/client/app/pages/home/home.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { Link, RouteComponentProps } from 'react-router-dom'; -import { ContentContainer } from '../../components'; +import { ContentContainer, ScrollToTop } from '../../components'; import './home.scss'; @@ -87,88 +87,90 @@ export class Home extends React.Component { render() { return ( - - -
- Welcome to the World of Warcraft community forums! -
-

- Blizzard provides the World of Warcraft community forums for its player to chat, exchange ideas, and submit feedback. Posting on - 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. -

- -
-
- {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.`)} + + + +
+ Welcome to the World of Warcraft community forums!
-
- {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!`)} +

+ Blizzard provides the World of Warcraft community forums for its player to chat, exchange ideas, and submit feedback. Posting on + 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. +

+ +
+
+ {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('#', '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!`)} +
+ +
+ +
+
+
+ +
+ Classes +
Discuss your favorite class:
+
+
+ {this.renderClasses()} +
+ +
+
+ +
+ Professions +
Discuss professions in detail.
+
+
+
+ +
+ PvP Discussion +
Discuss player versus player combat.
+
+
+
+ +
+ Quest Discussion +
Talk about and get help with the countless quests in World of Warcraft.
+
+
+
+ +
+ +
+ {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('#', '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('#', '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('#', 'Raid and Dungeon Discussion', dungeons, `Discuss the instance dungeons and end-game raid encounters in World of Warcraft.`)} +
+

-
-
-
- -
- Classes -
Discuss your favorite class:
-
-
- {this.renderClasses()} -
- -
-
- -
- Professions -
Discuss professions in detail.
-
-
-
- -
- PvP Discussion -
Discuss player versus player combat.
-
-
-
- -
- Quest Discussion -
Talk about and get help with the countless quests in World of Warcraft.
-
-
-
- -
- -
- {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('#', '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('#', '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('#', 'Raid and Dungeon Discussion', dungeons, `Discuss the instance dungeons and end-game raid encounters in World of Warcraft.`)} -
- -
- -
- -
+ +
); } } diff --git a/client/app/pages/realms/realms.tsx b/client/app/pages/realms/realms.tsx index 2dc997d..f04481f 100644 --- a/client/app/pages/realms/realms.tsx +++ b/client/app/pages/realms/realms.tsx @@ -3,7 +3,7 @@ import { chain } from 'lodash'; import { Link, RouteComponentProps } from 'react-router-dom'; import { CategoryService } from '../../services'; import { CategoryModel } from '../../model'; -import { ContentContainer } from '../../components'; +import { ContentContainer, ScrollToTop } from '../../components'; import './realms.scss'; import header_realmforums from '../../assets/header-realmforums.gif'; import realms_large from '../../assets/realms-large.gif'; @@ -49,6 +49,10 @@ export class Realms extends React.Component { render() { const { realms } = this.state; + if (realms.length === 0) { + return
; + } + // copy list so we don't modify state const realmsCopy = realms.slice(); // split realms into 3 lists @@ -56,32 +60,34 @@ export class Realms extends React.Component { const list2 = realmsCopy.splice(0, realmsCopy.length / 2); const list3 = realmsCopy; - return realms.length === 0 ?
: ( - -
- - -
+ return ( + + +
+ + +
-
-
Welcome to the World of Warcraft Realm Forums!
-
Use these forums to discuss topics related to World of Warcraft with player on your own Realm.
-
+
+
Welcome to the World of Warcraft Realm Forums!
+
Use these forums to discuss topics related to World of Warcraft with player on your own Realm.
+
-
-
    - {this.renderRealms(list1)} -
+
+
    + {this.renderRealms(list1)} +
-
    - {this.renderRealms(list2)} -
+
    + {this.renderRealms(list2)} +
-
    - {this.renderRealms(list3)} -
-
- +
    + {this.renderRealms(list3)} +
+
+
+
); } } diff --git a/client/app/pages/thread/thread.scss b/client/app/pages/thread/thread.scss new file mode 100644 index 0000000..5a10362 --- /dev/null +++ b/client/app/pages/thread/thread.scss @@ -0,0 +1,88 @@ +.topic-bg { + background-image: url('../../assets/topic-bg.gif'); + background-repeat: repeat-x; + height: 41px; + display: flex; + justify-content: space-between; + align-items: center; +} + +.threadTopic-container { + background-color: #0C0C0C; + border-style: solid; + border-width: 1px; + border-color: #8C8E89 #8C8E89 #0C0C0C #0C0C0C; + padding: 2px 10px 0 5px; + margin-top: 8px; +} + +.threadTopic { + display: flex; + align-items: center; +} + +.paging-bg { + background-image: url('../../assets/paging-bg.gif'); + background-repeat: repeat-x; + height: 25px; + margin-bottom: 4px; +} + +.reply-body { + background-color: #000000; + padding: 0 6px 4px 6px; +} + +.reply-container { + background-color: #000000; + padding: 2px; + border: 1px solid #343434; + + & + & { + margin-top: 3px; + } +} + +.reply { + display: flex; + background-color: rgb(22, 22, 22); + // border: 1px solid #343434; + + &__user-container { + display: flex; + align-items: center; + flex-direction: column; + padding: 4px; + width: 150px; + border-right: 1px solid #000000; + } + + &__title { + display: flex; + align-items: center; + justify-content: space-between; + height: 26px; + border-bottom: 1px solid #000000; + padding: 0 6px; + color: white; + + &__button { + cursor: pointer; + + & + & { + margin-left: 3px; + } + } + } + + &__content { + padding: 20px; + } +} + +.forumliner-bot-bg { + background-image: url('../../assets/forumliner-bot-bg.gif'); + background-repeat: repeat-x; + width: 100%; + height: 15px; +} diff --git a/client/app/pages/thread/thread.tsx b/client/app/pages/thread/thread.tsx index afc3569..d0cf5e1 100644 --- a/client/app/pages/thread/thread.tsx +++ b/client/app/pages/thread/thread.tsx @@ -1,25 +1,106 @@ import React from 'react'; import { RouteComponentProps } from 'react-router-dom'; +import { get } from 'lodash'; import { ThreadService } from '../../services'; +import { ForumNav, Portrait, ScrollToTop } from '../../components'; +import { ThreadModel } from '../../model'; +import './thread.scss'; interface Props extends RouteComponentProps {} -interface State {} +interface State { + thread?: ThreadModel; +} export class Thread extends React.Component { + constructor(props: Props) { + super(props); + this.state = {}; + } + componentDidMount() { this.getThreads(); } private async getThreads() { const thread = await ThreadService.getThread(this.props.match.params['id']); - console.log(thread); + thread.replies = [thread as any, ...thread.replies]; // add the thread topic to the front of the list + this.setState({ thread }); + } + + renderReplies(): any { + return this.state.thread!.replies.map((reply, index) => { + return ( +
+
+
+ +
Tyren
+
Blizzard Poster
+
+
+
+
+ {`${index + 1}. `}{this.state.thread!.title} + | {reply.inserted_at} +
+
+ + +
+
+ {/* TODO: xss sanitization */} +
{reply.content}
+
+
+
+ ); + }); + } + + private navigateForumIndex() { + this.props.history.push(`/f/${this.state.thread!.category_id}`); } render() { + + const replies = get(this.state, 'thread.replies'); + return ( -
+ + +
+ +
+ +
+
+
+ + Topic: | 12/20/2005 1:11:44 AM PST +
+
+ this.navigateForumIndex()} + style={{ cursor: 'pointer' }} + /> +
+ +
+
+ {replies && this.renderReplies()} +
+
+
+ this.navigateForumIndex()} + style={{ cursor: 'pointer', float: 'right' }} + /> + +
+ + ); } }