Unverified Commit 244bba5d authored by ggrund-tsi's avatar ggrund-tsi Committed by GitHub
Browse files

Feat/eu style (#63)



* first draft

* .

* draft of eu style
Co-authored-by: default avatarGordon Grund <gordon.grund@outlook.de>
parent 25a545ae
......@@ -24,10 +24,14 @@
}
// Override default variables before the import
$body-bg: white;
$font-family-base: TeleNeo;
$primary: #7e7e7e;
$light: #eeeeee;
$body-bg: #cfcfcf;
$font-family-base: Arial, sans-serif;
$primary: #004494;
$info:#FFD617;
$dark: #404040;
$gray-100: #F2F5F9;
$body-color:$dark;
$light: #ebebeb;
// Import Bootstrap and its default variables
@import '~bootstrap/scss/bootstrap.scss';
......@@ -35,13 +39,15 @@ $light: #eeeeee;
$header-height: 120px;
$menu-width: 120px;
$menu-padding: 1rem;
$data-card-border-radius: 10px;
$data-card-border-radius: 0px;
$input-border-radius: 4px;
$user-image-width:39px;
hr {
margin-left: 0;
margin-right: 0;
margin-top: 0px;
border-top: 1px solid #d9d9d9
}
#qt-header {
......@@ -54,6 +60,7 @@ hr {
}
#qt-body {
background-color: #ffffff;
display: flex;
flex-flow: column;
flex: 1;
......@@ -61,14 +68,10 @@ hr {
}
#qt-footer {
margin: 0;
padding: 1rem;
justify-content: flex-end;
height: 50px;
margin:0px;
height: 32px;
width: 100%;
border-top-style: solid;
border-width: 1px;
border-color: #757575;
align-items: center;
}
#root {
......@@ -108,16 +111,15 @@ hr {
height: 100%;
background-color: $light;
border-radius: $data-card-border-radius;
box-shadow: 4px 2px 8px rgba(0, 0, 0, 0.15);
border: none;
}
.data-modal{
background-color: $light;
border-radius: $data-card-border-radius;
box-shadow: 4px 2px 8px rgba(0, 0, 0, 0.15);
}
#data-header {
background-color: $light;
background-color: white;
border-top-left-radius: $data-card-border-radius;
border-top-right-radius: $data-card-border-radius;
border: 0;
......@@ -143,15 +145,13 @@ hr {
}
#id-query-text {
font-family: 'TeleNeo';
font-weight: bold;
font-size: 20px;
align-self: center;
text-align: center;
}
#qr-code-container {
background-color: $body-bg;
background-color: white;
padding-top: 100%;
position: relative;
}
......@@ -165,16 +165,62 @@ hr {
}
.qt-input{
align-self: center;
border-radius: $input-border-radius;
border: 1px solid $primary;
border-radius: 0px;
border: 1px solid #7e7e7e;
}
.qt-input:focus{
border: none;
box-shadow:none !important;
// box-shadow: 3px 3px px $info;
outline: 3px solid $info;
}
.qt-input:hover:not(:focus){
border: 1px solid $info;
}
.btn-primary:focus{
border: 1px solid $info;
box-shadow:none !important;
// box-shadow: 3px 3px px $info;
outline: 4px solid $info!important;
}
.btn-primary:hover:not(:focus){
border: 1px solid $info;
outline: 3px solid $info;
}
.btn-info{
border: 1px solid $info;
}
.btn-info:focus{
border: 1px solid $dark;
box-shadow:none !important;
// box-shadow: 3px 3px px $info;
outline: 3px solid $dark!important;
}
.btn-info:hover:not(:focus){
border: 1px solid $dark;
outline: 3px solid $dark;
}
.btn-info::after{
position: absolute;
content: "";
top:13px;
right:8%;
width: 0;
height: 0;
border: solid $dark;
border-width: 0 3px 3px 0;
display: inline-block;
padding: 4px;
transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
}
.footer-font {
font-size: 14px;
color: #757575;
font-size: 11px;
color: white;
}
.header-font {
font-family: 'TeleNeo';
font-weight: bold;
font-size: 26px;
color: black;
......@@ -191,29 +237,55 @@ hr {
// }
.btn {
font-size: 16px;
border-radius: 0px;
}
.landing-title{
font-size: 18px;
max-width: 480px;
width: 100%;
}
.landing-btn {
font-family: 'TeleNeo';
position: relative;
font-weight: bold;
color: white;
max-width: 500px;
margin-bottom: 0.5rem;
max-width: 480px;
height: 48px;
margin-left: auto;
margin-right: auto;
padding: 0px;
@include media-breakpoint-down(xs) {
padding-right: 15%;
}
}
.landing-btn::after{
position: absolute;
content: "";
top:13px;
right:10%;
width: 0;
height: 0;
border: solid white;
border-width: 0 4px 4px 0;
display: inline-block;
padding: 7px;
transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
}
.center-content {
display: flex;
flex-flow: column;
flex: 1;
padding: 1rem;
@include media-breakpoint-up(md) {
margin-top: 10vh;
}
}
.data-header-title {
color: #002f67;
font-size: 22px;
}
.data-label {
font-size: 18px;
}
.input-label {
font-size: 20px;
}
......@@ -349,4 +421,18 @@ hr {
option:not(:first-child) {
color: $dark;
}
}
.eu-logo{
margin-left: 1rem;
margin: 13px 0px 13px 16px;
}
.header-title{
font-size: 18px;
margin-left: 16px;
display: flex;
align-self: center;
}
.bg-gray-1{
height:32px;
background-color: $gray-100;
}
\ No newline at end of file
......@@ -19,7 +19,7 @@
* under the License.
*/
import { Image, Row } from 'react-bootstrap'
import { Col, Container, Image, Row } from 'react-bootstrap'
import '../i18n';
import { useTranslation } from 'react-i18next';
......@@ -31,12 +31,17 @@ const Footer = (props: any) => {
return (
// simple footer with imprint and data privacy --> links tbd
<Row id='qt-footer'>
<span className="my-0 mx-5 footer-font">{t('translation:imprint')}</span>
<Image className="my-auto" src={DataProtectLogo} />
<span className="my-0 mx-2 footer-font">{t('translation:data-privacy')}</span>
</Row>
<Container className='d-flex px-0 bg-primary'>
<Row id='qt-footer'>
<Col xs='6' className='pr-3'>
<span className='footer-font' >{t('translation:title')}</span>
</Col>
<Col xs='6' className='pr-3 d-flex justify-content-end'>
<span className="footer-font pr-3">{t('translation:data-privacy')}</span>
<span className="footer-font pl-3">{t('translation:imprint')}</span>
</Col>
</Row>
</Container>
)
}
......
......@@ -28,7 +28,7 @@ import { useTranslation } from 'react-i18next';
import { useKeycloak } from '@react-keycloak/web';
import useNavigation from '../misc/navigation';
import C19Logo from '../assets/images/c-19_logo.png'
import EULogo from '../assets/images/EU_logo@3x.png'
import dgcaIwLogo from '../assets/images/dgca_issuance_web.png';
import useLocalStorage from '../misc/local-storage';
......@@ -36,10 +36,7 @@ const Header = (props: any) => {
const navigation = useNavigation();
const { t } = useTranslation();
const { keycloak } = useKeycloak();
const [userName, setUserName] = React.useState('');
const [mandant, setMandant] = useLocalStorage('mandant', '');
const [isInit, setIsInit] = React.useState(false)
React.useEffect(() => {
......@@ -47,25 +44,13 @@ const Header = (props: any) => {
setIsInit(true);
}, [navigation])
// set user name from keycloak
React.useEffect(() => {
if (keycloak.idTokenParsed) {
setUserName((keycloak.idTokenParsed as any).name);
}
}, [keycloak])
const handleLogout = () => {
// keycloak.logout({ redirectUri: window.location.origin + navigation!.calculatedRoutes.landing});
}
return (!isInit?<></>:
<Container className='position-relative'>
<>
<Container className='bg-white px-0 position-relative'>
{/* simple header with logo */}
<Image src={EULogo} className='eu-logo' />
{/* user icon and user name */}
<Row id='qt-header'>
{/* <Row id='qt-header'>
<Image src={dgcaIwLogo} onClick={navigation!.toLanding} />
<span className='header-font my-auto mx-1'>{t('translation:title')}</span>
</Row>
......@@ -82,8 +67,12 @@ const Header = (props: any) => {
{t('translation:logout')}
</Navbar.Brand>
</NavDropdown>
</Navbar>
</Navbar> */}
</Container>
<Container className='d-flex bg-gray-1 px-0 position-relative'>
<span className='header-title'>{t('translation:title')}</span>
</Container>
</>
)
}
......
......@@ -42,11 +42,11 @@ const LandingPage = (props: any) => {
return (!isInit ? <Spinner /> :
<Container className='center-content'>
<h1 className='mx-auto mb-5'>{t('translation:welcome')}</h1>
<span className='landing-title mx-auto mb-4'>{t('translation:welcome')}</span>
<Button block className='landing-btn' onClick={navigation!.toRecordVac}>{t('translation:record-vaccination-cert-dat')}</Button>
<Button block className='landing-btn' onClick={navigation!.toRecordTest}>{t('translation:record-test-cert-dat')}</Button>
<Button block className='landing-btn' onClick={navigation!.toRecordRecovery}>{t('translation:record-recovery-cert-dat')}</Button>
<Button block className='landing-btn my-2' onClick={navigation!.toRecordVac}>{t('translation:record-vaccination-cert-dat')}</Button>
<Button block className='landing-btn my-2' onClick={navigation!.toRecordTest}>{t('translation:record-test-cert-dat')}</Button>
<Button block className='landing-btn my-2' onClick={navigation!.toRecordRecovery}>{t('translation:record-recovery-cert-dat')}</Button>
</Container>
)
......
......@@ -11,18 +11,19 @@ const CardFooter = (props: any) => {
return (!props ? <></> :
<Card.Footer id='data-footer'>
<Row>
<Col xs='6' md='3'>
<Col xs='6' md='3' className='pl-0 pr-2'>
<Button
className='my-1 my-md-0 p-0'
className='my-1 my-md-0'
block
onClick={props.handleCancel}
>
{t('translation:cancel')}
</Button>
</Col>
<Col xs='6' md='3' className='pr-md-0'>
<Col xs='6' md='3' className='pr-0 pl-2'>
<Button
className='my-1 my-md-0 p-0'
className='my-1 my-md-0 text-dark'
variant='info'
block
type='submit'
>
......
......@@ -9,16 +9,15 @@ const CardHeader = (props: any) => {
const { t } = useTranslation();
return (!props ? <></> :
<Card.Header id='data-header' className='pb-0'>
<Card.Header id='data-header' className='p-3'>
<Row>
<Col md='6'>
<Card.Title className='m-md-0 tac-xs-tal-md jcc-xs-jcfs-md' as={'h2'} >{props.title}</Card.Title>
<Col md='6' className='pl-0'>
<Card.Title className='m-md-0 tac-xs-tal-md jcc-xs-jcfs-md' as={'h3'} >{props.title}</Card.Title>
</Col>
<Col md='6' className='d-flex justify-content-center'>
<Col md='6' className='d-flex pr-0 justify-content-end'>
<Card.Text id='id-query-text'>{t('translation:query-id-card')}</Card.Text>
</Col>
</Row>
<hr />
</Card.Header>
)
......
......@@ -24,7 +24,7 @@ export interface IPersonData {
export const FormGroupInput = (props: any) => {
return (!props ? <></> :
<Form.Group as={Row} controlId={props.controlId} className='mb-1'>
<Form.Group as={Row} controlId={props.controlId} className='pb-3 mb-0'>
<Form.Label className='input-label' column xs='5' sm='3'>{props.title + (props.required ? '*' : '')}</Form.Label>
<Col xs='7' sm='9' className='d-flex'>
......@@ -69,7 +69,7 @@ export const FormGroupValueSetSelect = (props: any) => {
}
return (!(props && options) ? <></> :
<Form.Group as={Row} controlId={props.controlId} className='mb-1'>
<Form.Group as={Row} controlId={props.controlId} className='pb-3 mb-0'>
<Form.Label className='input-label' column xs='5' sm='3'>{props.title + (props.required ? '*' : '')}</Form.Label>
<Col xs='7' sm='9' className='d-flex'>
......@@ -105,7 +105,7 @@ export const FormGroupISOCountrySelect = (props: any) => {
return (!(props && options) ? <></> :
<Form.Group as={Row} controlId={props.controlId} className='mb-1'>
<Form.Group as={Row} controlId={props.controlId} className='pb-3 mb-0'>
<Form.Label className='input-label' column xs='5' sm='3'>{props.title + (props.required ? '*' : '')}</Form.Label>
<Col xs='7' sm='9' className='d-flex'>
......@@ -205,64 +205,66 @@ export const PersonInputs = (props: any) => {
return (
<>
{/* first name input */}
<FormGroupInput controlId='formGivenNameInput' title={t('translation:first-name')}
value={givenName}
onChange={(evt: any) => setGivenName(evt.target.value)}
maxLength={50}
/>
{/* name input */}
<FormGroupInput controlId='formNameInput' title={t('translation:name')}
value={familyName}
onChange={(evt: any) => setFamilyName(evt.target.value)}
maxLength={50}
/>
<hr />
{/* standardised first name input */}
<FormGroupInput controlId='formStandadisedGivenNameInput' title={t('translation:standardised-first-name')}
value={standardisedGivenName}
onChange={(evt: any) => handleStandardisedNameChanged(evt.target.value, setStandardisedGivenName)}
pattern={utils.pattern.standardisedName}
maxLength={50}
/>
{/*standardised name input */}
<FormGroupInput controlId='formStandadisedNameInput' title={t('translation:standardised-name')}
value={standardisedFamilyName}
onChange={(evt: any) => handleStandardisedNameChanged(evt.target.value, setStandardisedFamilyName)}
required
pattern={utils.pattern.standardisedName}
maxLength={50}
/>
<hr />
{/* date of birth input */}
<Form.Group as={Row} controlId='formDateOfBirthInput' className='mb-1'>
<Form.Label className='input-label txt-no-wrap' column xs='5' sm='3'>{t('translation:date-of-birth') + '*'}</Form.Label>
<Col xs='7' sm='9' className='d-flex'>
<DatePicker
selected={dateOfBirth}
onChange={handleDateOfBirthChange}
dateFormat={utils.pickerDateFormat}
isClearable
placeholderText={t('translation:date-of-birth')}
className='qt-input form-control'
wrapperClassName='align-self-center'
showMonthDropdown
showYearDropdown
dropdownMode="select"
maxDate={new Date()}
minDate={new Date(1900, 0, 1, 12)}
openToDate={new Date(1990, 0, 1)}
required
/>
</Col>
</Form.Group>
<div className='pt-3'>
{/* first name input */}
<FormGroupInput controlId='formGivenNameInput' title={t('translation:first-name')}
value={givenName}
onChange={(evt: any) => setGivenName(evt.target.value)}
maxLength={50}
/>
{/* name input */}
<FormGroupInput controlId='formNameInput' title={t('translation:name')}
value={familyName}
onChange={(evt: any) => setFamilyName(evt.target.value)}
maxLength={50}
/>
<hr />
{/* standardised first name input */}
<FormGroupInput controlId='formStandadisedGivenNameInput' title={t('translation:standardised-first-name')}
value={standardisedGivenName}
onChange={(evt: any) => handleStandardisedNameChanged(evt.target.value, setStandardisedGivenName)}
pattern={utils.pattern.standardisedName}
maxLength={50}
/>
{/*standardised name input */}
<FormGroupInput controlId='formStandadisedNameInput' title={t('translation:standardised-name')}
value={standardisedFamilyName}
onChange={(evt: any) => handleStandardisedNameChanged(evt.target.value, setStandardisedFamilyName)}
required
pattern={utils.pattern.standardisedName}
maxLength={50}
/>
<hr />
{/* date of birth input */}
<Form.Group as={Row} controlId='formDateOfBirthInput' className='pb-3 mb-0'>
<Form.Label className='input-label txt-no-wrap' column xs='5' sm='3'>{t('translation:date-of-birth') + '*'}</Form.Label>
<Col xs='7' sm='9' className='d-flex'>
<DatePicker
selected={dateOfBirth}
onChange={handleDateOfBirthChange}
dateFormat={utils.pickerDateFormat}
isClearable
placeholderText={t('translation:date-of-birth')}
className='qt-input form-control'
wrapperClassName='align-self-center'
showMonthDropdown
showYearDropdown
dropdownMode="select"
maxDate={new Date()}
minDate={new Date(1900, 0, 1, 12)}
openToDate={new Date(1990, 0, 1)}
required
/>
</Col>
</Form.Group>
</div>
</>
)
}
\ No newline at end of file
......@@ -188,7 +188,7 @@ const RecordRecoveryCertData = (props: any) => {
{/*
content area with patient inputs and check box
*/}
<Card.Body id='data-body' className='pt-0'>
<Card.Body id='data-body' className='p-3'>
{/* name inputs */}
<PersonInputs eudgc={props.eudgc} onChange={setPerson} />
......@@ -206,7 +206,7 @@ const RecordRecoveryCertData = (props: any) => {
<hr />
{/* Date of First Positive Test Result */}
<Form.Group as={Row} controlId='formLastDateInput' className='mb-1'>
<Form.Group as={Row} controlId='formLastDateInput'className='pb-3 mb-0'>
<Form.Label className='input-label txt-no-wrap' column xs='5' sm='3'>{t('translation:first-positive-test-date') + '*'}</Form.Label>
<Col xs='7' sm='9' className='d-flex'>
......@@ -247,7 +247,7 @@ const RecordRecoveryCertData = (props: any) => {
/>
{/* Date: Certificate Valid From - To */}
<Form.Group as={Row} controlId='formDateOfBirthInput' className='mb-1'>
<Form.Group as={Row} controlId='formDateOfBirthInput'className='pb-3 mb-0'>
<Form.Label className='input-label txt-no-wrap' column xs='5' sm='3'>{t('translation:cert-valid-from-to') + '*'}</Form.Label>
<Col xs='7' sm='9' className='d-flex'>
......
......@@ -208,7 +208,7 @@ const RecordTestCertData = (props: any) => {
{/*
content area with patient inputs and check box
*/}