diff --git a/client/app/app.tsx b/client/app/app.tsx index 5bdcc4d..56edf03 100644 --- a/client/app/app.tsx +++ b/client/app/app.tsx @@ -1,6 +1,6 @@ import React from 'react'; import ReactDOM from 'react-dom'; - import Wrapper from './Wrapper'; +import 'babel-polyfill'; ReactDOM.render(, document.getElementById('app')); diff --git a/client/app/assets/header-realmforums.gif b/client/app/assets/header-realmforums.gif new file mode 100644 index 0000000..0418fe1 Binary files /dev/null and b/client/app/assets/header-realmforums.gif differ diff --git a/client/app/assets/realms-large.gif b/client/app/assets/realms-large.gif new file mode 100644 index 0000000..32f1527 Binary files /dev/null and b/client/app/assets/realms-large.gif differ diff --git a/client/app/axios/axios.ts b/client/app/axios/axios.ts new file mode 100644 index 0000000..1837e4e --- /dev/null +++ b/client/app/axios/axios.ts @@ -0,0 +1,30 @@ +import axios, { AxiosInstance, AxiosResponse } from 'axios'; + +// create our own instance of axios so we can set request headers +const ax: AxiosInstance = axios.create(); + +// response interceptors +ax.interceptors.response.use( + (config: AxiosResponse) => { + return config; + }, + (error: any) => { + // TODO: log the user out if they get a 401 + // if code is unauthorized (401) then logout if already logged in + // if (error.response.status === 401 && store.getState().user.loggedIn) { + // store.dispatch(userActions.logout()); + // } + + return Promise.reject(error); + }, +); + +export function setAuthorizationHeader(jwt: string): void { + ax.defaults.headers.common['Authorization'] = jwt; +} + +export function resetAuthorizationHeader(): void { + ax.defaults.headers.common['Authorization'] = ''; +} + +export default ax; diff --git a/client/app/pages/realms/realms.scss b/client/app/pages/realms/realms.scss new file mode 100644 index 0000000..bd5476e --- /dev/null +++ b/client/app/pages/realms/realms.scss @@ -0,0 +1,4 @@ +.realm-column { + flex: 1; + min-width: 150px; +} diff --git a/client/app/pages/realms/realms.tsx b/client/app/pages/realms/realms.tsx index 605ee6a..9e42450 100644 --- a/client/app/pages/realms/realms.tsx +++ b/client/app/pages/realms/realms.tsx @@ -1,19 +1,87 @@ import React from 'react'; +import { filter } from 'lodash'; +import { Link } from 'react-router-dom'; +import axios from '../../axios/axios'; import { ContentContainer } from '../../components'; +import './realms.scss'; +import header_realmforums from '../../assets/header-realmforums.gif'; +import realms_large from '../../assets/realms-large.gif'; interface Props {} -interface State {} +interface State { + realms: Realm[]; +} + +interface Realm { + id: number; + category: string; + title: string; +} export class Realms extends React.Component { constructor(props: Props) { super(props); + this.state = { + realms: [], + }; + } + + async componentDidMount() { + try { + const res = await axios.get('/api/category'); + const realms = filter(res.data.data, { category: 'realm' }); + this.setState({ realms }); + } catch (e) { + console.error(e); + } + } + + private renderRealms(realms: Realm[]): any { + return realms.map((realm) => { + return ( +
  • + {realm.title} +
  • + ); + }); } render() { - return ( + const { realms } = this.state; + + // copy list so we don't modify state + const realmsCopy = realms.slice(); + // split realms into 3 lists + const list1 = realmsCopy.splice(0, realmsCopy.length / 3); + const list2 = realmsCopy.splice(0, realmsCopy.length / 2); + const list3 = realmsCopy; + + return realms.length === 0 ?
    : ( - {/* TODO: */} +
    + + +
    + +
    +
    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(list2)} +
    + +
      + {this.renderRealms(list3)} +
    +
    ); } diff --git a/client/app/scss/style.scss b/client/app/scss/style.scss index b7fa0b7..5f48848 100644 --- a/client/app/scss/style.scss +++ b/client/app/scss/style.scss @@ -44,10 +44,14 @@ hr { .flex { display: flex; -} -.flex--center { - align-items: center; + &--center { + align-items: center; + } + + &--wrap { + flex-wrap: wrap; + } } span.grey { diff --git a/client/package.json b/client/package.json index 80b81bd..4f89112 100644 --- a/client/package.json +++ b/client/package.json @@ -12,13 +12,16 @@ "author": "Mitchell Gerber", "license": "MIT", "dependencies": { + "@types/lodash": "^4.14.92", "@types/react": "^16.0.34", "@types/react-dom": "^16.0.3", "@types/react-router-dom": "^4.2.3", "autoprefixer": "^7.2.4", + "axios": "^0.17.1", "babel-core": "^6.26.0", "babel-loader": "^7.1.2", "babel-plugin-add-module-exports": "^0.2.1", + "babel-polyfill": "^6.26.0", "babel-preset-env": "^1.6.1", "babel-preset-react": "^6.24.1", "babel-preset-stage-0": "^6.24.1", @@ -29,6 +32,7 @@ "file-loader": "^1.1.6", "font-awesome": "^4.7.0", "html-webpack-plugin": "^2.30.1", + "lodash": "^4.17.4", "node-sass": "^4.7.2", "normalize.css": "^7.0.0", "postcss-loader": "^2.0.9", diff --git a/client/yarn.lock b/client/yarn.lock index 61a087a..f95a57b 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -6,6 +6,10 @@ version "4.6.2" resolved "https://registry.yarnpkg.com/@types/history/-/history-4.6.2.tgz#12cfaba693ba20f114ed5765467ff25fdf67ddb0" +"@types/lodash@^4.14.92": + version "4.14.92" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.92.tgz#6e3cb0b71a1e12180a47a42a744e856c3ae99a57" + "@types/node@*": version "8.5.5" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.5.5.tgz#6f9e8164ae1a55a9beb1d2571cfb7acf9d720c61" @@ -304,6 +308,13 @@ aws4@^1.2.1, aws4@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" +axios@^0.17.1: + version "0.17.1" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.17.1.tgz#2d8e3e5d0bdbd7327f91bc814f5c57660f81824d" + dependencies: + follow-redirects "^1.2.5" + is-buffer "^1.1.5" + babel-code-frame@^6.11.0, babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" @@ -850,6 +861,14 @@ babel-plugin-transform-strict-mode@^6.24.1: babel-runtime "^6.22.0" babel-types "^6.24.1" +babel-polyfill@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153" + dependencies: + babel-runtime "^6.26.0" + core-js "^2.5.0" + regenerator-runtime "^0.10.5" + babel-preset-env@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.6.1.tgz#a18b564cc9b9afdf4aae57ae3c1b0d99188e6f48" @@ -2436,6 +2455,12 @@ flatten@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" +follow-redirects@^1.2.5: + version "1.3.0" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.3.0.tgz#f684871fc116d2e329fda55ef67687f4fabc905c" + dependencies: + debug "^3.1.0" + font-awesome@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/font-awesome/-/font-awesome-4.7.0.tgz#8fa8cf0411a1a31afd07b06d2902bb9fc815a133" @@ -4957,6 +4982,10 @@ regenerate@^1.2.1: version "1.3.3" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f" +regenerator-runtime@^0.10.5: + version "0.10.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" + regenerator-runtime@^0.11.0: version "0.11.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" diff --git a/priv/repo/seeds.exs b/priv/repo/seeds.exs index 4b0736b..6a8434b 100644 --- a/priv/repo/seeds.exs +++ b/priv/repo/seeds.exs @@ -40,10 +40,130 @@ defmodule Category do ] end - # TODO: add all realms defp get_realms() do [ + "Aegwynn", + "Agamaggan", + "Aggramar", + "Akama", + "Alleria", + "Archimonde", + "Argent Dawn", + "Arthas", + "Azgalor", + "Azjol-Nerub", + "Azshara", + "Blackhand", + "Blackrock", + "Bleeding Hollow", + "Bloodhoof", + "Bloodscalp", + "Bonechewer", + "Boulderfist", + "Bronzebeard", + "Burning Blade", + "Burning Legion", + "Cenarion Circle", + "Cenarius", + "Cho'gall", + "Chromaggus", + "Crushridge", + "Daggerspine", + "Dalaran", + "Dark Iron", + "Darkspear", + "Deathwing", + "Destromath", + "Dethecus", + "Detheroc", + "Doomhammer", + "Draenor", + "Dragonblight", + "Dragonmaw", + "Draka", + "Dunemaul", + "Durotan", + "Earthen Ring", + "Eldre'Thalas", + "Elune", + "Emerald Dream", + "Eonar", + "Eredar", + "Feathermoon", + "Firetree", + "Frostmane", + "Frostmourne", + "Frostwolf", + "Garona", + "Gilneas", + "Greymane", + "Gorefiend", + "Gorgonnash", + "Gurubashi", + "Hellscream", + "Hyjal", + "Icecrown", + "Illidan", + "Kargath", + "Kalecgos", + "Kael'thas", + "Kel'Thuzad", + "Khadgar", + "Khaz'goroth", + "Kil'Jaeden", + "Kilrogg", + "Kirin Tor", + "Laughing Skull", + "Lightbringer", + "Lightning's Blade", + "Lightninghoof", + "Llane", + "Lothar", + "Magtheridon", + "Maelstrom", + "Mal'Ganis", + "Malfurion", + "Malygos", + "Mannoroth", + "Medivh", + "Moonrunner", + "Nathrezim", + "Ner'zhul", + "Perenolde", + "Proudmoore", + "Sargeras", + "Scarlet Crusade", + "Shadow Council", + "Shadow Moon", + "Shadowsong", + "Shattered Hand", + "Silver Hand", + "Silvermoon", + "Skullcrusher", + "Skywall", + "Smolderthorn", + "Spinebreaker", + "Spirestone", + "Staghelm", "Stonemaul", + "Stormrage", + "Stormreaver", + "Stormscale", + "Suramar", + "Terenas", + "Test", + "Thunderhorn", + "Thunderlord", + "Tichondrius", + "Twisting Nether", + "Uldum", + "Uther", + "Ursin", + "Warsong", + "Whisperwind", + "Wildhammer", + "Windrunner", + "Zul'jin", ] end