UniversityOffers.jsx 5.66 KB
Newer Older
1
2
3
4
/* eslint-disable indent */
import React from "react";
import PropTypes from "prop-types";
import compose from "recompose/compose";
5
import { connect } from "react-redux";
6
7
8
9
import Close from "@material-ui/icons/Close";
import DoneAll from "@material-ui/icons/DoneAll";

import Paper from "@material-ui/core/Paper";
10
import { makeStyles, withStyles } from "@material-ui/styles";
11
12
import Typography from "@material-ui/core/Typography";
import Chip from "@material-ui/core/Chip";
13
14
import getActions from "../../../redux/api/getActions";
import withUnivInfo from "../common/withUnivInfo";
15
import RequestParams from "../../../redux/api/RequestParams";
16
import CustomComponentForAPI from "../../common/CustomComponentForAPI";
17
import PaginatedData from "../../common/PaginatedData";
18

19
const style = theme => ({
20
  paper: {
21
    padding: theme.spacing(1)
22
23
24
25
26
27
28
  },
  chip: {
    margin: theme.spacing(0.5)
  },
  inlineIcon: {
    fontSize: "1em",
    position: "relative",
29
    top: ".125em"
30
31
32
  },
  itemRoot: {
    marginTop: theme.spacing(1),
33
    marginBottom: theme.spacing(1)
34
  }
35
});
36

37
const useStyle = makeStyles(style);
38
39

function Item(props) {
40
  const { majors, semester, seats, comment, master, doubleDegree } = props;
41
42
43
44
45
  const classes = useStyle();

  return (
    <div className={classes.itemRoot}>
      <div>
46
47
48
49
50
51
52
53
54
        <Chip label={semester} color="primary" className={classes.chip} />
        {majors.map(spe => (
          <Chip
            key={spe}
            label={<b>{spe}</b>}
            className={classes.chip}
            color="secondary"
          />
        ))}
55
56
      </div>
      <div>
57
58
59
60
61
62
63
        {seats ? (
          <>
            <Typography display="inline">Au total,&nbsp;</Typography>
            <Typography color="primary" display="inline">
              {seats}
              &nbsp; place
              {seats > 1 ? "s" : ""}
64
            </Typography>
65
66
67
68
69
70
71
72
73
74
75
            <Typography display="inline">
              &nbsp;
              {seats > 1 ? "étaient/sont disponibles" : "est/disponible"}.
            </Typography>
          </>
        ) : (
          <Typography variant="caption">
            Aucune information n'est disponible concernant le nombre de places
            disponibles.
          </Typography>
        )}
76
77
78
        <div>
          <Typography>
            Master
79
80
81
82
83
            {master ? (
              <DoneAll className={classes.inlineIcon} color="primary" />
            ) : (
              <Close className={classes.inlineIcon} color="error" />
            )}
84
85
86
          </Typography>
          <Typography>
            Double diplome
87
88
89
90
91
            {doubleDegree ? (
              <DoneAll className={classes.inlineIcon} color="primary" />
            ) : (
              <Close className={classes.inlineIcon} color="error" />
            )}
92
93
94
          </Typography>
        </div>
        <div>
95
96
97
98
99
100
101
102
103
104
          {comment ? (
            <>
              <Typography variant="caption">Commentaire de la DRI:</Typography>
              <Typography>
                <em>{comment}</em>
              </Typography>
            </>
          ) : (
            <></>
          )}
105
106
107
108
109
110
111
112
113
114
        </div>
      </div>
    </div>
  );
}

Item.propTypes = {
  doubleDegree: PropTypes.bool.isRequired,
  master: PropTypes.bool.isRequired,
  semester: PropTypes.string.isRequired,
Florent Chehab's avatar
Florent Chehab committed
115
  majors: PropTypes.arrayOf(PropTypes.string).isRequired,
116
  comment: PropTypes.string,
117
  seats: PropTypes.number
118
119
};

120
121
122
123
124
Item.defaultProps = {
  comment: "",
  seats: null
};

125
class UniversityOffers extends CustomComponentForAPI {
126
  state = { page: 1 };
127

128
  apiParams = {
129
130
    universityOffers: ({ props, state }) =>
      RequestParams.Builder.withQueryParam("university", props.univId)
131
132
        .withQueryParam("page", state.page)
        .withQueryParam("page_size", 3)
133
        .build()
134
135
  };

136
  goToPage(pageNumber) {
137
    this.setState({ page: pageNumber });
138
139
140
141
142
143
144
145
146
  }

  renderEl(dataEl) {
    const {
      comment,
      double_degree: doubleDegree,
      is_master_offered: master,
      semester,
      year,
Florent Chehab's avatar
Florent Chehab committed
147
      majors,
148
      id,
149
      nb_seats_offered: seats
150
151
152
153
154
    } = dataEl;

    const props = {
      seats,
      id,
155
      doubleDegree,
156
157
      comment,
      master,
Florent Chehab's avatar
Florent Chehab committed
158
      majors: typeof majors === "string" ? majors.split(",") : [],
159
160
161
      semester: `${semester}${year}`
    };

162
    return <Item key={props.id} {...props} />;
163
164
  }

165
  customRender() {
166
    const { classes } = this.props;
167
168
169
    const universityOffers = this.getLatestReadData("universityOffers");

    return (
170
      <Paper className={classes.paper}>
171
172
173
174
175
        <Typography variant="h4">Possibilité(s) d'échanges</Typography>
        <Typography variant="caption">
          REX-DRI s'efforce d'être à jour avec l'ENT. Toutefois, seul l'ENT fait
          foi à 100% concernant les possibilités passées et actuelles
          d'échanges.
176
177
        </Typography>

178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
        <PaginatedData
          data={universityOffers}
          goToPage={pageNumber => this.goToPage(pageNumber)}
          render={dataEl => this.renderEl(dataEl)}
          stepperOnBottom
          stepperOnTop={false}
          EmptyMessageComponent={
            <Typography>
              <em>
                Aucune possibilité (passée ou présente) n'a été enregistrée à ce
                jour.
              </em>
            </Typography>
          }
        />
193
      </Paper>
194
195
196
197
198
    );
  }
}

UniversityOffers.propTypes = {
199
200
  univId: PropTypes.number.isRequired,
  classes: PropTypes.object.isRequired
201
202
};

203
204
205
const mapStateToProps = state => ({
  universityOffers: state.api.offersAll
});
206

207
208
209
210
211
const mapDispatchToProps = dispatch => ({
  api: {
    universityOffers: params => dispatch(getActions("offers").readAll(params))
  }
});
212
213

export default compose(
214
  withStyles(style),
215
  withUnivInfo(),
216
217
218
219
  connect(
    mapStateToProps,
    mapDispatchToProps
  )
220
)(UniversityOffers);