@proteinjs/user-ui 1.0.41 → 1.1.0

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.
Files changed (36) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE +21 -0
  3. package/dist/generated/index.d.ts +1 -0
  4. package/dist/generated/index.d.ts.map +1 -1
  5. package/dist/generated/index.js +4 -1
  6. package/dist/generated/index.js.map +1 -1
  7. package/dist/src/AuthenticatedPageContainer.d.ts.map +1 -1
  8. package/dist/src/AuthenticatedPageContainer.js +2 -3
  9. package/dist/src/AuthenticatedPageContainer.js.map +1 -1
  10. package/dist/src/pages/ForgotPassword.d.ts +0 -1
  11. package/dist/src/pages/ForgotPassword.d.ts.map +1 -1
  12. package/dist/src/pages/ForgotPassword.js +2 -5
  13. package/dist/src/pages/ForgotPassword.js.map +1 -1
  14. package/dist/src/pages/Login.d.ts +0 -1
  15. package/dist/src/pages/Login.d.ts.map +1 -1
  16. package/dist/src/pages/Login.js +3 -4
  17. package/dist/src/pages/Login.js.map +1 -1
  18. package/dist/src/pages/PasswordReset.d.ts +0 -1
  19. package/dist/src/pages/PasswordReset.d.ts.map +1 -1
  20. package/dist/src/pages/PasswordReset.js +2 -3
  21. package/dist/src/pages/PasswordReset.js.map +1 -1
  22. package/dist/src/pages/SendInvite.d.ts +3 -0
  23. package/dist/src/pages/SendInvite.d.ts.map +1 -0
  24. package/dist/src/pages/SendInvite.js +169 -0
  25. package/dist/src/pages/SendInvite.js.map +1 -0
  26. package/dist/src/pages/Signup.d.ts.map +1 -1
  27. package/dist/src/pages/Signup.js +142 -49
  28. package/dist/src/pages/Signup.js.map +1 -1
  29. package/generated/index.ts +10 -10
  30. package/package.json +10 -8
  31. package/src/AuthenticatedPageContainer.tsx +3 -4
  32. package/src/pages/ForgotPassword.tsx +2 -5
  33. package/src/pages/Login.tsx +3 -4
  34. package/src/pages/PasswordReset.tsx +2 -3
  35. package/src/pages/SendInvite.tsx +111 -0
  36. package/src/pages/Signup.tsx +132 -49
@@ -14,6 +14,29 @@ var __extends = (this && this.__extends) || (function () {
14
14
  d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
15
15
  };
16
16
  })();
17
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ var desc = Object.getOwnPropertyDescriptor(m, k);
20
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
21
+ desc = { enumerable: true, get: function() { return m[k]; } };
22
+ }
23
+ Object.defineProperty(o, k2, desc);
24
+ }) : (function(o, m, k, k2) {
25
+ if (k2 === undefined) k2 = k;
26
+ o[k2] = m[k];
27
+ }));
28
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
29
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
30
+ }) : function(o, v) {
31
+ o["default"] = v;
32
+ });
33
+ var __importStar = (this && this.__importStar) || function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
17
40
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
18
41
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
19
42
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -50,27 +73,139 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
50
73
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
51
74
  }
52
75
  };
53
- var __importDefault = (this && this.__importDefault) || function (mod) {
54
- return (mod && mod.__esModule) ? mod : { "default": mod };
55
- };
56
76
  Object.defineProperty(exports, "__esModule", { value: true });
57
77
  exports.signupPage = void 0;
58
- var react_1 = __importDefault(require("react"));
78
+ var react_1 = __importStar(require("react"));
59
79
  var ui_1 = require("@proteinjs/ui");
60
80
  var user_1 = require("@proteinjs/user");
81
+ var material_1 = require("@mui/material");
82
+ var util_1 = require("@proteinjs/util");
83
+ var SignupComponent = function () {
84
+ var _a = (0, react_1.useState)(''), token = _a[0], setToken = _a[1];
85
+ var _b = (0, react_1.useState)(false), isInviteOnly = _b[0], setIsInviteOnly = _b[1];
86
+ var _c = (0, react_1.useState)(false), isInitializing = _c[0], setIsInitializing = _c[1];
87
+ var _d = (0, react_1.useState)(null), initializationError = _d[0], setInitializationError = _d[1];
88
+ var buttons = {
89
+ clear: ui_1.clearButton,
90
+ signup: {
91
+ name: 'Sign up',
92
+ style: {
93
+ color: 'primary',
94
+ variant: 'contained',
95
+ },
96
+ onClick: function (fields, buttons) { return __awaiter(void 0, void 0, void 0, function () {
97
+ var email, _a;
98
+ return __generator(this, function (_b) {
99
+ switch (_b.label) {
100
+ case 0:
101
+ if (!fields.name.field.value) {
102
+ return [2 /*return*/, 'Please enter your name.'];
103
+ }
104
+ email = fields.email.field.value && fields.email.field.value.trim();
105
+ // invited users don't enter an email
106
+ if (!token && (!email || !util_1.emailRegex.test(email))) {
107
+ return [2 /*return*/, 'Please enter a valid email address.'];
108
+ }
109
+ if (!fields.password.field.value) {
110
+ return [2 /*return*/, 'Please enter a password.'];
111
+ }
112
+ _b.label = 1;
113
+ case 1:
114
+ _b.trys.push([1, 3, , 4]);
115
+ return [4 /*yield*/, (0, user_1.getSignupService)().createUser({
116
+ name: fields.name.field.value,
117
+ email: email,
118
+ password: fields.password.field.value,
119
+ }, token)];
120
+ case 2:
121
+ _b.sent();
122
+ return [3 /*break*/, 4];
123
+ case 3:
124
+ _a = _b.sent();
125
+ return [2 /*return*/, 'Sign up failed.'];
126
+ case 4: return [2 /*return*/, "Successfully created your account! Please check your email for an email confirmation."];
127
+ }
128
+ });
129
+ }); },
130
+ },
131
+ };
132
+ (0, react_1.useEffect)(function () {
133
+ var searchParams = new URLSearchParams(window.location.search);
134
+ var inviteToken = searchParams.get('token');
135
+ if (inviteToken) {
136
+ setToken(inviteToken);
137
+ initializeSignup(inviteToken);
138
+ }
139
+ else {
140
+ initializeSignup();
141
+ }
142
+ }, []);
143
+ var initializeSignup = function (token) { return __awaiter(void 0, void 0, void 0, function () {
144
+ var response, error_1;
145
+ return __generator(this, function (_a) {
146
+ switch (_a.label) {
147
+ case 0:
148
+ setIsInitializing(true);
149
+ _a.label = 1;
150
+ case 1:
151
+ _a.trys.push([1, 3, 4, 5]);
152
+ return [4 /*yield*/, (0, user_1.getSignupService)().initializeSignup(token)];
153
+ case 2:
154
+ response = _a.sent();
155
+ if (response.isInviteOnly !== undefined) {
156
+ setIsInviteOnly(response.isInviteOnly);
157
+ }
158
+ if (!response.isReady && response.error) {
159
+ setInitializationError(response.error);
160
+ }
161
+ return [3 /*break*/, 5];
162
+ case 3:
163
+ error_1 = _a.sent();
164
+ setInitializationError('An error occurred while initializing sign up.');
165
+ return [3 /*break*/, 5];
166
+ case 4:
167
+ setIsInitializing(false);
168
+ return [7 /*endfinally*/];
169
+ case 5: return [2 /*return*/];
170
+ }
171
+ });
172
+ }); };
173
+ return (react_1.default.createElement(ui_1.FormPage, null, isInitializing ? (react_1.default.createElement(material_1.Stack, { direction: 'column', spacing: 2, sx: { px: 2, py: 1 } },
174
+ react_1.default.createElement(material_1.Skeleton, { variant: 'text', width: '500px', height: '60px' }),
175
+ react_1.default.createElement(material_1.Skeleton, { variant: 'text', width: '500px', height: '60px' }),
176
+ react_1.default.createElement(material_1.Skeleton, { variant: 'text', width: '500px', height: '60px' }),
177
+ react_1.default.createElement(material_1.Skeleton, { variant: 'text', width: '500px', height: '60px' }),
178
+ react_1.default.createElement(material_1.Stack, { direction: 'row', spacing: 2, justifyContent: 'flex-end' },
179
+ react_1.default.createElement(material_1.Skeleton, { variant: 'text', width: '100px', height: '60px' }),
180
+ react_1.default.createElement(material_1.Skeleton, { variant: 'text', width: '100px', height: '60px' })))) : initializationError ? (react_1.default.createElement(material_1.Stack, { alignItems: 'center', spacing: 3, sx: { p: 4 } },
181
+ react_1.default.createElement(material_1.Typography, { variant: 'h1', gutterBottom: true }, "Sign up is not available"),
182
+ react_1.default.createElement(material_1.Typography, { variant: 'body1', gutterBottom: true }, initializationError),
183
+ react_1.default.createElement(material_1.Button, { variant: 'contained', color: 'primary', href: '/login' }, "Go to login page"))) : (react_1.default.createElement(ui_1.Form, { name: 'Sign Up', createFields: function () { return new SignupFields(); }, fieldLayout: ['name', 'email', 'password', 'confirmPassword'], buttons: buttons, onLoad: function (fields) { return __awaiter(void 0, void 0, void 0, function () {
184
+ return __generator(this, function (_a) {
185
+ fields.token.field.value = token;
186
+ if (token) {
187
+ fields.email.field.accessibility = { hidden: true };
188
+ }
189
+ return [2 /*return*/];
190
+ });
191
+ }); } }))));
192
+ };
61
193
  exports.signupPage = {
62
194
  name: 'Sign Up',
63
- path: 'signup',
195
+ path: user_1.uiRoutes.auth.signup,
64
196
  auth: {
65
197
  public: true,
66
198
  },
67
- component: function () { return (react_1.default.createElement(ui_1.FormPage, null,
68
- react_1.default.createElement(ui_1.Form, { name: 'Sign Up', createFields: function () { return new SignupFields(); }, fieldLayout: ['name', 'email', 'password', 'confirmPassword'], buttons: buttons }))); },
199
+ component: SignupComponent,
69
200
  };
