Commit 9165cd59 authored by Sandro Lutz's avatar Sandro Lutz
Browse files

Add navigation bar styling

parent 7ce469f2
......@@ -11,13 +11,13 @@ import eventList from './views/events/eventList';
import eventDetails from './views/events/eventDetails';
import profile from './views/profile';
import layout from './views/layout';
import amivLayout from './views/amiv/amivLayout';
import frontpage from './views/frontpage';
import logout from './views/logout';
import statutes from './views/amiv/statutes';
import contact from './views/contact';
import about from './views/amiv/about';
import board from './views/amiv/board';
import minutes from './views/amiv/minutes';
import commissions from './views/amiv/commissions';
import jobOfferList from './views/jobs/jobofferList';
import jobOfferDetails from './views/jobs/jobofferDetails';
......@@ -56,23 +56,27 @@ Raven.context(() => {
const routes = [
{
url: '/:language',
view: () => m(amivLayout, m(frontpage)),
view: () => m(frontpage),
},
{
url: '/:language/amiv/statutes',
view: () => m(amivLayout, m(statutes)),
view: () => m(statutes),
},
{
url: '/:language/amiv/board',
view: () => m(amivLayout, m(board)),
view: () => m(board),
},
{
url: '/:language/amiv/commissions',
view: () => m(amivLayout, m(commissions)),
view: () => m(commissions),
},
{
url: '/:language/amiv/about',
view: () => m(amivLayout, m(about)),
view: () => m(about),
},
{
url: '/:language/amiv/minutes',
view: () => m(minutes),
},
{
url: '/:language/contact',
......
......@@ -3,19 +3,19 @@
"language.de": "Deutsch",
"language.en": "Englisch",
"AMIV": "AMIV",
"About AMIV": "Über den AMIV",
"Board": "Vorstand",
"Commissions": "Kommissionen",
"Statutes": "Statuten",
"Minutes": "Protokolle",
"Events": "Events",
"Studienunterlagen": "Studienunterlagen",
"Studydocuments": "Studienunterlagen",
"Jobs": "Jobs",
"Companies": "Firmenprofile",
"Login": "Login",
"Logout": "Logout",
"Profile": "Profil",
"example content": "beispiel Inhalte",
"Vorstand": "Vorstand",
"Aufenthaltsraum": "Aufenthaltsraum",
"Statuten": "Statuten",
"Kommissionen": "Kommissionen",
"Protokolle": "Protokolle",
"About AMIV": "Über den AMIV",
"President": "Präsident",
"Quaestor": "Quästor",
"IT": "IT",
......
......@@ -3,19 +3,19 @@
"language.de": "German",
"language.en": "English",
"AMIV": "AMIV",
"About AMIV": "About AMIV",
"Board": "Board",
"Commissions": "Commissions",
"Statutes": "Statutes",
"Minutes": "Minutes",
"Events": "Events",
"Studienunterlagen": "Study Documents",
"Studydocuments": "Study Documents",
"Jobs": "Jobs",
"Companies": "Companies",
"Login": "Login",
"Logout": "Logout",
"Profile": "Profile",
"example content": "blablabla",
"Vorstand": "Board Members",
"Aufenthaltsraum": "Aufenthaltsraum in englisch",
"Statuten": "Statuten in english",
"Kommissionen": "Commissions",
"Protokolle": "Protocols",
"About AMIV": "About AMIV",
"President": "President",
"Quaestor": "Quaestor",
"IT": "IT",
......
import m from 'mithril';
import { checkLogin, isLoggedIn } from '../models/auth';
import { currentLanguage, i18n } from './language';
const defaultTabs = ['AMIV', 'Events', 'Studienunterlagen', 'Jobs'];
const tabsLoggedOut = ['Login'];
const tabsLoggedIn = ['Profile', 'Logout'];
function tabToUrl() {
return {
AMIV: { href: `/${currentLanguage()}/`, onupdate: m.route.link, index: 0 },
Events: { href: `/${currentLanguage()}/events`, onupdate: m.route.link, index: 1 },
Studienunterlagen: {
href: `/${currentLanguage()}/studydocuments`,
onupdate: m.route.link,
index: 2,
},
Jobs: { href: `/${currentLanguage()}/jobs`, onupdate: m.route.link, index: 3 },
Login: { href: `/${currentLanguage()}/profile`, onupdate: m.route.link, index: 4 },
Profile: { href: `/${currentLanguage()}/profile`, onupdate: m.route.link, index: 4 },
Logout: { href: `/${currentLanguage()}/logout`, onupdate: m.route.link, index: 5 },
};
}
import { currentLanguage } from './language';
/**
* Navigation model to store the current state of the main navigation.
......@@ -28,55 +7,110 @@ function tabToUrl() {
* @return {Navigation} Navigation state model
*/
export default class Navigation {
constructor() {
checkLogin();
this._wasLoggedIn = isLoggedIn();
this._selectedTabIndex = 0;
Object.values(tabToUrl())
.filter(tab => m.route.get().includes(tab.href))
.forEach(tab => {
this._selectedTabIndex = tab.index;
});
constructor(items) {
this._items = items;
}
this._tabOptions = {
className: 'themed-tabs',
activeSelected: true,
element: 'tab',
selectedTab: this._selectedTabIndex,
};
this.setTabs();
get items() {
return this._items;
}
setTabs() {
if (isLoggedIn()) {
this._tabs = [...defaultTabs, ...tabsLoggedIn];
} else {
this._tabs = [...defaultTabs, ...tabsLoggedOut];
}
get selectedIndex() {
return this._selectedIndex;
}
this._tabOptions.tabs = [];
this._tabs.forEach(tab => {
this._tabOptions.tabs.push({
label: i18n(tab),
url: tabToUrl()[tab],
});
});
get selectedItem() {
return this._selectedIndex >= 0 ? this._items[this._selectedIndex] : undefined;
}
get tabs() {
return this._tabOptions;
map(callback) {
return this._items.map(callback);
}
onupdate() {
Object.values(tabToUrl())
.filter(tab => m.route.get().includes(tab.href))
.forEach(tab => {
this._selectedTabIndex = tab.index;
});
this._tabOptions.selectedTab = this._selectedTabIndex;
if (this._wasLoggedIn !== isLoggedIn()) {
this._wasLoggedIn = isLoggedIn();
this.setTabs();
}
this._items.forEach(item => {
if (item.submenu) {
item.submenu.onupdate();
}
});
this._selectedIndex = this._checkMenuItemSelection();
}
_checkMenuItemSelection() {
let selectedIndex;
this._items.forEach((item, index) => {
const link = item.getLink();
if (
(link.length <= 4 && m.route.get() === link) ||
(link.length > 4 && m.route.get().includes(link)) ||
(item.submenu && item.submenu.selectedIndex)
) {
selectedIndex = index;
}
});
this._selectedIndex = selectedIndex;
return this._selectedIndex;
}
}
export const mainNavigation = new Navigation([
{
label: 'AMIV',
getLink: () => `/${currentLanguage()}/amiv/about`,
onupdate: m.route.link,
submenu: new Navigation([
{
label: 'About AMIV',
getLink: () => `/${currentLanguage()}/amiv/about`,
onupdate: m.route.link,
},
{
label: 'Board',
getLink: () => `/${currentLanguage()}/amiv/board`,
onupdate: m.route.link,
},
{
label: 'Commissions',
getLink: () => `/${currentLanguage()}/amiv/commissions`,
onupdate: m.route.link,
},
{
label: 'Statutes',
getLink: () => `/${currentLanguage()}/amiv/statutes`,
onupdate: m.route.link,
},
{
label: 'Minutes',
getLink: () => `/${currentLanguage()}/amiv/minutes`,
onupdate: m.route.link,
},
]),
},
{
label: 'Events',
getLink: () => `/${currentLanguage()}/events`,
onupdate: m.route.link,
},
{
label: 'Studydocuments',
getLink: () => `/${currentLanguage()}/studydocuments`,
onupdate: m.route.link,
},
{
label: 'Jobs',
getLink: () => `/${currentLanguage()}/jobs`,
onupdate: m.route.link,
submenu: new Navigation([
{
label: 'Jobs',
getLink: () => `/${currentLanguage()}/jobs`,
onupdate: m.route.link,
},
{
label: 'Companies',
getLink: () => `/${currentLanguage()}/companies`,
onupdate: m.route.link,
},
]),
},
]);
......@@ -14,15 +14,13 @@ export default class AMIV {
return m.trust(this.content);
}
_load() {
async _load() {
if (this.content) return;
m.request({
this.content = await m.request({
url: `/dist/amiv/about.${currentLanguage()}.html`,
method: 'GET',
deserialize: response => {
this.content = response;
},
deserialize: response => response,
});
}
}
import m from 'mithril';
import { i18n, currentLanguage } from '../../models/language';
module.exports = {
view(vnode) {
return m('div', [
m('ul', [
m(
'li',
m(
'a',
{
href: `/${currentLanguage()}/amiv/board`,
oncreate: m.route.link,
},
i18n('Vorstand')
)
),
m(
'li',
m(
'a',
{
href: `/${currentLanguage()}/amiv/about`,
oncreate: m.route.link,
},
i18n('About AMIV')
)
),
m(
'li',
m(
'a',
{
href: `/${currentLanguage()}/amiv/statutes`,
oncreate: m.route.link,
},
i18n('Statuten')
)
),
m(
'li',
m(
'a',
{
href: `/${currentLanguage()}/amiv/commissions`,
oncreate: m.route.link,
},
i18n('Kommissionen')
)
),
m(
'li',
m(
'a',
{
href: '/amiv/protocols',
oncreate: m.route.link,
},
i18n('Protokolle')
)
),
]),
m('main', vnode.children),
]);
},
};
import m from 'mithril';
export default class AMIV {
oninit() {
this.content = '';
this._load();
}
static view() {
return m('p', 'The documents will be available in a minute ;D');
}
}
......@@ -16,15 +16,13 @@ export default class Statutes {
return m.trust(this.content);
}
_load() {
async _load() {
if (this.content) return;
m.request({
this.content = await m.request({
url: `/${statutes}`,
method: 'GET',
deserialize: response => {
this.content = response;
},
deserialize: response => response,
});
}
}
......@@ -9,13 +9,6 @@ export default class companyDetail {
});
}
onbeforeupdate(vnode) {
// load markdown whenever component is reloaded
load(vnode.attrs.companyId).then(response => {
this.content = response;
});
}
view() {
return m.trust(this.content);
}
......
import m from 'mithril';
export default class Footer {
static view() {
return m('footer', m('section.blue', m('div', m('p', '© 1893 - 2018 AMIV an der ETH'))));
}
}
import m from 'mithril';
import { mainNavigation } from '../models/navigation';
import AmivLogo from './images/logo.svg';
import { i18n, currentLanguage, switchLanguage } from '../models/language';
import { Button } from '../components';
export default class Header {
static onbeforeupdate() {
mainNavigation.onupdate();
}
static view() {
let submenu;
if (mainNavigation.selectedItem && mainNavigation.selectedItem.submenu) {
const menu = mainNavigation.selectedItem.submenu;
submenu = m(
'section.grey',
m(
'div',
m(
'nav.submenu',
menu.map((item, index) =>
m(
'a',
{
class: menu.selectedIndex === index ? 'active' : '',
href: item.getLink(),
onupdate: item.onupdate,
},
i18n(item.label)
)
)
)
)
);
}
return m('header', [
m(
'section.blue',
m('div', [
m(
'a',
{ href: `/${currentLanguage()}/`, onupdate: m.route.link },
m('img.logo', { src: AmivLogo })
),
m(
'nav',
mainNavigation.map((item, index) =>
m(
'a',
{
class: mainNavigation.selectedIndex === index ? 'active' : '',
href: item.getLink(),
onupdate: item.onupdate,
},
i18n(item.label)
)
)
),
m(
'div.profile',
m(
'a',
{ href: `/${currentLanguage()}/profile`, onupdate: m.route.link },
i18n('Profile')
)
),
m(
'div.language-switcher',
m(Button, {
label: i18n('language_button'),
events: { onclick: () => switchLanguage() },
})
),
])
),
submenu,
]);
}
}
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="196.052px" height="84.956px" viewBox="0 0 196.052 84.956" enable-background="new 0 0 196.052 84.956"
xml:space="preserve">
<g>
<defs>
<rect id="SVGID_1_" width="196.052" height="84.956"/>
</defs>
<clipPath id="SVGID_2_">
<use xlink:href="#SVGID_1_" overflow="visible"/>
</clipPath>
<path clip-path="url(#SVGID_2_)" fill="#E8462B" d="M89.187,46.405h-5.19c-2.369,0-3.679,1.109-3.679,2.975
c0,1.813,1.21,3.022,3.78,3.022c1.814,0,2.973-0.15,4.132-1.26c0.706-0.655,0.957-1.713,0.957-3.326V46.405z M89.338,57.493v-2.269
c-1.764,1.764-3.427,2.521-6.45,2.521c-2.974,0-5.141-0.757-6.703-2.318c-1.411-1.462-2.167-3.578-2.167-5.896
c0-4.183,2.872-7.609,8.97-7.609h6.198v-1.31c0-2.872-1.41-4.132-4.888-4.132c-2.519,0-3.678,0.605-5.039,2.167l-4.182-4.082
c2.569-2.822,5.089-3.628,9.473-3.628c7.358,0,11.188,3.124,11.188,9.272v17.286H89.338z"/>
<path clip-path="url(#SVGID_2_)" fill="#E8462B" d="M131.23,57.493V41.619c0-3.578-2.269-4.787-4.334-4.787
c-2.017,0-4.384,1.209-4.384,4.636v16.025h-6.553V41.619c0-3.578-2.267-4.787-4.333-4.787c-2.065,0-4.385,1.209-4.385,4.787v15.875
h-6.551V31.238h6.399v2.419c1.715-1.764,4.133-2.721,6.552-2.721c2.923,0,5.291,1.058,6.955,3.326
c2.217-2.319,4.586-3.326,7.86-3.326c2.62,0,4.989,0.856,6.45,2.318c2.117,2.116,2.873,4.586,2.873,7.458v16.781H131.23z"/>
<rect x="142.733" y="31.238" clip-path="url(#SVGID_2_)" fill="#E8462B" width="6.551" height="26.255"/>
<polygon clip-path="url(#SVGID_2_)" fill="#E8462B" points="170.697,31.238 165.406,47.465 160.065,31.238 153.161,31.238
162.836,57.493 167.977,57.493 177.602,31.24 177.602,31.238 "/>
<path clip-path="url(#SVGID_2_)" fill="#E8462B" d="M69.703,45.854c0.141-1.064,0.221-2.148,0.221-3.251
c0-1.103-0.08-2.186-0.221-3.251l-5.747-0.892c-0.257-1.147-0.619-2.271-1.086-3.357l4.121-4.096
c-0.511-0.944-1.083-1.868-1.731-2.76c-0.648-0.892-1.35-1.722-2.09-2.5l-5.168,2.652c-0.437-0.384-0.893-0.753-1.373-1.102
c-0.484-0.351-0.98-0.673-1.484-0.972l0.926-5.735c-0.968-0.464-1.974-0.875-3.024-1.216c-1.048-0.341-2.104-0.599-3.159-0.794
l-2.626,5.192c-1.174-0.107-2.352-0.103-3.52,0.007l-2.629-5.199c-1.056,0.195-2.111,0.453-3.16,0.794
c-1.049,0.341-2.055,0.752-3.023,1.215l0.927,5.743c-1.004,0.593-1.958,1.286-2.851,2.071l-5.175-2.656
c-0.74,0.778-1.442,1.607-2.09,2.5c-0.649,0.892-1.221,1.816-1.732,2.76l4.126,4.101c-0.472,1.092-0.836,2.214-1.089,3.351
l-5.748,0.893c-0.142,1.064-0.222,2.148-0.222,3.251c0,1.103,0.08,2.186,0.222,3.251l5.756,0.894
c0.256,1.145,0.617,2.267,1.082,3.35l-4.127,4.102c0.511,0.944,1.083,1.868,1.732,2.76c0.648,0.893,1.349,1.723,2.09,2.5
l5.168-2.652c0.441,0.387,0.9,0.759,1.384,1.11c0.48,0.349,0.972,0.669,1.472,0.966l-0.926,5.733
c0.969,0.464,1.975,0.875,3.024,1.216c1.049,0.342,2.104,0.6,3.16,0.793l2.622-5.185c1.177,0.109,2.357,0.106,3.528-0.004
l2.624,5.189c1.056-0.194,2.112-0.452,3.16-0.794c1.05-0.341,2.055-0.752,3.024-1.215l-0.925-5.729
c1.008-0.596,1.965-1.29,2.862-2.079l5.162,2.649c0.74-0.777,1.441-1.607,2.09-2.5c0.648-0.892,1.22-1.815,1.731-2.76l-4.115-4.091
c0.473-1.096,0.838-2.221,1.093-3.364L69.703,45.854z M33.051,48.321c-1.989-4.355-1.65-9.632,1.36-13.775
c4.445-6.118,13.038-7.479,19.156-3.034c0.435,0.316,0.839,0.658,1.225,1.013l-4.176,3.034l-4.056-5.582l-4.473,3.25l4.056,5.583
l-0.007,0.005l-12.772,1.245l3.82,5.258L33.051,48.321z M56.601,50.668c-4.445,6.118-13.038,7.479-19.156,3.034
c-0.397-0.289-0.772-0.596-1.129-0.918l4.119-2.992l4.095,5.638l5.135-11.771l3.768,5.186l4.473-3.25l-4.039-5.56l4.147-3.013
C59.94,41.353,59.582,46.564,56.601,50.668"/>
</g>
</svg>
import m from 'mithril';
import { i18n, switchLanguage } from '../models/language';
import { Button } from '../components';
import Navbar from './navbar';
import header from './header';
import footer from './footer';
export default class Layout {
static view(vnode) {
return m('div#amiv-container', [
m(Navbar),
m(Button, {
label: i18n('language_button'),
events: { onclick: () => switchLanguage() },
}),
m('main', vnode.children),
]);
return m('div', [m(header), m('main', vnode.children), m(footer)]);
}
}
import m from 'mithril';
import { Tabs } from '../components';
import Navigation from '../models/navigation';
export default class Navbar {
constructor() {
this.nav = new Navigation();
}
onupdate() {
this.nav.onupdate();
}
view() {
return m(Tabs, this.nav.tabs);
}
}