Skip to content
Snippets Groups Projects
Commit f4c7db34 authored by Tore.Brede's avatar Tore.Brede
Browse files

Merge branch 'GREG-41_footer' into 'master'

GREG-41: Initial footer and header

See merge request !53
parents f8b02b68 769f34d6
No related branches found
No related tags found
1 merge request!53GREG-41: Initial footer and header
Pipeline #93778 passed
Showing
with 454 additions and 46 deletions
REACT_APP_VERSION=$npm_package_version
REACT_APP_NAME=$npm_package_name
REACT_APP_SUPPORT_MAIL=test@example.org
REACT_APP_INST=uio
REACT_APP_SUPPORT_URL=https://example.org
REACT_APP_RESPONSIBLE_ORGANIZATION=N/A
REACT_APP_RESPONSIBLE_ORGANIZATION_LINK=https://example.org
REACT_APP_THEME=default
......@@ -6,5 +6,12 @@
"language": {
"change": "Change language to {{lang}}"
},
"loading": "Loading..."
"header": {
"applicationTitleShort": "GREG",
"applicationTitleLong": "Guest Registration",
"selectLanguage": "Select language"
},
"loading": "Loading...",
"termsHeader": "Terms",
"staging": "Staging"
}
{
"footerInfo": "This is a footer namespace value"
"footerInfo": "This is a footer namespace value",
"contactSectionHeader": "Need help?",
"contactHelp": "Contact",
"contactHelpMail": "Contact",
"responsibleOrganizationHeader": "Maintained by"
}
......@@ -6,5 +6,12 @@
"language": {
"change": "Bytt språk til {{lang}}"
},
"loading": "Laster..."
"header":{
"applicationTitleShort": "GREG",
"applicationTitleLong": "Gjesteregistrering",
"selectLanguage": "Velg språk"
},
"loading": "Laster...",
"termsHeader": "Vilkår",
"staging": "Staging"
}
{
"footerInfo": "Verdi i namespace footer"
"footerInfo": "Verdi i namespace footer",
"contactSectionHeader": "Trenger du hjelp?",
"contactHelp": "Kontakt",
"contactHelpMail": "Kontaktveileder",
"responsibleOrganizationHeader": "Ansvarlig for tjenesten"
}
......@@ -4,7 +4,15 @@
"test": "Dette er ein 'nested' verdi"
},
"language": {
"languageName": "Språk",
"change": "Bytt språk til {{lang}}"
},
"loading": "Lastar..."
"header":{
"applicationTitleShort": "GREG",
"applicationTitleLong": "Gjesteregistrering",
"selectLanguage": "Velg språk"
},
"loading": "Lastar...",
"termsHeader": "Vilkår",
"staging": "Staging"
}
{
"footerInfo": "Verdi i namespace footer"
"footerInfo": "Verdi i namespace footer",
"contactSectionHeader": "Trenger du hjelp?",
"contactHelp": "Kontakt",
"contactHelpMail": "Kontaktrettleiar",
"responsibleOrganizationHeader": "Ansvarleg for tenesta"
}
frontend/public/uio/uio-app-logo-en.png

5.14 KiB

frontend/public/uio/uio-app-logo-nb.png

4.81 KiB