70
201
  var SignupFields = /** @class */ (function (_super) {
71
202
  __extends(SignupFields, _super);
72
203
  function SignupFields() {
73
204
  var _this = _super !== null && _super.apply(this, arguments) || this;
205
+ _this.token = (0, ui_1.textField)({
206
+ name: 'token',
207
+ accessibility: { hidden: true },
208
+ });
74
209
  _this.name = (0, ui_1.textField)({
75
210
  name: 'name',
76
211
  });
@@ -92,46 +227,4 @@ var SignupFields = /** @class */ (function (_super) {
92
227
  };
93
228
  return SignupFields;
94
229
  }(ui_1.Fields));
95
- var buttons = {
96
- clear: ui_1.clearButton,
97
- signup: {
98
- name: 'Sign up',
99
- style: {
100
- color: 'primary',
101
- variant: 'contained',
102
- },
103
- onClick: function (fields, buttons) { return __awaiter(void 0, void 0, void 0, function () {
104
- var response, body;
105
- return __generator(this, function (_a) {
106
- switch (_a.label) {
107
- case 0: return [4 /*yield*/, fetch(user_1.routes.createUser.path, {
108
- method: user_1.routes.createUser.method,
109
- body: JSON.stringify({
110
- name: fields.name.field.value,
111
- email: fields.email.field.value,
112
- password: fields.password.field.value,
113
- }),
114
- redirect: 'follow',
115
- credentials: 'same-origin',
116
- headers: {
117
- 'Content-Type': 'application/json',
118
- },
119
- })];
120
- case 1:
121
- response = _a.sent();
122
- if (response.status != 200) {
123
- throw new Error("Failed to signup, error: ".concat(response.statusText));
124
- }
125
- return [4 /*yield*/, response.json()];
126
- case 2:
127
- body = _a.sent();
128
- if (body.error) {
129
- throw new Error(body.error);
130
- }
131
- return [2 /*return*/, "Successfully created your account! Please check your email for an email confirmation."];
132
- }
133
- });
134
- }); },
135
- },
136
- };
137
230
  //# sourceMappingURL=Signup.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Signup.js","sourceRoot":"","sources":["../../../src/pages/Signup.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,gDAA0B;AAC1B,oCAAkG;AAClG,wCAAyC;AAE5B,QAAA,UAAU,GAAS;IAC9B,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,QAAQ;IACd,IAAI,EAAE;QACJ,MAAM,EAAE,IAAI;KACb;IACD,SAAS,EAAE,cAAM,OAAA,CACf,8BAAC,aAAQ;QACP,8BAAC,SAAI,IACH,IAAI,EAAC,SAAS,EACd,YAAY,EAAE,cAAM,OAAA,IAAI,YAAY,EAAE,EAAlB,CAAkB,EACtC,WAAW,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,iBAAiB,CAAC,EAC7D,OAAO,EAAE,OAAO,GAChB,CACO,CACZ,EATgB,CAShB;CACF,CAAC;AAEF;IAA2B,gCAAM;IAAjC;QAAA,qEAsBC;QAjBC,UAAI,GAAG,IAAA,cAAS,EAAe;YAC7B,IAAI,EAAE,MAAM;SACb,CAAC,CAAC;QAEH,WAAK,GAAG,IAAA,cAAS,EAAe;YAC9B,IAAI,EAAE,OAAO;SACd,CAAC,CAAC;QAEH,cAAQ,GAAG,IAAA,cAAS,EAAe;YACjC,IAAI,EAAE,UAAU;YAChB,UAAU,EAAE,IAAI;SACjB,CAAC,CAAC;QAEH,qBAAe,GAAG,IAAA,cAAS,EAAe;YACxC,IAAI,EAAE,iBAAiB;YACvB,UAAU,EAAE,IAAI;SACjB,CAAC,CAAC;;IACL,CAAC;IArBQ,mBAAM,GAAb;QACE,OAAO,IAAI,YAAY,EAAE,CAAC;IAC5B,CAAC;IAmBH,mBAAC;AAAD,CAAC,AAtBD,CAA2B,WAAM,GAsBhC;AAED,IAAM,OAAO,GAA8B;IACzC,KAAK,EAAE,gBAAW;IAClB,MAAM,EAAE;QACN,IAAI,EAAE,SAAS;QACf,KAAK,EAAE;YACL,KAAK,EAAE,SAAS;YAChB,OAAO,EAAE,WAAW;SACrB;QACD,OAAO,EAAE,UAAO,MAAoB,EAAE,OAAkC;;;;4BACrD,qBAAM,KAAK,CAAC,aAAM,CAAC,UAAU,CAAC,IAAI,EAAE;4BACnD,MAAM,EAAE,aAAM,CAAC,UAAU,CAAC,MAAM;4BAChC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gCACnB,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK;gCAC7B,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK;gCAC/B,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK;6BACtC,CAAC;4BACF,QAAQ,EAAE,QAAQ;4BAClB,WAAW,EAAE,aAAa;4BAC1B,OAAO,EAAE;gCACP,cAAc,EAAE,kBAAkB;6BACnC;yBACF,CAAC,EAAA;;wBAZI,QAAQ,GAAG,SAYf;wBACF,IAAI,QAAQ,CAAC,MAAM,IAAI,GAAG,EAAE;4BAC1B,MAAM,IAAI,KAAK,CAAC,mCAA4B,QAAQ,CAAC,UAAU,CAAE,CAAC,CAAC;yBACpE;wBAEY,qBAAM,QAAQ,CAAC,IAAI,EAAE,EAAA;;wBAA5B,IAAI,GAAG,SAAqB;wBAClC,IAAI,IAAI,CAAC,KAAK,EAAE;4BACd,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;yBAC7B;wBAED,sBAAO,uFAAuF,EAAC;;;aAChG;KACF;CACF,CAAC"}
1
+ {"version":3,"file":"Signup.js","sourceRoot":"","sources":["../../../src/pages/Signup.tsx"],"names":[],"mappings":"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"}
@@ -6,35 +6,35 @@ import '@proteinjs/reflection';
6
6
  import '@proteinjs/server-api';
7
7
  import '@proteinjs/ui';
8
8
  import '@proteinjs/user';
9
+ import '@proteinjs/util';
9
10
  import 'moment';
10
11
  import 'react';
11
12
  import 'react-dom';
12
13
 
13
-
14
14
  /** Generate Source Graph */
15
15
 
16
- const sourceGraph = "{\"options\":{\"directed\":true,\"multigraph\":false,\"compound\":false},\"nodes\":[{\"v\":\"/Omit\"},{\"v\":\"@proteinjs/user-ui/forgotPasswordPage\",\"value\":{\"packageName\":\"@proteinjs/user-ui\",\"name\":\"forgotPasswordPage\",\"filePath\":\"/Users/brentbahry/workspaces/n3xa/packages/proteinjs/packages/user/packages/ui/src/pages/ForgotPassword.tsx\",\"qualifiedName\":\"@proteinjs/user-ui/forgotPasswordPage\",\"type\":{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/ui/Page\"},{\"v\":\"@proteinjs/user-ui/loginPage\",\"value\":{\"packageName\":\"@proteinjs/user-ui\",\"name\":\"loginPage\",\"filePath\":\"/Users/brentbahry/workspaces/n3xa/packages/proteinjs/packages/user/packages/ui/src/pages/Login.tsx\",\"qualifiedName\":\"@proteinjs/user-ui/loginPage\",\"type\":{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/user-ui/passwordResetPage\",\"value\":{\"packageName\":\"@proteinjs/user-ui\",\"name\":\"passwordResetPage\",\"filePath\":\"/Users/brentbahry/workspaces/n3xa/packages/proteinjs/packages/user/packages/ui/src/pages/PasswordReset.tsx\",\"qualifiedName\":\"@proteinjs/user-ui/passwordResetPage\",\"type\":{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/user-ui/signupPage\",\"value\":{\"packageName\":\"@proteinjs/user-ui\",\"name\":\"signupPage\",\"filePath\":\"/Users/brentbahry/workspaces/n3xa/packages/proteinjs/packages/user/packages/ui/src/pages/Signup.tsx\",\"qualifiedName\":\"@proteinjs/user-ui/signupPage\",\"type\":{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}}],\"edges\":[{\"v\":\"@proteinjs/user-ui/forgotPasswordPage\",\"w\":\"@proteinjs/ui/Page\",\"value\":\"has type\"},{\"v\":\"@proteinjs/user-ui/loginPage\",\"w\":\"@proteinjs/ui/Page\",\"value\":\"has type\"},{\"v\":\"@proteinjs/user-ui/passwordResetPage\",\"w\":\"@proteinjs/ui/Page\",\"value\":\"has type\"},{\"v\":\"@proteinjs/user-ui/signupPage\",\"w\":\"@proteinjs/ui/Page\",\"value\":\"has type\"}]}";
17
-
16
+ const sourceGraph =
17
+ '{"options":{"directed":true,"multigraph":false,"compound":false},"nodes":[{"v":"/Omit"},{"v":"@proteinjs/user-ui/forgotPasswordPage","value":{"packageName":"@proteinjs/user-ui","name":"forgotPasswordPage","filePath":"/home/runner/work/user/user/packages/ui/src/pages/ForgotPassword.tsx","qualifiedName":"@proteinjs/user-ui/forgotPasswordPage","type":{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":[{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":null}]},"isExported":true,"isConst":true,"sourceType":0}},{"v":"@proteinjs/ui/Page"},{"v":"@proteinjs/user-ui/loginPage","value":{"packageName":"@proteinjs/user-ui","name":"loginPage","filePath":"/home/runner/work/user/user/packages/ui/src/pages/Login.tsx","qualifiedName":"@proteinjs/user-ui/loginPage","type":{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":[{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":null}]},"isExported":true,"isConst":true,"sourceType":0}},{"v":"@proteinjs/user-ui/passwordResetPage","value":{"packageName":"@proteinjs/user-ui","name":"passwordResetPage","filePath":"/home/runner/work/user/user/packages/ui/src/pages/PasswordReset.tsx","qualifiedName":"@proteinjs/user-ui/passwordResetPage","type":{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":[{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":null}]},"isExported":true,"isConst":true,"sourceType":0}},{"v":"@proteinjs/user-ui/invitePage","value":{"packageName":"@proteinjs/user-ui","name":"invitePage","filePath":"/home/runner/work/user/user/packages/ui/src/pages/SendInvite.tsx","qualifiedName":"@proteinjs/user-ui/invitePage","type":{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":[{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":null}]},"isExported":true,"isConst":true,"sourceType":0}},{"v":"@proteinjs/user-ui/signupPage","value":{"packageName":"@proteinjs/user-ui","name":"signupPage","filePath":"/home/runner/work/user/user/packages/ui/src/pages/Signup.tsx","qualifiedName":"@proteinjs/user-ui/signupPage","type":{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":[{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":null}]},"isExported":true,"isConst":true,"sourceType":0}}],"edges":[{"v":"@proteinjs/user-ui/forgotPasswordPage","w":"@proteinjs/ui/Page","value":"has type"},{"v":"@proteinjs/user-ui/loginPage","w":"@proteinjs/ui/Page","value":"has type"},{"v":"@proteinjs/user-ui/passwordResetPage","w":"@proteinjs/ui/Page","value":"has type"},{"v":"@proteinjs/user-ui/invitePage","w":"@proteinjs/ui/Page","value":"has type"},{"v":"@proteinjs/user-ui/signupPage","w":"@proteinjs/ui/Page","value":"has type"}]}';
18
18
 
19
19
  /** Generate Source Links */
20
20
 
21
21
  import { forgotPasswordPage } from '../src/pages/ForgotPassword';
22
22
  import { loginPage } from '../src/pages/Login';
23
23
  import { passwordResetPage } from '../src/pages/PasswordReset';
24
+ import { invitePage } from '../src/pages/SendInvite';
24
25
  import { signupPage } from '../src/pages/Signup';
25
26
 
26
27
  const sourceLinks = {
27
- '@proteinjs/user-ui/forgotPasswordPage': forgotPasswordPage,
28
- '@proteinjs/user-ui/loginPage': loginPage,
29
- '@proteinjs/user-ui/passwordResetPage': passwordResetPage,
30
- '@proteinjs/user-ui/signupPage': signupPage,
28
+ '@proteinjs/user-ui/forgotPasswordPage': forgotPasswordPage,
29
+ '@proteinjs/user-ui/loginPage': loginPage,
30
+ '@proteinjs/user-ui/passwordResetPage': passwordResetPage,
31
+ '@proteinjs/user-ui/invitePage': invitePage,
32
+ '@proteinjs/user-ui/signupPage': signupPage,
31
33
  };
32
34
 
33
-
34
35
  /** Load Source Graph and Links */
35
36
 
36
37
  import { SourceRepository } from '@proteinjs/reflection';
37
38
  SourceRepository.merge(sourceGraph, sourceLinks);
38
39
 
39
-
40
- export * from '../index';
40
+ export * from '../index';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proteinjs/user-ui",
3
- "version": "1.0.41",
3
+ "version": "1.1.0",
4
4
  "description": "User ui components",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -23,16 +23,17 @@
23
23
  "dependencies": {
24
24
  "@mui/icons-material": "5.14.11",
25
25
  "@mui/material": "5.14.11",
26
- "@proteinjs/reflection": "1.1.7",
27
- "@proteinjs/server-api": "1.4.0",
28
- "@proteinjs/ui": "2.3.0",
29
- "@proteinjs/user": "^1.0.39",
26
+ "@proteinjs/reflection": "1.1.8",
27
+ "@proteinjs/server-api": "1.4.1",
28
+ "@proteinjs/ui": "2.4.1",
29
+ "@proteinjs/user": "^1.1.0",
30
+ "@proteinjs/util": "1.4.0",
30
31
  "moment": "2.29.4",
31
32
  "react": "18.2.0",
32
33
  "react-dom": "18.2.0"
33
34
  },
34
35
  "devDependencies": {
35
- "@proteinjs/reflection-build": "1.0.22",
36
+ "@proteinjs/reflection-build": "1.0.23",
36
37
  "@types/node": "14.0.13",
37
38
  "@types/react": "18.2.23",
38
39
  "@types/react-dom": "18.2.8",
@@ -44,5 +45,6 @@
44
45
  "typescript": "5.2.2"
45
46
  },
46
47
  "main": "./dist/generated/index.js",
47
- "types": "./dist/generated/index.d.ts"
48
- }
48
+ "types": "./dist/generated/index.d.ts",
49
+ "gitHead": "bdc34d9e39b0a90babc5f7fe1ca764077c574b1a"
50
+ }
@@ -1,7 +1,6 @@
1
1
  import React from 'react';
