Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Julien Jerphanion
Rex Dri
Commits
a0e5e515
Commit
a0e5e515
authored
Sep 16, 2018
by
Florent Chehab
Browse files
Displaying univ scholarships ok
parent
7e101126
Changes
8
Hide whitespace changes
Inline
Side-by-side
frontend/src/components/university/UniversityTemplate.js
View file @
a0e5e515
...
...
@@ -26,7 +26,7 @@ import MoreTab from './tabs/MoreTab';
function
TabContainer
(
props
)
{
let
style
=
{
padding
:
8
*
3
};
if
(
!
props
.
d
is
play
)
{
if
(
props
.
v
is
ible
===
false
)
{
style
=
{
display
:
'
none
'
}
}
return
(
...
...
@@ -91,10 +91,10 @@ class UniversityTemplate extends React.Component {
<
Tab
label
=
"
Autres
"
icon
=
{
<
MoreHorizIcon
/>
}
/
>
<
/Tabs
>
<
/AppBar
>
<
TabContainer
d
is
play
=
{
value
===
0
}
>
<
GeneralInfoTab
univId
=
{
univId
}
visible
=
{
value
===
0
}
/> </
TabContainer
>
{
/* {
value === 1 && <TabContainer
> <UniversityMoreTab univId={univId} /> </TabContainer>} */
}
<
TabContainer
v
is
ible
=
{
value
===
0
}
>
<
GeneralInfoTab
univId
=
{
univId
}
visible
=
{
value
===
0
}
/> </
TabContainer
>
{
/* {
<TabContainer visible={value === 1}
> <UniversityMoreTab univId={univId}
visible={value === 1}
/> </TabContainer>} */
}
{
/* {value === 2 && <TabContainer> <PreviousDeparturesTab univId={univId} /> </TabContainer>} */
}
{
/* {value === 3 && <TabContainer
> <ScholarshipsTab univId={univId} /> </TabContainer>}
*/
}
{
<
TabContainer
visible
=
{
value
===
3
}
>
<
ScholarshipsTab
univId
=
{
univId
}
visible
=
{
value
===
3
}
/> </
TabContainer
>
}
{
/* {value === 4 && <TabContainer> <CampusesCitiesTab univId={univId} /> </TabContainer>} */
}
{
/* {value === 5 && <TabContainer> <MoreTab univId={univId} /> </TabContainer>} */
}
<
/div
>
...
...
frontend/src/components/university/editors/UniversityScholarshipsEditor.js
0 → 100644
View file @
a0e5e515
import
React
from
'
react
'
;
import
PropTypes
from
'
prop-types
'
;
import
withStyles
from
'
@material-ui/core/styles/withStyles
'
;
import
compose
from
'
recompose/compose
'
;
import
{
connect
}
from
"
react-redux
"
;
import
Editor
from
'
../shared/Editor
'
;
import
editorStyle
from
'
../shared/editorStyle
'
;
import
getMapStateToPropsForEditor
from
'
../shared/editorFunctions/getMapStateToPropsForEditor
'
;
import
getMapDispatchToPropsForEditor
from
'
../shared/editorFunctions/getMapDispatchToPropsForEditor
'
;
import
{
universityScholarshipsElSaveData
,
universityScholarshipsElSavingHasError
}
from
'
../../../generated/actions
'
;
const
styles
=
theme
=>
({
...
editorStyle
(
theme
)
});
class
UniversityScholarshipsEditor
extends
Editor
{
renderEditor
()
{
const
{
modelData
}
=
this
.
props
;
return
(
<
div
>
{
this
.
renderObjModerationLevelField
()}
{
this
.
renderTitleField
()}
{
this
.
renderUniversitiesField
()}
{
this
.
renderCommentField
()}
{
this
.
renderUsefulLinksField
()}
<
/div
>
)
}
}
UniversityScholarshipsEditor
.
propTypes
=
{
modelData
:
PropTypes
.
object
.
isRequired
,
};
export
default
compose
(
withStyles
(
styles
,
{
withTheme
:
true
}),
connect
(
getMapStateToPropsForEditor
(
'
universityScholarshipsEl
'
),
getMapDispatchToPropsForEditor
(
universityScholarshipsElSaveData
,
universityScholarshipsElSavingHasError
)
)
)(
UniversityScholarshipsEditor
);
\ No newline at end of file
frontend/src/components/university/modules/UniversityScholarships.js
0 → 100644
View file @
a0e5e515
import
React
from
'
react
'
;
import
PropTypes
from
'
prop-types
'
;
import
withStyles
from
'
@material-ui/core/styles/withStyles
'
;
import
compose
from
'
recompose/compose
'
;
import
{
connect
}
from
"
react-redux
"
;
import
__pick
from
'
lodash/pick
'
;
import
MyComponent
from
'
../../MyComponent
'
;
import
GenericModule
from
'
../shared/GenericModule
'
;
import
GenericGroupModule
from
'
../shared/GenericGroupModule
'
;
import
Scholarship
from
'
../shared/Scholarship
'
;
import
UniversityScholarshipsEditor
from
'
../editors/UniversityScholarshipsEditor
'
;
import
{
universityScholarshipsFetchData
,
universityScholarshipsInvalidated
,
}
from
'
../../../generated/actions
'
;
const
styles
=
theme
=>
({
});
function
renderCore
(
rawModelData
,
classes
,
outsideData
)
{
const
{
comment
,
frequency
,
currency
,
type
}
=
rawModelData
;
const
amountMin
=
rawModelData
.
amount_min
,
amountMax
=
rawModelData
.
amount_max
,
otherAdvantages
=
rawModelData
.
other_advantages
;
return
(
<
Scholarship
currency
=
{
currency
}
currencies
=
{
outsideData
.
currencies
}
frequency
=
{
frequency
}
type
=
{
type
}
amountMin
=
{
amountMin
}
amountMax
=
{
amountMax
}
otherAdvantages
=
{
otherAdvantages
}
comment
=
{
comment
}
/
>
)
}
function
parseRawModelData
(
rawModelData
)
{
// reverse serialization
const
modelData
=
__pick
(
rawModelData
,
[
"
id
"
,
"
title
"
,
"
type
"
,
"
currency
"
,
"
frequency
"
,
"
amount_min
"
,
"
amount_max
"
,
// "importance_level",
"
universities
"
,
"
comment
"
,
"
other_advantages
"
,
"
useful_links
"
,
"
obj_moderation_level
"
,
]);
return
modelData
;
}
class
UniversityScholarships
extends
MyComponent
{
ignoreInvalidation
=
true
;
componentWillUnmount
()
{
this
.
props
.
invalidateData
(
true
);
}
myComponentDidUpdate
()
{
if
(
this
.
props
.
universityScholarships
.
invalidated
&&
!
this
.
props
.
universityScholarships
.
isLoading
)
{
this
.
props
.
fetchData
.
universityScholarships
(
this
.
props
.
univId
);
}
}
myRender
()
{
const
univScholarshipsItems
=
this
.
getFetchedData
(
'
universityScholarships
'
);
const
{
universities
,
currencies
,
classes
}
=
this
.
props
;
const
outsideData
=
{
universities
,
currencies
}
return
(
<
GenericGroupModule
groupTitle
=
{
"
Bourses liées à l'université
"
}
endPoint
=
{
"
universityScholarship
"
}
editor
=
{
UniversityScholarshipsEditor
}
invalidateGroup
=
{
this
.
props
.
invalidateData
}
propsForEditor
=
{{
modelData
:
{
universities
:
[
this
.
props
.
univId
],
importance_level
:
'
-
'
},
parseRawModelData
:
parseRawModelData
,
outsideData
:
outsideData
,
__apiAttr
:
this
.
props
.
univId
,
}}
>
{
univScholarshipsItems
.
map
((
rawModelData
)
=>
(
<
GenericModule
visible
=
{
this
.
props
.
visible
}
buildTitle
=
{(
modelData
)
=>
modelData
.
title
}
rawModelData
=
{
rawModelData
}
parseRawModelData
=
{
parseRawModelData
}
editor
=
{
UniversityScholarshipsEditor
}
renderCore
=
{
renderCore
}
coreClasses
=
{
classes
}
outsideData
=
{
outsideData
}
moduleInGroupInfos
=
{{
isInGroup
:
true
,
invalidateGroup
:
()
=>
this
.
props
.
invalidateData
()
}}
__apiAttr
=
{
this
.
props
.
univId
}
/
>
))
}
<
/GenericGroupModule
>
)
}
__apiAttr
=
{
universityScholarships
:
"
univId
"
};
}
UniversityScholarships
.
propTypes
=
{
classes
:
PropTypes
.
object
.
isRequired
,
theme
:
PropTypes
.
object
.
isRequired
,
univId
:
PropTypes
.
string
.
isRequired
,
universities
:
PropTypes
.
object
.
isRequired
,
};
const
mapStateToProps
=
(
state
)
=>
{
return
{
universityScholarships
:
state
.
universityScholarships
,
};
};
const
mapDispatchToProps
=
(
dispatch
)
=>
{
return
{
fetchData
:
{
universityScholarships
:
(
univId
)
=>
dispatch
(
universityScholarshipsFetchData
(
univId
)),
},
invalidateData
:
(
resetObj
=
false
)
=>
dispatch
(
universityScholarshipsInvalidated
(
true
,
resetObj
))
};
};
export
default
compose
(
withStyles
(
styles
,
{
withTheme
:
true
}),
connect
(
mapStateToProps
,
mapDispatchToProps
)
)(
UniversityScholarships
);
\ No newline at end of file
frontend/src/components/university/shared/InfoProvider.js
View file @
a0e5e515
...
...
@@ -11,6 +11,7 @@ import {
universitiesFetchData
,
citiesFetchData
,
countriesFetchData
,
currenciesFetchData
,
mainCampusesFetchData
,
}
from
'
../../../generated/actions
'
;
...
...
@@ -20,6 +21,7 @@ class InfoProvider extends MyComponent {
const
{
city
,
country
}
=
this
.
getUnivCityAndCountry
(
this
.
props
.
univId
);
const
universities
=
this
.
getFetchedData
(
'
universities
'
);
const
countries
=
this
.
getFetchedData
(
'
countries
'
);
const
currencies
=
this
.
getFetchedData
(
'
currencies
'
);
let
propsToAdd
=
{
univId
:
this
.
props
.
univId
,
visible
:
this
.
props
.
visible
};
...
...
@@ -33,6 +35,9 @@ class InfoProvider extends MyComponent {
case
'
countries
'
:
propsToAdd
[
key
]
=
countries
;
break
;
case
'
currencies
'
:
propsToAdd
[
key
]
=
currencies
;
break
;
case
'
city
'
:
propsToAdd
[
key
]
=
city
;
break
;
...
...
@@ -67,6 +72,7 @@ const mapStateToProps = (state) => {
return
{
countries
:
state
.
countries
,
cities
:
state
.
cities
,
currencies
:
state
.
currencies
,
mainCampuses
:
state
.
mainCampuses
,
universities
:
state
.
universities
,
};
...
...
@@ -77,6 +83,7 @@ const mapDispatchToProps = (dispatch) => {
fetchData
:
{
countries
:
()
=>
dispatch
(
countriesFetchData
()),
cities
:
()
=>
dispatch
(
citiesFetchData
()),
currencies
:
()
=>
dispatch
(
currenciesFetchData
()),
mainCampuses
:
()
=>
dispatch
(
mainCampusesFetchData
()),
universities
:
()
=>
dispatch
(
universitiesFetchData
()),
},
...
...
frontend/src/components/university/
modules
/Scholarship.js
→
frontend/src/components/university/
shared
/Scholarship.js
View file @
a0e5e515
...
...
@@ -2,26 +2,8 @@ import React from 'react';
import
PropTypes
from
'
prop-types
'
;
import
withStyles
from
'
@material-ui/core/styles/withStyles
'
;
import
Table
from
'
@material-ui/core/Table
'
;
import
TableBody
from
'
@material-ui/core/TableBody
'
;
import
TableCell
from
'
@material-ui/core/TableCell
'
;
import
TableHead
from
'
@material-ui/core/TableHead
'
;
import
TableRow
from
'
@material-ui/core/TableRow
'
;
import
Markdown
from
'
../../shared/Markdown
'
;
import
Typography
from
'
@material-ui/core/Typography
'
;
import
ArrowForwardIosIcon
from
'
@material-ui/icons/ArrowForwardIos
'
;
import
ArrowBackwardIosIcon
from
'
@material-ui/icons/ArrowBackIos
'
;
import
PersonIcon
from
'
@material-ui/icons/Person
'
;
import
MyComponent
from
'
../../MyComponent
'
;
import
TextLink
from
'
../../other/TextLink
'
;
import
GenericModule
from
'
../shared/GenericModule
'
;
import
Grid
from
'
@material-ui/core/Grid
'
;
import
Divider
from
'
@material-ui/core/Divider
'
;
const
styles
=
theme
=>
{
const
textAmountsVariant
=
'
title
'
;
...
...
@@ -54,79 +36,123 @@ const styles = theme => {
}
};
// function renderTypography(str) {
// return (
// <Typography variant='title' color="textSecondary">str</Typography>
// );
// }
// function renderAmount(amount, currency) {
// if (currency == 'EUR') {
// return String(amount) + '€';
// } else {
// return String(amount) + ' ' + currency;
// }
// }
// function renderAmounts() {
// const { amountMin, amountMax, currency, frequency, theme } = this.props;
// let output = renderAmount(amountMin, currency) + ' – ' + renderAmount(amountMax, currency);
// if (amountMin == amountMax) {
// return (
// renderTypography(renderAmount(amountMin, currency))
// renderTypography('/semestre')
// )
// } else {
// return (
// <div>
// </div>
// )
// }
// if (currency != 'EUR') {
// output += ' (~ ' + renderAmount(amountMin, 'EUR') + ' – ' + renderAmount(amountMax, 'EUR') + ')';
// }
// output += ' /'+frequency.toLowerCase();
// return output;
// if (amountMin == amountMax) {
// return (
// <Typography variant='title' color="textSecondary">{renderAmount(amountMin, amountCurrency)}</Typography>
// )
// } else {
// return (
// <Typography variant='caption'>Mis à jour par <em>chehabfl</em> le 08/09/2018 à 15h20</Typography>
// )
// }
// }
class
Scholarship
extends
React
.
Component
{
getFrequency
()
{
const
table
=
{
w
:
'
/semaine
'
,
m
:
'
/mois
'
,
s
:
'
/semestre
'
,
y
:
'
/année
'
,
o
:
'
(une seule fois)
'
}
const
{
frequency
}
=
this
.
props
;
return
table
[
frequency
];
}
getSymbol
()
{
const
{
currencies
,
currency
}
=
this
.
props
;
const
currencyInfo
=
currencies
[
currency
];
const
{
symbol
}
=
currencyInfo
;
if
(
symbol
)
{
return
symbol
;
}
else
{
return
'
'
+
currency
;
}
}
convertAmountToEur
(
amount
)
{
const
{
currencies
,
currency
}
=
this
.
props
;
const
rate
=
currencies
[
currency
].
one_EUR_in_this_currency
;
return
Math
.
trunc
(
amount
/
rate
);
}
getAmounts
()
{
const
{
amountMin
,
amountMax
}
=
this
.
props
;
if
(
amountMax
!=
null
&&
amountMax
!=
amountMin
)
{
return
`
${
amountMin
}${
this
.
getSymbol
()}
–
${
amountMax
}${
this
.
getSymbol
()}
`
;
}
else
{
return
`
${
amountMin
}${
this
.
getSymbol
()}
`
;
}
}
getConvertedAmounts
()
{
const
{
amountMin
,
amountMax
}
=
this
.
props
;
if
(
amountMax
!=
null
&&
amountMax
!=
amountMin
)
{
return
`
${
this
.
convertAmountToEur
(
amountMin
)}
€ –
${
this
.
convertAmountToEur
(
amountMax
)}
€`
;
}
else
{
return
`
${
this
.
convertAmountToEur
(
amountMin
)}
€`
;
}
}
renderFinancialAdvantage
()
{
const
{
amountMin
,
currency
,
classes
}
=
this
.
props
;
return
(
<
div
>
<
Typography
className
=
{
classes
.
item
}
variant
=
'
headline
'
>
Avantage
financier
:
<
/Typography
>
{
amountMin
!==
null
?
(
<
div
>
<
Typography
className
=
{
classes
.
textAmount
}
>
{
this
.
getAmounts
()}{
'
'
}{
this
.
getFrequency
()}
<
/Typography
>
{
currency
!=
'
EUR
'
?
<
Typography
variant
=
'
caption
'
><
em
>
(
≈
{
this
.
getConvertedAmounts
()}{
'
'
}{
this
.
getFrequency
()})
<
/em></
Typography
>
:
<
div
><
/div
>
}
<
/div
>
)
:
(
<
Typography
variant
=
'
caption
'
><
em
>
Aucun
avantage
financier
est
notifié
.
<
/em></
Typography
>
)
}
<
/div
>
)
}
renderOtherAdvantages
()
{
const
{
classes
,
otherAdvantages
}
=
this
.
props
;
return
(
<
div
>
<
Typography
className
=
{
classes
.
item
}
variant
=
'
headline
'
>
Autre
(
s
)
avantage
(
s
)
:
<
/Typography
>
{
otherAdvantages
!=
''
?
<
Markdown
source
=
{
otherAdvantages
}
/
>
:
<
Typography
variant
=
'
caption
'
><
em
>
Aucun
autre
avantage
a
été
notifié
.
<
/em></
Typography
>
}
<
/div
>
)
}
render
()
{
const
{
classes
,
theme
}
=
this
.
props
;
const
comment
=
'
Mon commentaire des familles
'
;
const
{
comment
}
=
this
.
props
return
(
<
GenericModule
title
=
{
"
Bourse Mermoz
"
}
usefulLinks
=
{[{
description
:
"
ENT
"
,
url
:
"
https://epfl.ch
"
}]}
>
<
Typography
className
=
{
classes
.
item
}
variant
=
'
headline
'
>
Avantage
financier
:
<
/Typography
>
<
Typography
className
=
{
classes
.
textAmount
}
>
300
CHF
–
400
CHF
/
mois
<
/Typography
>
<
Typography
variant
=
'
caption
'
><
em
>
(
≈
300
€
–
400
€
/
mois
)
<
/em></
Typography
>
<
div
>
{
this
.
renderFinancialAdvantage
()}
<
div
style
=
{{
height
:
2
*
theme
.
spacing
.
unit
}}
/
>
<
Typography
className
=
{
classes
.
item
}
variant
=
'
headline
'
>
Autres
avantages
:
<
/Typography
>
<
Markdown
source
=
{
comment
}
/
>
{
this
.
renderOtherAdvantages
()}
<
Typography
className
=
{
classes
.
item
}
variant
=
'
headline
'
>
Informations
complémentaires
:
<
/Typography
>
<
Markdown
source
=
{
comment
}
/
>
<
/
GenericModule
>
<
/
div
>
)
}
}
Scholarship
.
defaultProps
=
{
amountMin
:
0
,
amountMax
:
200
,
frequency
:
'
Semestre
'
,
currency
:
'
CHF
'
,
Scholarship
.
propTypes
=
{
classes
:
PropTypes
.
object
.
isRequired
,
theme
:
PropTypes
.
object
.
isRequired
,
currency
:
PropTypes
.
string
.
isRequired
,
frequency
:
PropTypes
.
string
.
isRequired
,
type
:
PropTypes
.
string
.
isRequired
,
comment
:
PropTypes
.
string
.
isRequired
,
otherAdvantages
:
PropTypes
.
string
.
isRequired
,
amountMin
:
PropTypes
.
string
,
amountMax
:
PropTypes
.
string
,
};
export
default
withStyles
(
styles
,
{
withTheme
:
true
})(
Scholarship
);
frontend/src/components/university/tabs/GeneralInfoTab.js
View file @
a0e5e515
...
...
@@ -41,12 +41,14 @@ class GeneralInfoTab extends MyComponent {
<
Grid
container
direction
=
'
column
'
>
<
Grid
item
xs
style
=
{{
paddingBottom
:
2
*
theme
.
spacing
.
unit
}}
>
<
InfoProvider
add
=
{[
'
city
'
,
'
country
'
]}
univId
=
{
this
.
props
.
univId
}
renderAndAddPropsTo
=
{
UniversityGeneral
}
/
>
<
/Grid
>
<
Grid
item
xs
>
<
InfoProvider
add
=
{[
'
universities
'
]}
univId
=
{
this
.
props
.
univId
}
renderAndAddPropsTo
=
{
UniversityDri
}
/
>
...
...
@@ -54,6 +56,7 @@ class GeneralInfoTab extends MyComponent {
<
Grid
item
xs
>
<
InfoProvider
univId
=
{
this
.
props
.
univId
}
add
=
{[
'
countries
'
,
'
countryId
'
]}
renderAndAddPropsTo
=
{
CountryDri
}
/
>
<
/Grid
>
...
...
@@ -80,6 +83,7 @@ class GeneralInfoTab extends MyComponent {
<
Grid
item
xs
=
{
12
}
>
<
InfoProvider
add
=
{[
'
city
'
,
'
country
'
]}
univId
=
{
this
.
props
.
univId
}
renderAndAddPropsTo
=
{
UniversityGeneral
}
/
>
...
...
@@ -87,11 +91,13 @@ class GeneralInfoTab extends MyComponent {
<
Grid
item
xs
=
{
12
}
>
<
InfoProvider
univId
=
{
this
.
props
.
univId
}
add
=
{[
'
universities
'
]}
renderAndAddPropsTo
=
{
UniversityDri
}
/
>
<
/Grid
>
<
Grid
item
xs
=
{
12
}
>
<
InfoProvider
add
=
{[
'
countries
'
,
'
countryId
'
]}
univId
=
{
this
.
props
.
univId
}
renderAndAddPropsTo
=
{
CountryDri
}
/
>
...
...
frontend/src/components/university/tabs/ScholarshipsTab.js
View file @
a0e5e515
...
...
@@ -2,33 +2,56 @@ import React from 'react';
import
PropTypes
from
'
prop-types
'
;
import
withStyles
from
'
@material-ui/core/styles/withStyles
'
;
import
MyComponent
from
'
../../MyComponent
'
;
import
compose
from
'
recompose/compose
'
;
import
GenericGroupModules
from
'
../shared/GenericGroupModule
'
;
import
Scholarship
from
'
../modules/Scholarship
'
;
import
Grid
from
'
@material-ui/core/Grid
'
;
import
UniversityScholarships
from
'
../modules/UniversityScholarships
'
;
import
UniversityDri
from
'
../modules/UniversityDri
'
;
import
InfoProvider
from
'
../shared/InfoProvider
'
;
const
styles
=
theme
=>
({
root
:
{},
root
:
{
display
:
'
flex
'
,
width
:
"
90%
"
,
marginLeft
:
"
auto
"
,
marginRight
:
"
auto
"
},
});
class
ScholarshipsTab
extends
MyComponent
{
myRender
()
{
const
{
classes
,
theme
}
=
this
.
props
;
return
(
<
div
>
<
GenericGroupModules
groupTitle
=
{
"
Bourse(s) qui concerne 'le pays'
"
}
>
<
Scholarship
/>
<
Scholarship
/>
<
/GenericGroupModules
>
<
GenericGroupModules
groupTitle
=
{
"
Bourse(s) qui concerne l'université
"
}
/
>
<
div
className
=
{
classes
.
root
}
>
<
Grid
container
spacing
=
{
16
}
>
<
Grid
item
xs
=
{
12
}
>
<
InfoProvider
univId
=
{
this
.
props
.
univId
}
add
=
{[
'
universities
'
,
'
currencies
'
]}
renderAndAddPropsTo
=
{
UniversityScholarships
}
/
>
<
/Grid
>
<
/Grid
>
<
/div
>
);
}