declare global {
/* tslint:disable */
interface Window {
ENV: any
}
/* tslint:disable */
interface Window {
ENV: any
}
}
/* Locate the client environment */
......@@ -16,7 +16,19 @@ export const appTimezone: string = 'Europe/Oslo'
export const appVersion: string = process.env.REACT_APP_VERSION as string
export const appName: string = process.env.REACT_APP_NAME as string
/* Institution */
export const appInst: string = env.REACT_APP_INST as string
/* Theming */
export const appTheme: string = env.REACT_APP_THEME
? (env.REACT_APP_THEME as string)
: 'default'
? (env.REACT_APP_THEME as string)
: 'default'
/* Show warning in the footer about this being a staging/test system */
export const appStagingWarning: boolean =
env.REACT_APP_STAGING_WARNING === 'true'
/* Footer content */
export const appTechnicalSupportLink: string = env.REACT_APP_SUPPORT_URL as string
export const reponsibleOrganization: string = env.REACT_APP_RESPONSIBLE_ORGANIZATION as string
export const responsibleOrganizationLink: string = env.REACT_APP_RESPONSIBLE_ORGANIZATION_LINK as string
import React, { useState } from 'react'
import styled from 'styled-components/macro'
const DropDownMenu = styled.div`
position: relative;
&:hover {
cursor: pointer;
}
width: fit-content;
display: inline-block;
`
const DropDownList = styled.ul`
position: absolute;
right: 1rem;
top: 2rem;
border-radius: 1rem;
list-style-type: none;
min-width: 10rem;
max-height: 50rem;
z-index: 100;
background: ${({ theme }) => theme.colors.dropDownMenuBackground};
`
interface IDropDownOption {
name: string;
value: any;
}
const getValueName = (value: any, options: Array<IDropDownOption>): string => {
for (let i = 0; i < options.length; i += 1) {
if (options[i].value === value) {
return options[i].name
}
}
return ''
}
interface IProps {
options: any[];
placeholder?: string;
value: any;
onChange: (event: any) => void;
}
function DropDown(props: IProps) {
const [open, setOpen] = useState(false)
const {
options,
placeholder,
value,
onChange,
} = props
function handleClick(option: any) {
setOpen(!open)
onChange(option.value)
}
function openMenu() {
if (!open) {
setOpen(true)
}
}
return (
<DropDownMenu
aria-haspopup='true'
aria-expanded={open}
/* eslint-disable-next-line react/jsx-no-bind */
onFocus={openMenu}
tabIndex={0}
>
<div>
<div role='button'
onKeyDown={(event) => {
if (event.key === 'Enter' || event.key === ' ') {
openMenu()
}
}}
onClick={openMenu}
tabIndex={0}
>
{/* eslint-disable-next-line */}
{placeholder
? placeholder
: getValueName(value, options).toLowerCase()}
</div>
</div>
<div>
{open && (
<DropDownList>
{options.map((option) => (
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
<li
onKeyDown={(event) => {
if (event.key === 'Enter' || event.key === ' ') {
openMenu()
}
}}
onClick={(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
event: React.MouseEvent<HTMLElement, MouseEvent>,
) => {
handleClick(option)
}}
>
<p>{option.name}</p>
</li>
))}
</DropDownList>
)}
</div>
</DropDownMenu>
)
}
DropDown.defaultProps =
{
placeholder: undefined,
}
export default DropDown
import React from 'react'
import { useTranslation } from 'react-i18next'
import DropDown from '../dropdownmenu'
function LanguageSelector() {
const { i18n, t } = useTranslation('common')
const options = [
{
name: 'English',
value: 'en',
},
{
name: 'Norsk nynorsk',
value: 'nn',
},
{
name: 'Norsk bokmål',
value: 'nb',
},
]
return (
<DropDown options={options}
placeholder={t('header.selectLanguage')}
value={options[2]}
onChange={newValue => {
i18n.changeLanguage(newValue)
}
}
/>
)
}
export default LanguageSelector
import React from 'react'
import { appTheme } from 'appConfig'
import UiOLogoBar from './UiO'
import UiBLogoBar from './UiB'
function LogoBar() {
switch (appTheme) {
case 'uio':
return <UiOLogoBar />
case 'uib':
return <UiBLogoBar />
default:
return <UiOLogoBar />
}
}
export default LogoBar
\ No newline at end of file
import React from 'react'
import styled from 'styled-components/macro'
const LogoBarWrapper = styled.div`
background-color: ${(props) => props.theme.colors.secondary});
`
const LogoBar = styled.div`
margin: 0 auto;
max-width: ${({ theme }) => theme.appMaxWidth});
padding: 0 ${({ theme }) => theme.horizontalMdPadding});
`
function UiBLogoBar() {
return (
<LogoBarWrapper>
<LogoBar>
Insert UiB logo here
</LogoBar>
</LogoBarWrapper>
)
}
export default UiBLogoBar
import React from 'react'
import styled from 'styled-components/macro'
import { useTranslation } from 'react-i18next'
const LogoBarWrapper = styled.div`
display: flex;
justify-content: center;
background-color: ${({ theme }) => theme.page.headerBackgroundColor};
`
type Language = {
language: string
}
const Logo = styled.div<Language>`
background: ${props => props.language === 'en' ? 'url("/uio/uio-app-logo-en.png") left center no-repeat' : 'url("/uio/uio-app-logo-nb.png") left center no-repeat'};
min-width: 20rem;
height: 2rem;
`
function UiOLogoBar() {
const { i18n } = useTranslation(['common', 'footer'])
return (
<LogoBarWrapper>
<Logo language={i18n.language} />
</LogoBarWrapper>
)
}
export default UiOLogoBar
import React from 'react'
import styled from 'styled-components/macro'
import { useTranslation } from 'react-i18next'
import {
appStagingWarning,
appTechnicalSupportLink,
reponsibleOrganization, responsibleOrganizationLink,
} from '../../appConfig'
import Link from '../../components/link'
// Placeholder footer component
const StyledFooter = styled.footer`
const FooterWrapper = styled.footer`
background: ${({ theme }) => theme.footer.backgroundColor};
padding: 4rem 0;
height: fit-content;
padding: 0rem ${({ theme }) => theme.horizontalPadding};
margin-top: auto;
`
const FooterWrapper = styled.div`
background: ${({ theme }) => theme.footer.backgroundColor};
color: white;
height: fit-content;
max-width: ${({ theme }) => theme.appMaxWidth};
margin: 0 auto;
padding: 0rem ${({ theme }) => theme.horizontalPadding};
const FooterSection = styled.section`
header {
margin-bottom: 0.5rem;
font-size: 1.5rem;
}
padding-left: 1rem;
`
const FooterSectionContent = styled.div`
font-size: 1rem;
padding-left: 0.3rem;
`
const ContentContainer = styled.div`
width: fit-content;
color: ${({ theme }) => theme.footerTextColor};
display: flex;
flex-wrap: nowrap;
justify-content: space-between;
margin: auto;
padding-top: 1rem;
padding-right: 1rem;
padding-bottom: 1rem;
`
export default function Footer() {
const Footer: React.FunctionComponent = () => {
const { t } = useTranslation(['common', 'footer'])
return (
<StyledFooter>
<FooterWrapper>Footer 123</FooterWrapper>
</StyledFooter>
<>
<FooterWrapper>
<ContentContainer>
<FooterSection>
<header>{t('footer:contactSectionHeader')}</header>
<FooterSectionContent>
<Link
external
to={appTechnicalSupportLink}
inheritColor
underline
>
{t('footer:contactHelp')}
</Link>
</FooterSectionContent>
</FooterSection>
<FooterSection>
<header>{t('footer:responsibleOrganizationHeader')}</header>
<FooterSectionContent>
<Link
external
to={responsibleOrganizationLink}
inheritColor
underline
>
{reponsibleOrganization}
</Link>
</FooterSectionContent>
</FooterSection>
</ContentContainer>
</FooterWrapper>
{appStagingWarning && (
<div className='alert'>
{t('staging')}
</div>
)}
</>
)
}
export default Footer
import React from 'react'
import styled from 'styled-components/macro'
import { useTranslation } from 'react-i18next'
import LogoBar from '../../components/logobars/LogoBar'
import LanguageSelector from '../../components/languageselector'
// Placeholder header component!
const MainWrapper = styled.div`
background-color: green;
color: ${({ theme }) => theme.page.headerColor};
background-color: ${({ theme }) => theme.page.headerBackgroundColor};
`
const Main = styled.div`
display: flex;
justify-content: space-between;
margin: 0 auto;
max-width: ${({ theme }) => theme.maxWidth};
height: ${({ theme }) => theme.header.height};
padding: 2.5rem ${({ theme }) => theme.horizontalPadding} 3rem
${({ theme }) => theme.horizontalPadding};
max-width: ${props => props.theme.appMaxWidth};
padding: ${props => `0.5rem ${props.theme.horizontalPadding} 1rem ${props.theme.horizontalPadding}`};
`
const Menu = styled.ul`
list-style-type: none;
`
const MenuItem = styled.div`
font-size: 1rem;
display: inline;
`
const MainRow = styled.div`
const TitleBox = styled.div`
display: flex;
justify-content: space-between;
flex-direction: column;
padding-left: 3rem;
`
const PageTitle = styled.div`
color: blue;
const ShortTitle = styled.div`
font-size: 2rem;
`
const H2 = styled.h2`
font-size: 2.8rem;
line-height: 4.5rem;
const LongTitle = styled.div`
font-size: 1rem;
`
export default function Header() {
function Header() {
const { t } = useTranslation('common')
return (
<header>
<LogoBar />
<MainWrapper>
<Main>
<MainRow>
<PageTitle>
<H2>Greg!</H2>
</PageTitle>
</MainRow>
<TitleBox>
<ShortTitle>{t('header.applicationTitleShort')}</ShortTitle>
<LongTitle>{t('header.applicationTitleLong')}</LongTitle>
</TitleBox>
<Menu>
<MenuItem>
<LanguageSelector/>
</MenuItem>
</Menu>
</Main>
</MainWrapper>
</header>
)
}
export default Header
......@@ -7,6 +7,7 @@ declare module 'styled-components' {
colors: {
main: string
secondary: string
dropDownMenuBackground: string
}
footer: {
backgroundColor: string
......@@ -17,9 +18,14 @@ declare module 'styled-components' {
horizontalPadding: string
linkExternalColor: string
linkInternalColor: string
footerBackgroundColor: string
footerTextColor: string
footerJustifyContent: string
horizontalMdPadding: string
maxWidth: string
page: {
headerColor: string
headerBackgroundColor: string
horizontalPadding: string
}
}
......
export module Color {
export const white = '#FFFFFF'
export const hotPink = '#FF69B4'
export const blueish = '#2771bb'
export const lightOliveGreen = '#91BD60'
export const black = '#000000'
export const darkGray = '#2D2D2E'
export const lighterBlack = '#282c34'
}
......@@ -6,6 +6,7 @@ const mainTheme: DefaultTheme = {
colors: {
main: 'hotPink',
secondary: 'white',
dropDownMenuBackground: 'grey'
},
footer: {
backgroundColor: 'black',
......@@ -17,8 +18,13 @@ const mainTheme: DefaultTheme = {
linkInternalColor: 'white',
linkExternalColor: 'blueish',
maxWidth: '110rem',
footerBackgroundColor: 'green',
footerTextColor: 'white',
footerJustifyContent: 'flex-end',
horizontalMdPadding: '6.5rem',
page: {
headerColor: 'grey',
headerColor: 'white',
headerBackgroundColor: 'black',
horizontalPadding: '0rem',
},
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment