@movalib/movalib-commons 1.0.14 → 1.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/PV_README.md CHANGED
@@ -12,4 +12,12 @@
12
12
  Make shure that "private=true" in your package.json
13
13
 
14
14
  ### `npm login`
15
- ### `npm publish --access=restricted`
15
+ ### `npm publish --access=restricted`
16
+
17
+ Pour lier la librairie aux projets qui l'utilise, executer la commande suivnte
18
+
19
+ ### `npm run link`
20
+
21
+ Les commandes exécutées (ci-dessous) permettent de contourner un problème de double référence vers react et react-dom lorsque les deux appli utilisent des Hook
22
+
23
+ "link": "npm link --only=production && npm link \"/home/dimitri/Projets/5 - MOVALIB/02 - Développement/Front-End/movalib-user-app/node_modules/react\" && npm link \"/home/dimitri/Projets/5 - MOVALIB/02 - Développement/Front-End/movalib-user-app/node_modules/react-dom\"",
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ import { SelectChangeEvent } from '@mui/material';
3
+ import { MovaFormField } from './helpers/Types';
4
+ interface GenderSelectorProps {
5
+ handleSelectChange: (event: SelectChangeEvent<string>) => void;
6
+ form: {
7
+ gender: MovaFormField;
8
+ };
9
+ required?: boolean;
10
+ }
11
+ declare const GenderSelector: React.FC<GenderSelectorProps>;
12
+ export default GenderSelector;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ var jsx_runtime_1 = require("react/jsx-runtime");
15
+ var material_1 = require("@mui/material");
16
+ var GenderSelector = function (_a) {
17
+ var handleSelectChange = _a.handleSelectChange, form = _a.form, required = _a.required;
18
+ return ((0, jsx_runtime_1.jsxs)(material_1.FormControl, __assign({ fullWidth: true, margin: "normal", required: required }, { children: [(0, jsx_runtime_1.jsx)(material_1.InputLabel, __assign({ id: "gender-label" }, { children: "Sexe" })), (0, jsx_runtime_1.jsxs)(material_1.Select, __assign({ labelId: "gender-label", id: "gender", name: "gender", value: form.gender.value, onChange: function (e) { return handleSelectChange(e); } }, { children: [(0, jsx_runtime_1.jsx)(material_1.MenuItem, __assign({ value: "MALE" }, { children: "Homme" })), (0, jsx_runtime_1.jsx)(material_1.MenuItem, __assign({ value: "FEMALE" }, { children: "Femme" })), (0, jsx_runtime_1.jsx)(material_1.MenuItem, __assign({ value: "OTHER" }, { children: "Autre" }))] }))] })));
19
+ };
20
+ exports.default = GenderSelector;
@@ -0,0 +1,21 @@
1
+ import { FunctionComponent } from "react";
2
+ import { AlertColor } from "@mui/material";
3
+ import { MovaLoginForm } from "./helpers/Types";
4
+ import { MovaAppType } from "./helpers/Enums";
5
+ /**
6
+ * Propriétés du composant
7
+ * movaAppType : type d'application Movalib au sein de laquelle le composant est injectée
8
+ * onSubmit : callbakc invoquée en cas de formulaire valide
9
+ * alertMessage : éventuel message à afficher
10
+ * alertSeverity : niveau d'alerte pour le message à afficher
11
+ * loading : permet de mettre éventuellement le bouton de soumission en état de chargement
12
+ */
13
+ interface MovaSignUpProps {
14
+ movaAppType: MovaAppType;
15
+ onSubmit: (form: MovaLoginForm) => void;
16
+ alertMessage?: string;
17
+ alertSeverity?: AlertColor;
18
+ loading?: boolean;
19
+ }
20
+ declare const MovaLogin: FunctionComponent<MovaSignUpProps>;
21
+ export default MovaLogin;
@@ -0,0 +1,175 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
+ return new (P || (P = Promise))(function (resolve, reject) {
16
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
20
+ });
21
+ };
22
+ var __generator = (this && this.__generator) || function (thisArg, body) {
23
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
+ function verb(n) { return function (v) { return step([n, v]); }; }
26
+ function step(op) {
27
+ if (f) throw new TypeError("Generator is already executing.");
28
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
29
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
+ if (y = 0, t) op = [op[0] & 2, t.value];
31
+ switch (op[0]) {
32
+ case 0: case 1: t = op; break;
33
+ case 4: _.label++; return { value: op[1], done: false };
34
+ case 5: _.label++; y = op[1]; op = [0]; continue;
35
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
+ default:
37
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
+ if (t[2]) _.ops.pop();
42
+ _.trys.pop(); continue;
43
+ }
44
+ op = body.call(thisArg, _);
45
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
+ }
48
+ };
49
+ var __importDefault = (this && this.__importDefault) || function (mod) {
50
+ return (mod && mod.__esModule) ? mod : { "default": mod };
51
+ };
52
+ Object.defineProperty(exports, "__esModule", { value: true });
53
+ var jsx_runtime_1 = require("react/jsx-runtime");
54
+ var react_1 = require("react");
55
+ var lab_1 = require("@mui/lab");
56
+ var logo_large_png_1 = __importDefault(require("./assets/images/logo/logo_large.png"));
57
+ var logo_pro_large_png_1 = __importDefault(require("./assets/images/logo/logo_pro_large.png"));
58
+ var leaf_green_large_png_1 = __importDefault(require("./assets/images/leaf_green_large.png"));
59
+ var leaf_pink_large_png_1 = __importDefault(require("./assets/images/leaf_pink_large.png"));
60
+ var material_1 = require("@mui/material");
61
+ var MovaCopyright_1 = __importDefault(require("./MovaCopyright"));
62
+ var Enums_1 = require("./helpers/Enums");
63
+ var Validator_1 = require("./helpers/Validator");
64
+ var GenderSelector_1 = __importDefault(require("./GenderSelector"));
65
+ // Permet de centrer le contenu de l'application
66
+ var styles = {
67
+ display: 'flex',
68
+ justifyContent: 'center',
69
+ alignItems: 'center',
70
+ height: '100vh', // Ajustez la hauteur en fonction de vos besoins
71
+ };
72
+ var initialUserFormState = {
73
+ firstname: { value: '', isValid: true },
74
+ lastname: { value: '', isValid: true },
75
+ email: { value: '', isValid: true },
76
+ password: { value: '', isValid: true },
77
+ gender: { value: '', isValid: true },
78
+ birthDate: { value: '', isValid: true },
79
+ acceptsTerms: { value: false, isValid: true },
80
+ };
81
+ var MovaLogin = function (_a) {
82
+ var loading = _a.loading, movaAppType = _a.movaAppType, onSubmit = _a.onSubmit, alertMessage = _a.alertMessage, alertSeverity = _a.alertSeverity;
83
+ var _b = (0, react_1.useState)(initialUserFormState), userForm = _b[0], setUserForm = _b[1];
84
+ var _c = (0, react_1.useState)(""), message = _c[0], setMessage = _c[1];
85
+ //const [loading, setLoading] = useState(false);
86
+ var handleInputChange = function (e) {
87
+ var _a;
88
+ var fieldName = e.target.name;
89
+ var fieldValue = e.target.value;
90
+ var newField = (_a = {}, _a[fieldName] = { value: fieldValue, isValid: true }, _a);
91
+ setUserForm(__assign(__assign({}, userForm), newField));
92
+ };
93
+ var handleCheckboxChange = function (e, checked) {
94
+ var _a;
95
+ var fieldName = e.target.name;
96
+ var fieldValue = checked;
97
+ var newField = (_a = {}, _a[fieldName] = { value: fieldValue, isValid: true }, _a);
98
+ setUserForm(__assign(__assign({}, userForm), newField));
99
+ };
100
+ var handleSelectChange = function (e) {
101
+ var _a;
102
+ var fieldName = e.target.name;
103
+ var fieldValue = e.target.value;
104
+ var newField = (_a = {}, _a[fieldName] = { value: fieldValue, isValid: true }, _a);
105
+ setUserForm(__assign(__assign({}, userForm), newField));
106
+ };
107
+ var handleSubmit = function (e) { return __awaiter(void 0, void 0, void 0, function () {
108
+ return __generator(this, function (_a) {
109
+ e.preventDefault();
110
+ try {
111
+ if (validateForm() && onSubmit) {
112
+ // Si le formulaire est valide, on appel la function callback transmise en props
113
+ onSubmit(userForm);
114
+ }
115
+ }
116
+ catch (error) {
117
+ console.error('Error occurred during submission:', error);
118
+ }
119
+ return [2 /*return*/];
120
+ });
121
+ }); };
122
+ var validateForm = function () {
123
+ var newForm = userForm;
124
+ // Validator email
125
+ if (!(0, Validator_1.validateEmail)(userForm.email.value)) {
126
+ var errorMsg = 'Adresse email invalide';
127
+ var newField = { value: userForm.email.value, error: errorMsg, isValid: false };
128
+ newForm = __assign(__assign({}, newForm), { email: newField });
129
+ }
130
+ else {
131
+ var newField = { value: userForm.email.value, error: '', isValid: true };
132
+ newForm = __assign(__assign({}, newForm), { email: newField });
133
+ }
134
+ // Validator password
135
+ if (userForm.password.value.length < 8) {
136
+ var errorMsg = 'Votre mot de passe doit faire au moins 8 caractères de long.';
137
+ var newField = { value: userForm.password.value, error: errorMsg, isValid: false };
138
+ newForm = __assign(__assign({}, newForm), { password: newField });
139
+ }
140
+ else {
141
+ var newField = { value: userForm.password.value, error: '', isValid: true };
142
+ newForm = __assign(__assign({}, newForm), { password: newField });
143
+ }
144
+ setUserForm(newForm);
145
+ return newForm.email.isValid && newForm.password.isValid;
146
+ };
147
+ var getMovaLogo = function () {
148
+ return movaAppType === Enums_1.MovaAppType.GARAGE ? logo_pro_large_png_1.default :
149
+ movaAppType === Enums_1.MovaAppType.USER ? logo_large_png_1.default :
150
+ movaAppType === Enums_1.MovaAppType.ADMIN ? logo_large_png_1.default : logo_large_png_1.default;
151
+ };
152
+ return ((0, jsx_runtime_1.jsxs)("div", __assign({ style: styles }, { children: [(0, jsx_runtime_1.jsx)("img", { src: leaf_green_large_png_1.default, style: { position: 'fixed',
153
+ float: 'left',
154
+ width: '250px',
155
+ height: '400px',
156
+ top: '-20%',
157
+ left: '3%',
158
+ opacity: '0.3',
159
+ zIndex: -8 }, alt: 'Feuille Verte Movalib' }), (0, jsx_runtime_1.jsxs)(material_1.Container, __assign({ component: "main", maxWidth: "sm" }, { children: [(0, jsx_runtime_1.jsx)(material_1.CssBaseline, {}), (0, jsx_runtime_1.jsxs)(material_1.Box, __assign({ sx: {
160
+ marginTop: 6,
161
+ display: 'flex',
162
+ flexDirection: 'column',
163
+ alignItems: 'center',
164
+ } }, { children: [(0, jsx_runtime_1.jsx)("img", { src: getMovaLogo(), style: { width: '50%' } }), (0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsx)(material_1.Typography, __assign({ variant: "h2" }, { children: "Nouveau compte utilisateur" }))] })), (0, jsx_runtime_1.jsxs)(material_1.Box, __assign({ component: "form", onSubmit: handleSubmit, noValidate: true, sx: { mt: 1 } }, { children: [(0, jsx_runtime_1.jsx)(material_1.TextField, { margin: "normal", required: true, autoFocus: true, fullWidth: true, id: "firstname", label: "Pr\u00E9nom", name: "firstname", autoComplete: "given-name", onChange: function (e) { return handleInputChange(e); }, value: userForm.firstname.value, error: Boolean(userForm.firstname.error), helperText: userForm.firstname.error }), (0, jsx_runtime_1.jsx)(material_1.TextField, { margin: "normal", required: true, fullWidth: true, id: "lastname", label: "Nom", name: "lastname", autoComplete: "family-name", onChange: function (e) { return handleInputChange(e); }, value: userForm.lastname.value, error: Boolean(userForm.lastname.error), helperText: userForm.lastname.error }), (0, jsx_runtime_1.jsx)(material_1.TextField, { margin: "normal", required: true, fullWidth: true, id: "email", label: "Adresse email", name: "email", autoComplete: "email", autoFocus: true, onChange: function (e) { return handleInputChange(e); }, value: userForm.email.value, error: !userForm.email.isValid, helperText: userForm.email.error }), (0, jsx_runtime_1.jsx)(material_1.TextField, { margin: "normal", required: true, fullWidth: true, name: "password", label: "Mot de passe", type: "password", id: "password", autoComplete: "current-password", onChange: function (e) { return handleInputChange(e); }, value: userForm.password.value, error: !userForm.password.isValid, helperText: userForm.password.error }), (0, jsx_runtime_1.jsx)(GenderSelector_1.default, { handleSelectChange: handleSelectChange, form: userForm, required: true }), (0, jsx_runtime_1.jsx)(material_1.TextField, { margin: "normal", required: true, label: "Date de naissance", type: "date", InputLabelProps: {
165
+ shrink: true,
166
+ }, autoComplete: "bday", value: userForm.password.value, error: !userForm.password.isValid, helperText: userForm.password.error, onChange: function (e) { return handleInputChange(e); } }), (0, jsx_runtime_1.jsxs)(material_1.FormControl, __assign({ error: !userForm.acceptsTerms.isValid }, { children: [(0, jsx_runtime_1.jsx)(material_1.FormControlLabel, { control: (0, jsx_runtime_1.jsx)(material_1.Checkbox, { color: "primary", checked: userForm.acceptsTerms.value, onChange: function (e, checked) { return handleCheckboxChange(e, checked); } }), label: (0, jsx_runtime_1.jsxs)("span", { children: ["J'accepte les", ' ', (0, jsx_runtime_1.jsx)(material_1.Link, __assign({ href: "/terms-and-conditions", target: "_blank" }, { children: "Conditions G\u00E9n\u00E9rales d'Utilisation" }))] }) }), (0, jsx_runtime_1.jsx)(material_1.FormHelperText, { children: userForm.acceptsTerms.error })] })), alertMessage && alertSeverity && (0, jsx_runtime_1.jsx)(material_1.Alert, __assign({ severity: alertSeverity, sx: { mb: 2 } }, { children: alertMessage })), (0, jsx_runtime_1.jsx)(lab_1.LoadingButton, __assign({ loading: loading, type: "submit", fullWidth: true, variant: "contained", sx: { mt: 3, mb: 2 } }, { children: (0, jsx_runtime_1.jsx)("span", { children: "Cr\u00E9er mon compte" }) }))] })), (0, jsx_runtime_1.jsx)(MovaCopyright_1.default, { sx: { mt: 8, mb: 4 } })] })), (0, jsx_runtime_1.jsx)("img", { src: leaf_pink_large_png_1.default, style: { position: 'fixed',
167
+ float: 'right',
168
+ width: '250px',
169
+ height: '400px',
170
+ bottom: '-20%',
171
+ right: '3%',
172
+ opacity: '0.3',
173
+ zIndex: '-10' }, alt: 'Feuille Rose Movalib' })] })));
174
+ };
175
+ exports.default = MovaLogin;
@@ -1,3 +1,12 @@
1
+ export type MovaUserSignUpForm = {
2
+ firstname: MovaFormField;
3
+ lastname: MovaFormField;
4
+ email: MovaFormField;
5
+ password: MovaFormField;
6
+ gender: MovaFormField;
7
+ birthDate: MovaFormField;
8
+ acceptsTerms: MovaFormField;
9
+ };
1
10
  export type MovaLoginForm = {
2
11
  email: MovaFormField;
3
12
  password: MovaFormField;
package/dist/index.d.ts CHANGED
@@ -5,7 +5,5 @@ export { default as MovaCopyright } from './MovaCopyright';
5
5
  export { default as User } from './models/User';
6
6
  export { default as Role } from './models/Role';
7
7
  export { default as Address } from './models/Address';
8
- export type { MovaFormField } from './helpers/Types';
9
- export type { MovaLoginForm } from './helpers/Types';
10
- export { RoleType } from './helpers/Enums';
11
- export { MovaAppType } from './helpers/Enums';
8
+ export type { MovaFormField, MovaLoginForm, MovaUserSignUpForm } from './helpers/Types';
9
+ export { RoleType, MovaAppType } from './helpers/Enums';
package/dist/index.js CHANGED
@@ -24,5 +24,4 @@ Object.defineProperty(exports, "Address", { enumerable: true, get: function () {
24
24
  // Export des enums
25
25
  var Enums_1 = require("./helpers/Enums");
26
26
  Object.defineProperty(exports, "RoleType", { enumerable: true, get: function () { return Enums_1.RoleType; } });
27
- var Enums_2 = require("./helpers/Enums");
28
- Object.defineProperty(exports, "MovaAppType", { enumerable: true, get: function () { return Enums_2.MovaAppType; } });
27
+ Object.defineProperty(exports, "MovaAppType", { enumerable: true, get: function () { return Enums_1.MovaAppType; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@movalib/movalib-commons",
3
- "version": "1.0.14",
3
+ "version": "1.0.15",
4
4
  "description": "Bibliothèque d'objets communs à l'ensemble des projets React de Movalib",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -15,11 +15,10 @@
15
15
  "author": "",
16
16
  "license": "ISC",
17
17
  "dependencies": {
18
+ "@types/node": "^16.18.53",
18
19
  "react": "^18.2.0",
19
- "react-scripts": "5.0.1",
20
20
  "react-dom": "^18.2.0",
21
- "@types/node": "^16.18.53",
22
- "@types/react": "^18.2.22"
21
+ "react-scripts": "5.0.1"
23
22
  },
24
23
  "eslintConfig": {
25
24
  "extends": [
@@ -27,13 +26,20 @@
27
26
  ]
28
27
  },
29
28
  "devDependencies": {
30
- "@mui/material": "^5.13.5",
31
- "@mui/icons-material": "^5.11.16",
32
- "@mui/lab": "^5.0.0-alpha.134",
33
29
  "@emotion/react": "^11.11.1",
34
30
  "@emotion/styled": "^11.11.0",
31
+ "@mui/icons-material": "^5.11.16",
32
+ "@mui/lab": "^5.0.0-alpha.134",
33
+ "@mui/material": "^5.13.5",
35
34
  "@types/react": "^18.2.22",
36
35
  "@types/react-dom": "^18.2.7",
37
- "typescript": "^4.9.5"
36
+ "babel-plugin-named-exports-order": "^0.0.2",
37
+ "prop-types": "^15.8.1",
38
+ "typescript": "^4.9.5",
39
+ "webpack": "^5.88.2"
40
+ },
41
+ "peerDependencies": {
42
+ "react": "^18.2.0",
43
+ "react-dom": "^18.2.0"
38
44
  }
39
45
  }
@@ -0,0 +1,32 @@
1
+ import React, { ChangeEvent } from 'react';
2
+ import { FormControl, InputLabel, Select, MenuItem, SelectChangeEvent } from '@mui/material';
3
+ import { MovaFormField } from './helpers/Types';
4
+
5
+ interface GenderSelectorProps {
6
+ handleSelectChange: (event: SelectChangeEvent<string>) => void;
7
+ form: {
8
+ gender: MovaFormField
9
+ };
10
+ required?: boolean;
11
+ }
12
+
13
+ const GenderSelector: React.FC<GenderSelectorProps> = ({ handleSelectChange, form, required }) => {
14
+ return (
15
+ <FormControl fullWidth margin="normal" required={required}>
16
+ <InputLabel id="gender-label">Sexe</InputLabel>
17
+ <Select
18
+ labelId="gender-label"
19
+ id="gender"
20
+ name="gender"
21
+ value={form.gender.value}
22
+ onChange={e => handleSelectChange(e)}
23
+ >
24
+ <MenuItem value="MALE">Homme</MenuItem>
25
+ <MenuItem value="FEMALE">Femme</MenuItem>
26
+ <MenuItem value="OTHER">Autre</MenuItem>
27
+ </Select>
28
+ </FormControl>
29
+ );
30
+ };
31
+
32
+ export default GenderSelector;
package/src/MovaLogin.tsx CHANGED
@@ -159,10 +159,7 @@ const MovaLogin: FunctionComponent<MovaLoginProps> = ({ loading, movaAppType, on
159
159
  <FormControlLabel control={<Checkbox value="remember" color="primary" />}
160
160
  label="Se souvenir de moi"
161
161
  />
162
- {/* <MyLoadingButton
163
- type={ButtonType.SUBMIT}
164
- label="Se connecter" /> */}
165
-
162
+
166
163
  <LoadingButton
167
164
  loading={loading}
168
165
  type="submit"
@@ -0,0 +1,274 @@
1
+ import { CSSProperties, FormEvent, FunctionComponent, useState } from "react";
2
+ import { LoadingButton } from '@mui/lab';
3
+ import LogoLarge from './assets/images/logo/logo_large.png';
4
+ import LogoProLarge from './assets/images/logo/logo_pro_large.png';
5
+ import GreenLeafImage from "./assets/images/leaf_green_large.png";
6
+ import PinkLeafImage from "./assets/images/leaf_pink_large.png";
7
+ import { Alert, AlertColor, Box, Checkbox, Container, CssBaseline, FormControl, FormControlLabel, FormHelperText, Grid, Link, SelectChangeEvent, TextField, Typography } from "@mui/material";
8
+ import MovaCopyright from "./MovaCopyright";
9
+ import { MovaLoginForm, MovaFormField, MovaUserSignUpForm } from "./helpers/Types";
10
+ import { MovaAppType } from "./helpers/Enums";
11
+ import { validateEmail } from "./helpers/Validator";
12
+ import GenderSelector from "./GenderSelector";
13
+
14
+ // Permet de centrer le contenu de l'application
15
+ const styles: CSSProperties = {
16
+ display: 'flex',
17
+ justifyContent: 'center',
18
+ alignItems: 'center',
19
+ height: '100vh', // Ajustez la hauteur en fonction de vos besoins
20
+ };
21
+
22
+ const initialUserFormState = {
23
+ firstname: { value: '', isValid: true },
24
+ lastname: { value: '', isValid: true },
25
+ email: { value: '', isValid: true },
26
+ password: { value: '', isValid: true },
27
+ gender: { value: '', isValid: true },
28
+ birthDate: { value: '', isValid: true },
29
+ acceptsTerms: { value: false, isValid: true },
30
+ };
31
+
32
+ /**
33
+ * Propriétés du composant
34
+ * movaAppType : type d'application Movalib au sein de laquelle le composant est injectée
35
+ * onSubmit : callbakc invoquée en cas de formulaire valide
36
+ * alertMessage : éventuel message à afficher
37
+ * alertSeverity : niveau d'alerte pour le message à afficher
38
+ * loading : permet de mettre éventuellement le bouton de soumission en état de chargement
39
+ */
40
+ interface MovaSignUpProps {
41
+ movaAppType: MovaAppType,
42
+ onSubmit: (form: MovaLoginForm) => void,
43
+ alertMessage?: string,
44
+ alertSeverity?: AlertColor,
45
+ loading?: boolean
46
+ }
47
+
48
+ const MovaLogin: FunctionComponent<MovaSignUpProps> = ({ loading, movaAppType, onSubmit, alertMessage, alertSeverity }) => {
49
+
50
+ const [userForm, setUserForm] = useState<MovaUserSignUpForm>(initialUserFormState);
51
+
52
+ const [message, setMessage] = useState<string>("");
53
+ //const [loading, setLoading] = useState(false);
54
+
55
+ const handleInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>): void => {
56
+ const fieldName: string = e.target.name;
57
+ const fieldValue: string = e.target.value;
58
+ const newField: MovaFormField = { [fieldName]: { value: fieldValue, isValid: true } };
59
+
60
+ setUserForm({ ...userForm, ...newField});
61
+ }
62
+
63
+ const handleCheckboxChange = (e: SelectChangeEvent<string>, checked: boolean): void => {
64
+ const fieldName: string = e.target.name;
65
+ const fieldValue: boolean = checked;
66
+ const newField: MovaFormField = { [fieldName]: { value: fieldValue, isValid: true } };
67
+
68
+ setUserForm({ ...userForm, ...newField});
69
+ }
70
+
71
+ const handleSelectChange = (e: SelectChangeEvent<string>): void => {
72
+ const fieldName: string = e.target.name;
73
+ const fieldValue: string = e.target.value;
74
+ const newField: MovaFormField = { [fieldName]: { value: fieldValue, isValid: true } };
75
+
76
+ setUserForm({ ...userForm, ...newField});
77
+ }
78
+
79
+ const handleSubmit = async (e: FormEvent) => {
80
+ e.preventDefault();
81
+ try {
82
+ if(validateForm() && onSubmit) {
83
+ // Si le formulaire est valide, on appel la function callback transmise en props
84
+ onSubmit(userForm);
85
+ }
86
+
87
+ }catch (error){
88
+ console.error('Error occurred during submission:', error);
89
+ }
90
+ }
91
+
92
+ const validateForm = () => {
93
+ let newForm: MovaUserSignUpForm = userForm;
94
+
95
+ // Validator email
96
+ if(!validateEmail(userForm.email.value)) {
97
+ const errorMsg: string = 'Adresse email invalide';
98
+ const newField: MovaFormField = { value: userForm.email.value, error: errorMsg, isValid: false };
99
+ newForm = { ...newForm, ...{ email: newField } };
100
+ } else {
101
+ const newField: MovaFormField = { value: userForm.email.value, error: '', isValid: true };
102
+ newForm = { ...newForm, ...{ email: newField } };
103
+ }
104
+
105
+ // Validator password
106
+ if(userForm.password.value.length < 8) {
107
+ const errorMsg: string = 'Votre mot de passe doit faire au moins 8 caractères de long.';
108
+ const newField: MovaFormField = {value: userForm.password.value, error: errorMsg, isValid: false};
109
+ newForm = { ...newForm, ...{ password: newField } };
110
+ } else {
111
+ const newField: MovaFormField = { value: userForm.password.value, error: '', isValid: true };
112
+ newForm = { ...newForm, ...{ password: newField } };
113
+ }
114
+
115
+ setUserForm(newForm);
116
+
117
+ return newForm.email.isValid && newForm.password.isValid;
118
+ }
119
+
120
+ const getMovaLogo = () => {
121
+
122
+ return movaAppType === MovaAppType.GARAGE ? LogoProLarge :
123
+ movaAppType === MovaAppType.USER ? LogoLarge :
124
+ movaAppType === MovaAppType.ADMIN ? LogoLarge : LogoLarge;
125
+ }
126
+
127
+
128
+ return (
129
+ <div style={styles}>
130
+ <img src={GreenLeafImage} style={{position: 'fixed',
131
+ float:'left',
132
+ width: '250px',
133
+ height: '400px',
134
+ top: '-20%',
135
+ left: '3%',
136
+ opacity: '0.3',
137
+ zIndex: -8}} alt='Feuille Verte Movalib'></img>
138
+
139
+ <Container component="main" maxWidth="sm">
140
+ <CssBaseline />
141
+ <Box
142
+ sx={{
143
+ marginTop: 6,
144
+ display: 'flex',
145
+ flexDirection: 'column',
146
+ alignItems: 'center',
147
+ }}
148
+ >
149
+ <img src={getMovaLogo()} style={{width:'50%'}}/>
150
+ <br />
151
+ <Typography variant="h2">Nouveau compte utilisateur</Typography>
152
+ </Box>
153
+
154
+ <Box component="form" onSubmit={handleSubmit} noValidate sx={{ mt: 1 }}>
155
+ <TextField
156
+ margin="normal"
157
+ required
158
+ autoFocus
159
+ fullWidth
160
+ id="firstname"
161
+ label="Prénom"
162
+ name="firstname"
163
+ autoComplete="given-name"
164
+ onChange={e => handleInputChange(e)}
165
+ value={userForm.firstname.value}
166
+ error={Boolean(userForm.firstname.error)}
167
+ helperText={userForm.firstname.error}
168
+ />
169
+ <TextField
170
+ margin="normal"
171
+ required
172
+ fullWidth
173
+ id="lastname"
174
+ label="Nom"
175
+ name="lastname"
176
+ autoComplete="family-name"
177
+ onChange={e => handleInputChange(e)}
178
+ value={userForm.lastname.value}
179
+ error={Boolean(userForm.lastname.error)}
180
+ helperText={userForm.lastname.error}
181
+ />
182
+ <TextField
183
+ margin="normal"
184
+ required
185
+ fullWidth
186
+ id="email"
187
+ label="Adresse email"
188
+ name="email"
189
+ autoComplete="email"
190
+ autoFocus
191
+ onChange={e => handleInputChange(e)}
192
+ value={userForm.email.value}
193
+ error={!userForm.email.isValid}
194
+ helperText={userForm.email.error}
195
+ />
196
+ <TextField
197
+ margin="normal"
198
+ required
199
+ fullWidth
200
+ name="password"
201
+ label="Mot de passe"
202
+ type="password"
203
+ id="password"
204
+ autoComplete="current-password"
205
+ onChange={e => handleInputChange(e)}
206
+ value={userForm.password.value}
207
+ error={!userForm.password.isValid}
208
+ helperText={userForm.password.error}
209
+ />
210
+ <GenderSelector handleSelectChange={handleSelectChange} form={userForm} required/>
211
+ <TextField
212
+ margin="normal"
213
+ required
214
+ label="Date de naissance"
215
+ type="date"
216
+ InputLabelProps={{
217
+ shrink: true,
218
+ }}
219
+ autoComplete="bday"
220
+ value={userForm.password.value}
221
+ error={!userForm.password.isValid}
222
+ helperText={userForm.password.error}
223
+ onChange={(e) => handleInputChange(e)}
224
+ />
225
+ <FormControl error={!userForm.acceptsTerms.isValid}>
226
+ <FormControlLabel
227
+ control={
228
+ <Checkbox
229
+ color="primary"
230
+ checked={userForm.acceptsTerms.value}
231
+ onChange={(e, checked) => handleCheckboxChange(e, checked)}
232
+ />
233
+ }
234
+ label={
235
+ <span>
236
+ J'accepte les{' '}
237
+ <Link href="/terms-and-conditions" target="_blank">
238
+ Conditions Générales d'Utilisation
239
+ </Link>
240
+ </span>
241
+ }
242
+ />
243
+ <FormHelperText>{userForm.acceptsTerms.error}</FormHelperText>
244
+ </FormControl>
245
+
246
+ {alertMessage && alertSeverity && <Alert severity={alertSeverity} sx={{ mb: 2 }}>{alertMessage}</Alert>}
247
+
248
+
249
+ <LoadingButton
250
+ loading={loading}
251
+ type="submit"
252
+ fullWidth
253
+ variant="contained"
254
+ sx={{ mt: 3, mb: 2 }}>
255
+ <span>Créer mon compte</span>
256
+ </LoadingButton>
257
+
258
+ </Box>
259
+ <MovaCopyright sx={{ mt: 8, mb: 4 }} />
260
+ </Container>
261
+
262
+ <img src={PinkLeafImage} style={{position: 'fixed',
263
+ float:'right',
264
+ width: '250px',
265
+ height: '400px',
266
+ bottom: '-20%',
267
+ right: '3%',
268
+ opacity: '0.3',
269
+ zIndex: '-10'}} alt='Feuille Rose Movalib'></img>
270
+ </div>
271
+ );
272
+ };
273
+
274
+ export default MovaLogin;
@@ -1,3 +1,12 @@
1
+ export type MovaUserSignUpForm = {
2
+ firstname: MovaFormField,
3
+ lastname: MovaFormField,
4
+ email: MovaFormField,
5
+ password: MovaFormField,
6
+ gender: MovaFormField,
7
+ birthDate: MovaFormField,
8
+ acceptsTerms: MovaFormField
9
+ }
1
10
 
2
11
  export type MovaLoginForm = {
3
12
  email: MovaFormField,
package/src/index.ts CHANGED
@@ -12,9 +12,8 @@ export { default as Role } from './models/Role';
12
12
  export { default as Address } from './models/Address';
13
13
 
14
14
  // Export des types
15
- export type { MovaFormField } from './helpers/Types';
16
- export type { MovaLoginForm } from './helpers/Types';
15
+ export type { MovaFormField, MovaLoginForm, MovaUserSignUpForm } from './helpers/Types';
16
+
17
17
 
18
18
  // Export des enums
19
- export { RoleType } from './helpers/Enums';
20
- export { MovaAppType } from './helpers/Enums';
19
+ export { RoleType, MovaAppType } from './helpers/Enums';