bananas-commerce-admin 0.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 (188) hide show
  1. package/README.md +25 -0
  2. package/dist/cjs/Admin.js +47 -0
  3. package/dist/cjs/App.js +49 -0
  4. package/dist/cjs/api.js +225 -0
  5. package/dist/cjs/components/Branding.js +41 -0
  6. package/dist/cjs/components/Hamburger.js +40 -0
  7. package/dist/cjs/components/Link.js +21 -0
  8. package/dist/cjs/components/Logo.js +25 -0
  9. package/dist/cjs/components/NavBar.js +101 -0
  10. package/dist/cjs/components/NavBarItem.js +42 -0
  11. package/dist/cjs/components/NavBarRoutes.js +47 -0
  12. package/dist/cjs/components/ProgressBar.js +14 -0
  13. package/dist/cjs/components/User.js +71 -0
  14. package/dist/cjs/containers/Content.js +16 -0
  15. package/dist/cjs/containers/ErrorScreen.js +35 -0
  16. package/dist/cjs/containers/LoadingScreen.js +84 -0
  17. package/dist/cjs/containers/PageErrorBoundary.js +43 -0
  18. package/dist/cjs/containers/PageLoader.js +123 -0
  19. package/dist/cjs/contexts/ApiContext.js +105 -0
  20. package/dist/cjs/contexts/I18nContext.js +109 -0
  21. package/dist/cjs/contexts/RouterContext.js +99 -0
  22. package/dist/cjs/contexts/UserContext.js +144 -0
  23. package/dist/cjs/extensions/bananas/components/PasswordChangeForm.js +85 -0
  24. package/dist/cjs/extensions/bananas/index.js +54 -0
  25. package/dist/cjs/extensions/bananas/pages/me/list.js +20 -0
  26. package/dist/cjs/extensions/pos/components/PurchaseRow.js +32 -0
  27. package/dist/cjs/extensions/pos/components/ReceiptCard.js +86 -0
  28. package/dist/cjs/extensions/pos/components/ReceiptLine.js +29 -0
  29. package/dist/cjs/extensions/pos/index.js +22 -0
  30. package/dist/cjs/extensions/pos/pages/purchase/detail.js +13 -0
  31. package/dist/cjs/extensions/pos/pages/purchase/list.js +34 -0
  32. package/dist/cjs/extensions/pos/types/purchase.js +2 -0
  33. package/dist/cjs/extensions/pos/types/receipt.js +2 -0
  34. package/dist/cjs/forms/LoginForm.js +63 -0
  35. package/dist/cjs/hooks/useAsyncError.js +15 -0
  36. package/dist/cjs/hooks/useLocalStorage.js +47 -0
  37. package/dist/cjs/index.js +40 -0
  38. package/dist/cjs/pages/DashboardPage.js +10 -0
  39. package/dist/cjs/pages/LoginPage.js +31 -0
  40. package/dist/cjs/router/Router.js +35 -0
  41. package/dist/cjs/router/routes.js +57 -0
  42. package/dist/cjs/types/index.js +2 -0
  43. package/dist/cjs/util/get_cookie.js +10 -0
  44. package/dist/cjs/util/index.js +62 -0
  45. package/dist/cjs/util/select_styles.js +38 -0
  46. package/dist/esm/Admin.js +42 -0
  47. package/dist/esm/App.js +44 -0
  48. package/dist/esm/api.js +219 -0
  49. package/dist/esm/components/Branding.js +36 -0
  50. package/dist/esm/components/Hamburger.js +35 -0
  51. package/dist/esm/components/Link.js +16 -0
  52. package/dist/esm/components/Logo.js +20 -0
  53. package/dist/esm/components/NavBar.js +73 -0
  54. package/dist/esm/components/NavBarItem.js +37 -0
  55. package/dist/esm/components/NavBarRoutes.js +42 -0
  56. package/dist/esm/components/ProgressBar.js +9 -0
  57. package/dist/esm/components/User.js +66 -0
  58. package/dist/esm/containers/Content.js +11 -0
  59. package/dist/esm/containers/ErrorScreen.js +30 -0
  60. package/dist/esm/containers/LoadingScreen.js +79 -0
  61. package/dist/esm/containers/PageErrorBoundary.js +38 -0
  62. package/dist/esm/containers/PageLoader.js +117 -0
  63. package/dist/esm/contexts/ApiContext.js +77 -0
  64. package/dist/esm/contexts/I18nContext.js +77 -0
  65. package/dist/esm/contexts/RouterContext.js +71 -0
  66. package/dist/esm/contexts/UserContext.js +113 -0
  67. package/dist/esm/extensions/bananas/components/PasswordChangeForm.js +80 -0
  68. package/dist/esm/extensions/bananas/index.js +48 -0
  69. package/dist/esm/extensions/bananas/pages/me/list.js +15 -0
  70. package/dist/esm/extensions/pos/components/PurchaseRow.js +25 -0
  71. package/dist/esm/extensions/pos/components/ReceiptCard.js +56 -0
  72. package/dist/esm/extensions/pos/components/ReceiptLine.js +22 -0
  73. package/dist/esm/extensions/pos/index.js +16 -0
  74. package/dist/esm/extensions/pos/pages/purchase/detail.js +8 -0
  75. package/dist/esm/extensions/pos/pages/purchase/list.js +29 -0
  76. package/dist/esm/extensions/pos/types/purchase.js +1 -0
  77. package/dist/esm/extensions/pos/types/receipt.js +1 -0
  78. package/dist/esm/forms/LoginForm.js +58 -0
  79. package/dist/esm/hooks/useAsyncError.js +9 -0
  80. package/dist/esm/hooks/useLocalStorage.js +41 -0
  81. package/dist/esm/index.js +14 -0
  82. package/dist/esm/pages/DashboardPage.js +5 -0
  83. package/dist/esm/pages/LoginPage.js +26 -0
  84. package/dist/esm/router/Router.js +28 -0
  85. package/dist/esm/router/routes.js +49 -0
  86. package/dist/esm/types/index.js +1 -0
  87. package/dist/esm/util/get_cookie.js +6 -0
  88. package/dist/esm/util/index.js +54 -0
  89. package/dist/esm/util/select_styles.js +34 -0
  90. package/dist/types/Admin.d.ts +13 -0
  91. package/dist/types/App.d.ts +13 -0
  92. package/dist/types/api.d.ts +20 -0
  93. package/dist/types/components/Branding.d.ts +14 -0
  94. package/dist/types/components/Hamburger.d.ts +8 -0
  95. package/dist/types/components/Link.d.ts +9 -0
  96. package/dist/types/components/Logo.d.ts +7 -0
  97. package/dist/types/components/NavBar.d.ts +11 -0
  98. package/dist/types/components/NavBarItem.d.ts +12 -0
  99. package/dist/types/components/NavBarRoutes.d.ts +7 -0
  100. package/dist/types/components/ProgressBar.d.ts +7 -0
  101. package/dist/types/components/User.d.ts +824 -0
  102. package/dist/types/containers/Content.d.ts +3 -0
  103. package/dist/types/containers/ErrorScreen.d.ts +7 -0
  104. package/dist/types/containers/LoadingScreen.d.ts +50 -0
  105. package/dist/types/containers/PageErrorBoundary.d.ts +16 -0
  106. package/dist/types/containers/PageLoader.d.ts +13 -0
  107. package/dist/types/contexts/ApiContext.d.ts +12 -0
  108. package/dist/types/contexts/I18nContext.d.ts +10 -0
  109. package/dist/types/contexts/RouterContext.d.ts +24 -0
  110. package/dist/types/contexts/UserContext.d.ts +20 -0
  111. package/dist/types/extensions/bananas/components/PasswordChangeForm.d.ts +3 -0
  112. package/dist/types/extensions/bananas/index.d.ts +2 -0
  113. package/dist/types/extensions/bananas/pages/me/list.d.ts +6 -0
  114. package/dist/types/extensions/pos/components/PurchaseRow.d.ts +7 -0
  115. package/dist/types/extensions/pos/components/ReceiptCard.d.ts +7 -0
  116. package/dist/types/extensions/pos/components/ReceiptLine.d.ts +7 -0
  117. package/dist/types/extensions/pos/index.d.ts +2 -0
  118. package/dist/types/extensions/pos/pages/purchase/detail.d.ts +7 -0
  119. package/dist/types/extensions/pos/pages/purchase/list.d.ts +9 -0
  120. package/dist/types/extensions/pos/types/purchase.d.ts +18 -0
  121. package/dist/types/extensions/pos/types/receipt.d.ts +34 -0
  122. package/dist/types/forms/LoginForm.d.ts +3 -0
  123. package/dist/types/hooks/useAsyncError.d.ts +1 -0
  124. package/dist/types/hooks/useLocalStorage.d.ts +2 -0
  125. package/dist/types/index.d.ts +14 -0
  126. package/dist/types/pages/DashboardPage.d.ts +5 -0
  127. package/dist/types/pages/LoginPage.d.ts +9 -0
  128. package/dist/types/router/Router.d.ts +13 -0
  129. package/dist/types/router/routes.d.ts +20 -0
  130. package/dist/types/types/index.d.ts +6 -0
  131. package/dist/types/util/get_cookie.d.ts +1 -0
  132. package/dist/types/util/index.d.ts +8 -0
  133. package/dist/types/util/select_styles.d.ts +3 -0
  134. package/example/Dockerfile +27 -0
  135. package/example/docker-compose.yml +7 -0
  136. package/example/index.html +13 -0
  137. package/example/index.tsx +21 -0
  138. package/example/package-lock.json +13167 -0
  139. package/example/package.json +52 -0
  140. package/example/pages/.gitkeep +0 -0
  141. package/example/webpack.config.js +67 -0
  142. package/package.json +52 -0
  143. package/src/Admin.tsx +94 -0
  144. package/src/App.tsx +43 -0
  145. package/src/api.ts +202 -0
  146. package/src/components/Branding.tsx +79 -0
  147. package/src/components/Hamburger.tsx +41 -0
  148. package/src/components/Link.tsx +23 -0
  149. package/src/components/Logo.tsx +57 -0
  150. package/src/components/NavBar.tsx +115 -0
  151. package/src/components/NavBarItem.tsx +73 -0
  152. package/src/components/NavBarRoutes.tsx +67 -0
  153. package/src/components/ProgressBar.tsx +30 -0
  154. package/src/components/User.tsx +97 -0
  155. package/src/containers/Content.tsx +18 -0
  156. package/src/containers/ErrorScreen.tsx +64 -0
  157. package/src/containers/LoadingScreen.tsx +135 -0
  158. package/src/containers/PageErrorBoundary.tsx +32 -0
  159. package/src/containers/PageLoader.tsx +64 -0
  160. package/src/contexts/ApiContext.tsx +55 -0
  161. package/src/contexts/I18nContext.tsx +55 -0
  162. package/src/contexts/RouterContext.tsx +127 -0
  163. package/src/contexts/UserContext.tsx +99 -0
  164. package/src/extensions/bananas/components/PasswordChangeForm.tsx +138 -0
  165. package/src/extensions/bananas/index.ts +14 -0
  166. package/src/extensions/bananas/pages/me/list.tsx +31 -0
  167. package/src/extensions/pos/components/PurchaseRow.tsx +42 -0
  168. package/src/extensions/pos/components/ReceiptCard.tsx +101 -0
  169. package/src/extensions/pos/components/ReceiptLine.tsx +51 -0
  170. package/src/extensions/pos/index.tsx +20 -0
  171. package/src/extensions/pos/pages/purchase/detail.tsx +22 -0
  172. package/src/extensions/pos/pages/purchase/list.tsx +56 -0
  173. package/src/extensions/pos/types/purchase.ts +20 -0
  174. package/src/extensions/pos/types/receipt.ts +36 -0
  175. package/src/forms/LoginForm.tsx +99 -0
  176. package/src/hooks/useAsyncError.ts +13 -0
  177. package/src/hooks/useLocalStorage.ts +42 -0
  178. package/src/index.ts +18 -0
  179. package/src/pages/DashboardPage.tsx +9 -0
  180. package/src/pages/LoginPage.tsx +50 -0
  181. package/src/router/Router.tsx +63 -0
  182. package/src/router/routes.ts +67 -0
  183. package/src/types/index.ts +4 -0
  184. package/src/types/swagger-client.d.ts +1 -0
  185. package/src/util/get_cookie.ts +6 -0
  186. package/src/util/index.ts +63 -0
  187. package/src/util/select_styles.ts +29 -0
  188. package/tsconfig.json +38 -0