2
2
  import { Page, PageContainer, PageContainerProps } from '@proteinjs/ui';
3
- import { routes, guestUser, UserAuth, UserRepo } from '@proteinjs/user';
4
- import { loginPath } from './pages/Login';
3
+ import { routes, guestUser, UserAuth, UserRepo, uiRoutes } from '@proteinjs/user';
5
4
 
6
5
  export type AuthenticatedPageContainerProps = Omit<PageContainerProps, 'auth'>;
7
6
 
@@ -28,7 +27,7 @@ export function AuthenticatedPageContainer(props: AuthenticatedPageContainerProp
28
27
 
29
28
  return UserAuth.hasRoles(page.auth?.roles);
30
29
  },
31
- login: loginPath,
30
+ login: uiRoutes.auth.login,
32
31
  logout: async () => {
33
32
  const response = await fetch(routes.logout.path, {
34
33
  method: routes.logout.method,
@@ -44,7 +43,7 @@ export function AuthenticatedPageContainer(props: AuthenticatedPageContainerProp
44
43
 
45
44
  new UserRepo().setUser(guestUser);
46
45
  setIsLoggedIn(false);
47
- return loginPath;
46
+ return uiRoutes.auth.login;
48
47
  },
49
48
  }}
50
49
  {...other}
@@ -1,12 +1,10 @@
1
1
  import React from 'react';
2
2
  import { Page, Form, Fields, textField, FormButtons, FormPage } from '@proteinjs/ui';
3
- import { routes } from '@proteinjs/user';
4
- import { passwordResetPath } from './PasswordReset';
3
+ import { routes, uiRoutes } from '@proteinjs/user';
5
4
 
6
- export const forgotPasswordPath = 'login/forgot-password';
7
5
  export const forgotPasswordPage: Page = {
8
6
  name: 'Forgot Password',
9
- path: forgotPasswordPath,
7
+ path: uiRoutes.auth.forgotPassword,
10
8
  auth: {
11
9
  public: true,
12
10
  },
@@ -44,7 +42,6 @@ const buttons: FormButtons<ForgotPasswordFields> = {
44
42
  method: routes.initiatePasswordReset.method,
45
43
  body: JSON.stringify({
46
44
  email: fields.email.field.value,
47
- resetPath: passwordResetPath,
48
45
  }),
49
46
  redirect: 'follow',
50
47
  credentials: 'same-origin',
@@ -1,11 +1,10 @@
1
1
  import React from 'react';
2
2
  import { Page, Form, Fields, textField, FormButtons, clearButton, FormPage } from '@proteinjs/ui';
3
- import { routes } from '@proteinjs/user';
3
+ import { routes, uiRoutes } from '@proteinjs/user';
4
4
 
5
- export const loginPath = 'login';
6
5
  export const loginPage: Page = {
7
6
  name: 'Login',
8
- path: loginPath,
7
+ path: uiRoutes.auth.login,
9
8
  auth: {
10
9
  public: true,
11
10
  },
@@ -45,7 +44,7 @@ const buttons: FormButtons<LoginFields> = {
45
44
  align: 'left',
46
45
  },
47
46
  redirect: async () => {
48
- return { path: '/login/forgot-password' };
47
+ return { path: `/${uiRoutes.auth.forgotPassword}` };
49
48
  },
50
49
  },
51
50
  clear: clearButton,
@@ -1,9 +1,8 @@
1
1
  import React, { useEffect, useState } from 'react';
2
2
  import { Page, Form, Fields, textField, FormButtons, FormPage } from '@proteinjs/ui';
3
- import { routes } from '@proteinjs/user';
3
+ import { routes, uiRoutes } from '@proteinjs/user';
4
4
  import { Button, Stack, Typography } from '@mui/material';
5
5
 
6
- export const passwordResetPath = 'login/password-reset';
7
6
  const PasswordResetComponent: React.FC = () => {
8
7
  const [token, setToken] = useState('');
9
8
  const [isValidating, setIsValidating] = useState(false);
@@ -130,7 +129,7 @@ const PasswordResetComponent: React.FC = () => {
130
129
 
131
130
  export const passwordResetPage: Page = {
132
131
  name: 'Reset Password',
133
- path: passwordResetPath,
132
+ path: uiRoutes.auth.passwordReset,
134
133
  auth: {
135
134
  public: true,
136
135
  },
@@ -0,0 +1,111 @@
1
+ import React from 'react';
2
+ import { Page, Form, Fields, textField, FormButtons, FormPage } from '@proteinjs/ui';
3
+ import { getSignupService, uiRoutes } from '@proteinjs/user';
4
+ import { emailRegex } from '@proteinjs/util';
5
+ import { Stack } from '@mui/material';
6
+
7
+ export const invitePage: Page = {
8
+ name: 'Send an Invite',
9
+ path: uiRoutes.admin.invite,
10
+ auth: {
11
+ roles: ['admin'],
12
+ },
13
+ component: () => (
14
+ <Stack direction='column' spacing={4} mt={2}>
15
+ <FormPage gridItemProps={{ width: '400px' }}>
16
+ <Form<InviteFields, typeof buttons>
17
+ name='Send an Invite'
18
+ createFields={() => new InviteFields()}
19
+ fieldLayout={['email']}
20
+ buttons={buttons}
21
+ />
22
+ </FormPage>
23
+
24
+ <FormPage gridItemProps={{ width: '400px' }}>
25
+ <Form<RevokeInviteFields, typeof revokeInviteButtons>
26
+ name='Revoke an Invite'
27
+ createFields={() => new RevokeInviteFields()}
28
+ fieldLayout={['email']}
29
+ buttons={revokeInviteButtons}
30
+ />
31
+ </FormPage>
32
+ </Stack>
33
+ ),
34
+ };
35
+
36
+ class InviteFields extends Fields {
37
+ static create() {
38
+ return new InviteFields();
39
+ }
40
+
41
+ email = textField<InviteFields>({
42
+ name: 'email',
43
+ });
44
+ }
45
+
46
+ const buttons: FormButtons<InviteFields> = {
47
+ signup: {
48
+ name: 'Send',
49
+ style: {
50
+ color: 'primary',
51
+ variant: 'contained',
52
+ },
53
+ onClick: async (fields: InviteFields, buttons: FormButtons<InviteFields>) => {
54
+ const email = fields.email.field.value && fields.email.field.value.trim();
55
+
56
+ if (!email) {
57
+ return 'Please enter an email address.';
58
+ }
59
+
60
+ if (!emailRegex.test(email)) {
61
+ return 'Please enter a valid email address.';
62
+ }
63
+
64
+ const response = await getSignupService().sendInvite(email);
65
+ if (response.sent === false) {
66
+ return response.error || 'Failed to send invite.';
67
+ }
68
+
69
+ return `Successfully sent invite to ${email}!`;
70
+ },
71
+ },
72
+ };
73
+
74
+ class RevokeInviteFields extends Fields {
75
+ static create() {
76
+ return new InviteFields();
77
+ }
78
+
79
+ email = textField<InviteFields>({
80
+ name: 'email',
81
+ });
82
+ }
83
+
84
+ const revokeInviteButtons: FormButtons<RevokeInviteFields> = {
85
+ signup: {
86
+ name: 'Revoke',
87
+ style: {
88
+ color: 'primary',
89
+ variant: 'contained',
90
+ },
91
+ onClick: async (fields: RevokeInviteFields, buttons: FormButtons<RevokeInviteFields>) => {
92
+ const email = fields.email.field.value && fields.email.field.value.trim();
93
+
94
+ if (!email) {
95
+ return 'Please enter an email address.';
96
+ }
97
+
98
+ if (!emailRegex.test(email)) {
99
+ return 'Please enter a valid email address.';
100
+ }
101
+
102
+ try {
103
+ await getSignupService().revokeInvite(email);
104
+ } catch {
105
+ return `Revoke invite failed.`;
106
+ }
107
+
108
+ return `Successfully revoked invite to ${email}.`;
109
+ },
110
+ },
111
+ };