@@ -0,0 +1,219 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __generator = (this && this.__generator) || function (thisArg, body) {
11
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
12
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
13
+ function verb(n) { return function (v) { return step([n, v]); }; }
14
+ function step(op) {
15
+ if (f) throw new TypeError("Generator is already executing.");
16
+ while (_) try {
17
+ 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;
18
+ if (y = 0, t) op = [op[0] & 2, t.value];
19
+ switch (op[0]) {
20
+ case 0: case 1: t = op; break;
21
+ case 4: _.label++; return { value: op[1], done: false };
22
+ case 5: _.label++; y = op[1]; op = [0]; continue;
23
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
24
+ default:
25
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
26
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
27
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
28
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
29
+ if (t[2]) _.ops.pop();
30
+ _.trys.pop(); continue;
31
+ }
32
+ op = body.call(thisArg, _);
33
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
34
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
+ }
36
+ };
37
+ import SwaggerParser from "@apidevtools/swagger-parser";
38
+ import { getCookie } from "./util/get_cookie";
39
+ var ApiOperation = /** @class */ (function () {
40
+ function ApiOperation(id, tags, server, endpoint, method, request, summary, description) {
41
+ this.id = id;
42
+ this.tags = tags;
43
+ this.server = server;
44
+ this.endpoint = endpoint;
45
+ this.method = method;
46
+ this.request = request;
47
+ this.summary = summary;
48
+ this.description = description;
49
+ }
50
+ ApiOperation.prototype.call = function (request, init) {
51
+ var _a, _b;
52
+ return __awaiter(this, void 0, void 0, function () {
53
+ var endpoint, csrftoken, _i, _c, _d, name_1, value, url, _e, _f, _g, name_2, value;
54
+ return __generator(this, function (_h) {
55
+ switch (_h.label) {
56
+ case 0:
57
+ endpoint = this.endpoint;
58
+ csrftoken = getCookie("csrftoken");
59
+ init !== null && init !== void 0 ? init : (init = {});
60
+ (_a = init.method) !== null && _a !== void 0 ? _a : (init.method = this.method);
61
+ init.headers = new Headers(init.headers);
62
+ if (csrftoken !== undefined)
63
+ init.headers.append("X-CSRFToken", csrftoken);
64
+ init.credentials = "include";
65
+ // Add body to request
66
+ if ((request === null || request === void 0 ? void 0 : request.body) !== undefined) {
67
+ (_b = init.body) !== null && _b !== void 0 ? _b : (init.body = JSON.stringify(request === null || request === void 0 ? void 0 : request.body));
68
+ }
69
+ // Add params to url
70
+ if ((request === null || request === void 0 ? void 0 : request.params) !== undefined) {
71
+ for (_i = 0, _c = Object.entries(request.params); _i < _c.length; _i++) {
72
+ _d = _c[_i], name_1 = _d[0], value = _d[1];
73
+ endpoint = endpoint.replace("{".concat(name_1, "}"), value);
74
+ }
75
+ }
76
+ url = new URL(this.server + endpoint);
77
+ // Add query to url
78
+ if ((request === null || request === void 0 ? void 0 : request.query) !== undefined) {
79
+ for (_e = 0, _f = Object.entries(request.query); _e < _f.length; _e++) {
80
+ _g = _f[_e], name_2 = _g[0], value = _g[1];
81
+ url.searchParams.append(name_2, value);
82
+ }
83
+ }
84
+ return [4 /*yield*/, fetch(url, init)];
85
+ case 1: return [2 /*return*/, _h.sent()];
86
+ }
87
+ });
88
+ });
89
+ };
90
+ return ApiOperation;
91
+ }());
92
+ export { ApiOperation };
93
+ var ApiClient = /** @class */ (function () {
94
+ function ApiClient(document, server) {
95
+ var _a, _b, _c, _d, _e, _f, _g, _h;
96
+ this.operations = {};
97
+ this.document = document;
98
+ // If the document uses servers and it is not manually set this will be prepended to path later
99
+ if ("servers" in this.document && this.document.servers !== undefined &&
100
+ this.document.servers.length >= 1) {
101
+ server !== null && server !== void 0 ? server : (server = this.document.servers.pop().url);
102
+ }
103
+ // Make sure the server variable is an URL
104
+ if (server !== undefined && !(server instanceof URL)) {
105
+ server = new URL(server);
106
+ }
107
+ // Build operations
108
+ for (var _i = 0, _j = Object.entries((_a = this.document.paths) !== null && _a !== void 0 ? _a : {}); _i < _j.length; _i++) {
109
+ var _k = _j[_i], path = _k[0], definition = _k[1];
110
+ for (var _l = 0, _m = Object.entries(definition); _l < _m.length; _l++) {
111
+ var _o = _m[_l], method = _o[0], operation = _o[1];
112
+ // All operations require an operation id
113
+ if (!operation.operationId) {
114
+ break;
115
+ }
116
+ // Check if an tag starting with `app:` exists on the operation
117
+ if (!((_b = operation.tags) === null || _b === void 0 ? void 0 : _b.some(function (tag) { return tag.startsWith("app:"); }))) {
118
+ break;
119
+ }
120
+ var request = {};
121
+ // Fill the request object with `path`, `query` and `body` data which may be provided
122
+ for (var _p = 0, _q = (_c = operation.parameters) !== null && _c !== void 0 ? _c : []; _p < _q.length; _p++) {
123
+ var parameter = _q[_p];
124
+ if ("in" in parameter) {
125
+ switch (parameter.in) {
126
+ case "body": {
127
+ request["body"] = {
128
+ required: (_d = parameter.required) !== null && _d !== void 0 ? _d : false,
129
+ schema: parameter.schema,
130
+ };
131
+ break;
132
+ }
133
+ case "path": {
134
+ (_e = request["params"]) !== null && _e !== void 0 ? _e : (request["params"] = {});
135
+ request["params"][parameter.name] = {
136
+ // Path parameters are always required: https://swagger.io/docs/specification/describing-parameters/#path-parameters
137
+ required: true,
138
+ schema: parameter.schema,
139
+ };
140
+ break;
141
+ }
142
+ case "query": {
143
+ (_f = request["query"]) !== null && _f !== void 0 ? _f : (request["query"] = {});
144
+ request["query"][parameter.name] = {
145
+ required: (_g = parameter.required) !== null && _g !== void 0 ? _g : false,
146
+ schema: parameter.schema,
147
+ };
148
+ }
149
+ }
150
+ }
151
+ }
152
+ // If `requestBody` exists then add it to the request objects body object
153
+ if ("requestBody" in operation && operation.requestBody !== undefined) {
154
+ if ("content" in operation.requestBody) {
155
+ var schema = operation.requestBody.content["application/json"].schema;
156
+ var required = (_h = operation.requestBody.required) !== null && _h !== void 0 ? _h : false;
157
+ request["body"] = {
158
+ schema: schema,
159
+ required: required,
160
+ };
161
+ }
162
+ }
163
+ // Combine base url and path
164
+ server = server ? server.toString() : "";
165
+ if (server.endsWith("/")) {
166
+ server = server.slice(0, -1);
167
+ }
168
+ var endpoint = path.startsWith("/") ? path : "/" + path;
169
+ // Create a new `ApiOperation` with the relevant information
170
+ this.operations[operation.operationId] = new ApiOperation(operation.operationId, operation.tags, server, endpoint, method, request, operation.summary, operation.description);
171
+ }
172
+ }
173
+ }
174
+ ApiClient.load = function (source, server) {
175
+ return __awaiter(this, void 0, void 0, function () {
176
+ var response, schema, document;
177
+ return __generator(this, function (_a) {
178
+ switch (_a.label) {
179
+ case 0: return [4 /*yield*/, fetch(source)];
180
+ case 1:
181
+ response = _a.sent();
182
+ if (!response.ok) {
183
+ throw new Error("Could not load schema from ".concat(source));
184
+ }
185
+ return [4 /*yield*/, response.json().catch(function (e) {
186
+ throw e;
187
+ })];
188
+ case 2:
189
+ schema = _a.sent();
190
+ return [4 /*yield*/, SwaggerParser.dereference(schema)];
191
+ case 3:
192
+ document = _a.sent();
193
+ return [2 /*return*/, new ApiClient(document, server)];
194
+ }
195
+ });
196
+ });
197
+ };
198
+ ApiClient.prototype.isAuthenticated = function () {
199
+ return __awaiter(this, void 0, void 0, function () {
200
+ var response, _a;
201
+ return __generator(this, function (_b) {
202
+ switch (_b.label) {
203
+ case 0:
204
+ _b.trys.push([0, 2, , 3]);
205
+ return [4 /*yield*/, this.operations["bananas.me:list"].call()];
206
+ case 1:
207
+ response = _b.sent();
208
+ return [2 /*return*/, response.ok];
209
+ case 2:
210
+ _a = _b.sent();
211
+ return [2 /*return*/, false];
212
+ case 3: return [2 /*return*/];
213
+ }
214
+ });
215
+ });
216
+ };
217
+ return ApiClient;
218
+ }());
219
+ export { ApiClient };
@@ -0,0 +1,36 @@
1
+ import React from "react";
2
+ import Box from "@mui/material/Box";
3
+ import ButtonBase from "@mui/material/ButtonBase";
4
+ import Typography from "@mui/material/Typography";
5
+ import { ss } from "../util/select_styles";
6
+ import Logo from "./Logo";
7
+ var Branding = function (_a) {
8
+ var logo = _a.logo, title = _a.title, subtitle = _a.subtitle, version = _a.version, onClick = _a.onClick, fullWidth = _a.fullWidth, sx = _a.sx;
9
+ return (React.createElement(Box, { sx: ss({
10
+ display: "flex",
11
+ flexDirection: "row",
12
+ alignItems: "center",
13
+ flexGrow: 1,
14
+ }, [{ width: "100%" }, fullWidth !== null && fullWidth !== void 0 ? fullWidth : false], sx) },
15
+ React.createElement(ButtonBase, { sx: {
16
+ justifyContent: "flex-start",
17
+ width: "100%",
18
+ height: "100%",
19
+ padding: 0,
20
+ }, color: "inherit", onClick: onClick },
21
+ logo ? React.createElement(Logo, { src: logo }) : (React.createElement(Typography, { sx: {
22
+ fontWeight: "bold",
23
+ }, color: "inherit", variant: "h4" }, title)),
24
+ React.createElement(Box, { sx: {
25
+ marginLeft: 10,
26
+ "& > *": {
27
+ textAlign: "left",
28
+ fontSize: "0.75rem",
29
+ display: "block",
30
+ lineHeight: "1em",
31
+ },
32
+ } },
33
+ React.createElement(Typography, { color: "inherit" }, subtitle),
34
+ React.createElement(Typography, { color: "inherit" }, version)))));
35
+ };
36
+ export default Branding;
@@ -0,0 +1,35 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ var __rest = (this && this.__rest) || function (s, e) {
13
+ var t = {};
14
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
15
+ t[p] = s[p];
16
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
17
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
18
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
19
+ t[p[i]] = s[p[i]];
20
+ }
21
+ return t;
22
+ };
23
+ import React from "react";
24
+ import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
25
+ import MenuIcon from "@mui/icons-material/Menu";
26
+ import Box from "@mui/material/Box";
27
+ import IconButton from "@mui/material/IconButton";
28
+ import { useTheme } from "@mui/material/styles";
29
+ var Hamburger = function (_a) {
30
+ var open = _a.open, onToggle = _a.onToggle, rest = __rest(_a, ["open", "onToggle"]);
31
+ var theme = useTheme();
32
+ return (React.createElement(Box, { sx: __assign({ display: "flex", alignItems: "center", justifyContent: "flex-start", padding: theme.spacing(0, 1), flexShrink: 1 }, theme.mixins.toolbar) },
33
+ React.createElement(IconButton, __assign({ "aria-label": open ? "Close drawer" : "Open drawer", color: "inherit", onClick: onToggle }, rest, { size: "large" }), open ? React.createElement(ChevronLeftIcon, null) : React.createElement(MenuIcon, null))));
34
+ };
35
+ export default Hamburger;
@@ -0,0 +1,16 @@
1
+ import { useRouter } from "../contexts/RouterContext";
2
+ import { Link as RouterLink } from "react-router-dom";
3
+ import React from "react";
4
+ var Link = function (_a) {
5
+ var route = _a.route;
6
+ var getRoute = useRouter().getRoute;
7
+ if (typeof route === "string") {
8
+ var routeInfo = getRoute(route);
9
+ if (routeInfo === undefined) {
10
+ throw new Error("Could not find route with reverse: ".concat(route));
11
+ }
12
+ route = routeInfo;
13
+ }
14
+ return React.createElement(RouterLink, { to: route.path });
15
+ };
16
+ export default Link;
@@ -0,0 +1,20 @@
1
+ import React from "react";
2
+ var Logo = function (_a) {
3
+ var src = _a.src;
4
+ if (src === true) {
5
+ return (React.createElement("svg", { version: "1.1", id: "bananas", x: "0px", y: "0px", width: "32px", height: "32px", viewBox: "0 0 927.611 927.611", xmlSpace: "preserve", xmlns: "http://www.w3.org/2000/svg", xmlnsXlink: "http://www.w3.org/1999/xlink" },
6
+ React.createElement("g", { fill: "#FFFFFF" },
7
+ React.createElement("path", { d: "M158.56,618.97l2.4-0.7c97-26.199,181.6-59.8,251.2-99.8c94.5-54.3,159.4-119.5,193-193.799l16-35.4l-28.699,26.2\n\t\t\tc-57,52.1-134.801,91-231.4,115.8c-81.9,21-176,31.7-279.8,31.7c-5.4,0-17.4-0.1-24.6-0.2l-16.9-0.8c-13.3-0.6-25.4,7.6-29.8,20.2\n\t\t\tl-6.6,19.1c-3.9,11.301-0.7,23.9,8.2,32c7.4,6.7,14.9,13.2,14.9,13.2s56,48.5,129.6,71.7L158.56,618.97z" }),
8
+ React.createElement("path", { d: "M811.86,163.17c-29.1-13.4-56.899-15.4-70.899-15.4c-1.801,0-3.5,0-4.9,0.1c-3.2-11.2-19.4-78.1-30.7-124.9\n\t\t\tc-5.2-21.5-31.1-30.2-48.2-16.1l-53.6,44.2c-14,11.5-16.9,31.7-6.7,46.7c22.4,32.9,59.5,91.7,77.7,144.8\n\t\t\tc17.2,50.3,18.7,102.9,10.5,154.6c-13.4,83.7-57.6,168.2-131.4,251.2c-40.199,45.2-84.699,86.399-132.199,123.7\n\t\t\tc-23.801,18.699-48.4,36.399-73.7,53c-2.601,1.699-32.7,19.399-53.601,30.199c-11.699,6-18.1,19-15.8,31.9l2.5,14\n\t\t\tc2.4,13.4,13.5,23.5,27,24.6c34.3,2.9,105.101,4.801,199.7-13.899c51.8-10.2,101.8-34.5,148.2-62.101\n\t\t\tc78.1-46.6,182.8-131.399,238.1-271c24.7-62.3,35.2-126.699,31.2-191.599c-3.9-63.8-20.7-112.4-34.1-142\n\t\t\tC873.66,206.771,847.06,179.271,811.86,163.17z" }),
9
+ React.createElement("path", { d: "M109.46,744.97c13.1,8.101,34.4,19.8,60.3,28.4c44.5,14.8,91.8,21.2,138.5,22.7l2.6,0.1l2.101-1.4\n\t\t\tc34.5-23.1,67.3-47.3,97.6-71.899c37.7-30.7,71.5-62.2,100.5-93.601c26.3-28.5,50.6-58.899,71.4-91.6\n\t\t\tc18.199-28.6,33.699-59.1,44.8-91.2c5.2-15,9.5-30.399,12.399-46.1c3-15.9,4.4-32.1,6.5-48.2c0.4-3.2,0.801-6.3,1.2-9.5\n\t\t\tl-19.899,33.9c-41.7,71.199-110.5,133.699-204.601,186c-61.2,34.1-126.8,60.1-193.6,81.199c-36.4,11.5-71.6,21.601-108.6,27.301\n\t\t\tc-14.6,2.199-25.3,14.8-25.3,29.6c0,6.4,0,13.1,0,18.9C95.36,729.87,100.66,739.47,109.46,744.97z" }))));
10
+ }
11
+ if (typeof src === "string") {
12
+ return React.createElement("img", { src: src });
13
+ }
14
+ if (src) {
15
+ var Src = src;
16
+ return React.createElement(Src, null);
17
+ }
18
+ return null;
19
+ };
20
+ export default Logo;
@@ -0,0 +1,73 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ import * as React from "react";
13
+ import { useTheme } from "@mui/material/styles";
14
+ import Box from "@mui/material/Box";
15
+ import Drawer from "@mui/material/Drawer";
16
+ import Divider from "@mui/material/Divider";
17
+ import User from "./User";
18
+ import Hamburger from "./Hamburger";
19
+ import NavBarRoutes from "./NavBarRoutes";
20
+ import Branding from "./Branding";
21
+ import { useNavigate } from "react-router-dom";
22
+ var drawerWidth = 240;
23
+ var openedMixin = function (theme) { return ({
24
+ width: drawerWidth,
25
+ transition: theme.transitions.create("width", {
26
+ easing: theme.transitions.easing.sharp,
27
+ duration: theme.transitions.duration.enteringScreen,
28
+ }),
29
+ overflowX: "hidden",
30
+ }); };
31
+ var closedMixin = function (theme) {
32
+ var _a;
33
+ return (_a = {
34
+ transition: theme.transitions.create("width", {
35
+ easing: theme.transitions.easing.sharp,
36
+ duration: theme.transitions.duration.leavingScreen,
37
+ }),
38
+ overflowX: "hidden",
39
+ width: "calc(".concat(theme.spacing(7), " + 1px)")
40
+ },
41
+ _a[theme.breakpoints.up("sm")] = {
42
+ width: "calc(".concat(theme.spacing(8), " + 1px)"),
43
+ },
44
+ _a);
45
+ };
46
+ var NavBar = function (_a) {
47
+ var nav = _a.nav, logo = _a.logo, title = _a.title, subtitle = _a.subtitle, version = _a.version;
48
+ var theme = useTheme();
49
+ var navigate = useNavigate();
50
+ var _b = React.useState(true), open = _b[0], setOpen = _b[1];
51
+ var toggleDrawerOpen = function () {
52
+ setOpen(!open);
53
+ };
54
+ var onClick = function () {
55
+ navigate("/", { replace: true });
56
+ };
57
+ return (React.createElement(Drawer, { sx: __assign(__assign({ width: drawerWidth, flexShrink: 0, whiteSpace: "nowrap", boxSizing: "border-box" }, (open && __assign(__assign({}, openedMixin(theme)), { "& .MuiDrawer-paper": openedMixin(theme) }))), (!open && __assign(__assign({}, closedMixin(theme)), { "& .MuiDrawer-paper": closedMixin(theme) }))), anchor: "left", variant: "permanent", open: open },
58
+ React.createElement(Box, { sx: { display: "flex", padding: theme.spacing(2, 0, 2) } },
59
+ React.createElement(Hamburger, { open: open, onClick: toggleDrawerOpen }),
60
+ React.createElement(Branding, { sx: { opacity: open ? 1 : 0 }, logo: logo, title: title, subtitle: subtitle, version: version, onClick: onClick, fullWidth: open })),
61
+ React.createElement(Box, { sx: {
62
+ flexGrow: 1,
63
+ flexShrink: 0,
64
+ } },
65
+ React.createElement(NavBarRoutes, { nav: nav, open: open })),
66
+ React.createElement(Box, { sx: {
67
+ flexGrow: 0,
68
+ flexShrink: 0,
69
+ } },
70
+ React.createElement(Divider, null),
71
+ React.createElement(User, { open: open }))));
72
+ };
73
+ export default NavBar;
@@ -0,0 +1,37 @@
1
+ import { useTheme } from "@mui/material/styles";
2
+ import ListItem from "@mui/material/ListItem";
3
+ import ListItemButton from "@mui/material/ListItemButton";
4
+ import ListItemIcon from "@mui/material/ListItemIcon";
5
+ import ListItemText from "@mui/material/ListItemText";
6
+ import React from "react";
7
+ import { useLocation } from "react-router-dom";
8
+ import { useRouter } from "../contexts/RouterContext";
9
+ import Logo from "./Logo";
10
+ var NavBarItem = function (_a) {
11
+ var route = _a.route, title = _a.title, subtitle = _a.subtitle, icon = _a.icon, children = _a.children, open = _a.open;
12
+ var Icon = icon;
13
+ var _b = React.useState(false), selected = _b[0], setSelected = _b[1];
14
+ var location = useLocation();
15
+ var navigate = useRouter().navigate;
16
+ var theme = useTheme();
17
+ var onClick = function () {
18
+ navigate(route);
19
+ };
20
+ React.useEffect(function () {
21
+ setSelected(location.pathname === route.path);
22
+ }, [location]);
23
+ return (React.createElement(ListItem, { onClick: onClick, key: route.id, disablePadding: true, sx: { display: "block" } },
24
+ React.createElement(ListItemButton, { selected: selected, sx: {
25
+ minHeight: 48,
26
+ justifyContent: open ? "initial" : "center",
27
+ px: 2.5,
28
+ } },
29
+ React.createElement(ListItemIcon, { sx: {
30
+ minWidth: 0,
31
+ justifyContent: "center",
32
+ padding: theme.spacing(1, 1),
33
+ } }, Icon !== undefined ? React.createElement(Logo, { src: Icon }) : title.substring(0, 1)),
34
+ React.createElement(ListItemText, { sx: { opacity: open ? 1 : 0 }, primary: title, secondary: subtitle }),
35
+ children)));
36
+ };
37
+ export default NavBarItem;
@@ -0,0 +1,42 @@
1
+ import List from "@mui/material/List";
2
+ import React from "react";
3
+ import { useRouter } from "../contexts/RouterContext";
4
+ import NavBarItem from "./NavBarItem";
5
+ function groupRoutesByApp(routes) {
6
+ var _a;
7
+ var _b;
8
+ var groupedRoutes = {};
9
+ for (var _i = 0, routes_1 = routes; _i < routes_1.length; _i++) {
10
+ var route = routes_1[_i];
11
+ (_a = groupedRoutes[_b = route.app]) !== null && _a !== void 0 ? _a : (groupedRoutes[_b] = []);
12
+ groupedRoutes[route.app].push(route);
13
+ }
14
+ return groupedRoutes;
15
+ }
16
+ var NavBarRoutes = function (_a) {
17
+ var nav = _a.nav, open = _a.open;
18
+ var routes = useRouter().routes;
19
+ var navItems = React.useMemo(function () {
20
+ var apps = [];
21
+ var groupedRoutes = groupRoutesByApp(routes);
22
+ for (var _i = 0, _a = Object.keys(groupedRoutes); _i < _a.length; _i++) {
23
+ var app = _a[_i];
24
+ var appRoutes = groupedRoutes[app];
25
+ var appItems = [];
26
+ for (var _b = 0, appRoutes_1 = appRoutes; _b < appRoutes_1.length; _b++) {
27
+ var route = appRoutes_1[_b];
28
+ if (route.navigation) {
29
+ appItems.push(React.createElement(NavBarItem, { key: route.id, route: route, title: route.title, open: open }));
30
+ }
31
+ }
32
+ apps.push(React.createElement(List, { key: app }, appItems));
33
+ }
34
+ return apps;
35
+ }, [
36
+ routes,
37
+ nav,
38
+ open,
39
+ ]);
40
+ return (React.createElement(React.Fragment, null, navItems));
41
+ };
42
+ export default NavBarRoutes;
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import { LinearProgress } from "@mui/material";
3
+ var ProgressBar = function (_a) {
4
+ var loading = _a.loading, color = _a.color;
5
+ loading !== null && loading !== void 0 ? loading : (loading = true);
6
+ color !== null && color !== void 0 ? color : (color = "secondary");
7
+ return (loading && React.createElement(LinearProgress, { color: color }));
8
+ };
9
+ export default ProgressBar;
@@ -0,0 +1,66 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ import React from "react";
13
+ import AccountCircleIcon from "@mui/icons-material/AccountCircle";
14
+ import ButtonBase from "@mui/material/ButtonBase";
15
+ import List from "@mui/material/List";
16
+ import { useTheme } from "@mui/material/styles";
17
+ import Typography from "@mui/material/Typography";
18
+ import { useUser } from "../contexts/UserContext";
19
+ import NavBarItem from "./NavBarItem";
20
+ import { ss } from "../util/select_styles";
21
+ import { useRouter } from "../contexts/RouterContext";
22
+ var styles = function (theme) { return ({
23
+ root: __assign({ display: "flex", padding: 0, borderTopWidth: 1, borderTopStyle: "solid", borderTopColor: theme.palette.divider }, theme.mixins.toolbar),
24
+ link: {
25
+ fontSize: "inherit",
26
+ "& > *": {
27
+ fontSize: "0.9em",
28
+ },
29
+ },
30
+ drawerLink: {
31
+ "&:hover": {
32
+ color: theme.palette.primary.main,
33
+ opacity: 1,
34
+ },
35
+ },
36
+ appbarLink: {
37
+ "&:hover": {
38
+ color: theme.palette.secondary.light,
39
+ opacity: 1,
40
+ },
41
+ },
42
+ }); };
43
+ var User = function (_a) {
44
+ var classes = _a.classes, open = _a.open, icon = _a.icon;
45
+ var _b = useUser(), user = _b.user, logout = _b.logout;
46
+ var _c = useRouter(), routes = _c.routes, getRoute = _c.getRoute;
47
+ classes !== null && classes !== void 0 ? classes : (classes = styles(useTheme()));
48
+ var UserIcon = icon !== null && icon !== void 0 ? icon : AccountCircleIcon;
49
+ var _d = React.useMemo(function () {
50
+ var route = getRoute("bananas.me:list");
51
+ return [
52
+ route,
53
+ getRoute("bananas.logout:create").title,
54
+ (route === null || route === void 0 ? void 0 : route.path) === window.location.pathname,
55
+ ];
56
+ }, [routes]), route = _d[0], logoutText = _d[1], selected = _d[2];
57
+ return (user !== null && route !== undefined
58
+ ? (React.createElement(List, null,
59
+ React.createElement(NavBarItem, { route: route, open: open, icon: UserIcon, title: user.full_name, subtitle: React.createElement(ButtonBase, { sx: ss(classes.link, classes.drawerLink), onClick: function (e) {
60
+ e.preventDefault();
61
+ logout();
62
+ } },
63
+ React.createElement(Typography, { color: "inherit" }, logoutText)) })))
64
+ : null);
65
+ };
66
+ export default User;
@@ -0,0 +1,11 @@
1
+ import { Box } from "@mui/material";
2
+ import React from "react";
3
+ var Content = function (_a) {
4
+ var children = _a.children;
5
+ return (React.createElement(Box, { sx: {
6
+ display: "flex",
7
+ position: "relative",
8
+ flexGrow: 1,
9
+ } }, children));
10
+ };
11
+ export default Content;
@@ -0,0 +1,30 @@
1
+ import React from "react";
2
+ import Box from "@mui/material/Box";
3
+ import Card from "@mui/material/Card";
4
+ import CardContent from "@mui/material/CardContent";
5
+ import { useTheme } from "@mui/material/styles";
6
+ import { Button, CardActions, Typography } from "@mui/material";
7
+ import { useI18n } from "../contexts/I18nContext";
8
+ import { useUser } from "../contexts/UserContext";
9
+ var errorMessages = {
10
+ 403: "You are authenticated as %(username)s, but are not authorized to access this page. Would you like to login to a different account?",
11
+ 404: "We're sorry, but the requested page could not be found.",
12
+ };
13
+ var ErrorScreen = function (_a) {
14
+ var _b, _c;
15
+ var error = _a.error;
16
+ var t = useI18n().t;
17
+ var _d = useUser(), user = _d.user, logout = _d.logout;
18
+ var theme = useTheme();
19
+ return (React.createElement(Card, null,
20
+ React.createElement(CardContent, null,
21
+ React.createElement(Typography, { variant: "h4" }, error.message),
22
+ React.createElement(Typography, null, t(error.response.status >= 500
23
+ ? "There's been an error. It's been reported to the site administrators via email and should be fixed shortly. Thanks for your patience."
24
+ : (_b = errorMessages[error.response.status]) !== null && _b !== void 0 ? _b : "", (_c = user) !== null && _c !== void 0 ? _c : {}))),
25
+ React.createElement(CardActions, null, error.response.status === 403 && (React.createElement(Box, { sx: { marginTop: theme.spacing(3), textAlign: "right" } },
26
+ React.createElement(Button, { variant: "contained", color: "secondary", onClick: function () {
27
+ return logout();
28
+ }, sx: { boxShadow: "none" } }, t("Log in again")))))));
29
+ };
30
+ export default ErrorScreen;