afront 1.0.25 → 1.0.26

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 (45) hide show
  1. package/.babelrc +13 -13
  2. package/.env +1 -1
  3. package/LICENSE +21 -21
  4. package/README.md +94 -94
  5. package/build-prod/manifest.json +25 -25
  6. package/build-prod/offline.html +1023 -1023
  7. package/build-prod/robots.txt +3 -3
  8. package/build-prod-static/manifest.json +25 -25
  9. package/build-prod-static/offline.html +1023 -1023
  10. package/build-prod-static/robots.txt +3 -3
  11. package/install.js +518 -415
  12. package/package.json +102 -102
  13. package/server.js +40 -40
  14. package/src/ARoutes/AFRoutes.js +28 -28
  15. package/src/Api/api.config.js +266 -266
  16. package/src/Api/login.service.js +44 -44
  17. package/src/App.js +28 -28
  18. package/src/Components/Background/MeshGradient.js +18 -18
  19. package/src/Components/Footer/Footer.js +108 -108
  20. package/src/Components/Header/Header.js +149 -149
  21. package/src/Components/Loading/LoadingIndicator.js +12 -12
  22. package/src/Components/Loading/LoadingIndicator.module.css +34 -34
  23. package/src/Components/Loading/LoadingSpinner.js +27 -27
  24. package/src/Components/Loading/LoadingSpinner.module.css +100 -100
  25. package/src/Components/RequireAuth.js +29 -29
  26. package/src/LoadingFallback.js +13 -13
  27. package/src/PageNotFound.js +19 -19
  28. package/src/Pages/Home.js +50 -50
  29. package/src/Pages/Signup.js +230 -230
  30. package/src/Pages/Support.js +68 -68
  31. package/src/Routes/ARoutes.js +66 -66
  32. package/src/Routes/ARoutesStatic.js +83 -83
  33. package/src/Static/appStatic.js +16 -16
  34. package/src/Static/indexStatic.js +13 -13
  35. package/src/Style/App.module.css +11 -11
  36. package/src/Style/MeshGradient.module.css +130 -130
  37. package/src/Style/PageNotFound.module.css +37 -37
  38. package/src/Style/Style.module.css +686 -686
  39. package/src/Style/Support.module.css +185 -185
  40. package/src/Utils/LoadingContext.js +5 -5
  41. package/src/index.js +25 -25
  42. package/webpack.build-prod.js +141 -141
  43. package/webpack.dev.js +127 -127
  44. package/webpack.prod.js +148 -148
  45. package/webpack.ssr.prod.js +97 -97
@@ -1,266 +1,266 @@
1
- // Lightweight fetch-based API instance with interceptors and retry helper
2
- const apiBase =
3
- (typeof process !== "undefined" &&
4
- process.env &&
5
- process.env.REACT_APP_API_BASE) ||
6
- (typeof window !== "undefined" &&
7
- window.__env &&
8
- window.__env.REACT_APP_API_BASE) ||
9
- "http://localhost:4000/api/v1";
10
-
11
- function isAbsoluteUrl(u) {
12
- return /^https?:\/\//i.test(u);
13
- }
14
-
15
- function buildUrl(base, url, params) {
16
- const full = isAbsoluteUrl(url) ? url : `${base}${url}`;
17
- if (!params) return full;
18
- const search = new URLSearchParams(params).toString();
19
- return search ? `${full}${full.includes("?") ? "&" : "?"}${search}` : full;
20
- }
21
-
22
- function createInstance({
23
- baseURL = apiBase,
24
- timeout = 60000,
25
- headers = { "Content-Type": "application/json" },
26
- withCredentials = true,
27
- } = {}) {
28
- const requestHandlers = [];
29
- const responseHandlers = [];
30
-
31
- const interceptors = {
32
- request: {
33
- use: (fn) => {
34
- requestHandlers.push(fn);
35
- return requestHandlers.length - 1;
36
- },
37
- },
38
- response: {
39
- use: (onFulfilled, onRejected) => {
40
- responseHandlers.push({ onFulfilled, onRejected });
41
- return responseHandlers.length - 1;
42
- },
43
- },
44
- };
45
-
46
- async function runRequestHandlers(cfg) {
47
- let c = { ...cfg };
48
- for (const h of requestHandlers) {
49
- // handlers may be sync or async
50
- // allow them to modify/return the config
51
- // if they return undefined, assume they mutated in place
52
- // otherwise use returned value
53
- // eslint-disable-next-line no-await-in-loop
54
- const out = await h(c);
55
- if (typeof out !== "undefined") c = out;
56
- }
57
- return c;
58
- }
59
-
60
- async function runResponseHandlers(resOrErr, success = true) {
61
- let acc = resOrErr;
62
- for (const h of responseHandlers) {
63
- try {
64
- if (success && typeof h.onFulfilled === "function") {
65
- // eslint-disable-next-line no-await-in-loop
66
- const out = await h.onFulfilled(acc);
67
- if (typeof out !== "undefined") acc = out;
68
- } else if (!success && typeof h.onRejected === "function") {
69
- // eslint-disable-next-line no-await-in-loop
70
- const out = await h.onRejected(acc);
71
- if (typeof out !== "undefined") acc = out;
72
- }
73
- } catch (e) {
74
- // if a handler throws, treat as rejection
75
- acc = e;
76
- success = false;
77
- }
78
- }
79
- if (success) return acc;
80
- throw acc;
81
- }
82
-
83
- async function request(cfg) {
84
- const finalCfg = await runRequestHandlers({
85
- baseURL,
86
- timeout,
87
- headers: { ...headers },
88
- withCredentials,
89
- ...cfg,
90
- });
91
-
92
- const url = buildUrl(
93
- finalCfg.baseURL || baseURL,
94
- finalCfg.url || finalCfg.path || "/",
95
- finalCfg.params
96
- );
97
-
98
- const controller = new AbortController();
99
- const to = finalCfg.timeout || timeout;
100
- const timer = setTimeout(() => controller.abort(), to);
101
-
102
- const fetchOpts = {
103
- method: (finalCfg.method || "GET").toUpperCase(),
104
- headers: finalCfg.headers || {},
105
- signal: controller.signal,
106
- };
107
- if (finalCfg.withCredentials || finalCfg.withCredentials === undefined)
108
- fetchOpts.credentials = "include";
109
- if (finalCfg.body !== undefined && finalCfg.body !== null) {
110
- fetchOpts.body = finalCfg.body;
111
- }
112
-
113
- try {
114
- // log request for convenience
115
- // allow user interceptors to already log as requested
116
- const raw = await fetch(url, fetchOpts);
117
- clearTimeout(timer);
118
-
119
- // try to parse JSON, fallback to text
120
- let data = null;
121
- const ct = raw.headers.get("content-type") || "";
122
- if (ct.includes("application/json")) {
123
- try {
124
- data = await raw.json();
125
- } catch (e) {
126
- data = null;
127
- }
128
- } else {
129
- try {
130
- data = await raw.text();
131
- } catch (e) {
132
- data = null;
133
- }
134
- }
135
-
136
- const response = { ok: raw.ok, status: raw.status, data, raw };
137
- return await runResponseHandlers(response, true);
138
- } catch (err) {
139
- clearTimeout(timer);
140
- // network or abort
141
- return await runResponseHandlers(err, false);
142
- }
143
- }
144
-
145
- // convenience methods
146
- const instance = {
147
- interceptors,
148
- request,
149
- get: (url, cfg = {}) => request({ method: "GET", url, ...cfg }),
150
- post: (url, body, cfg = {}) =>
151
- request({
152
- method: "POST",
153
- url,
154
- body:
155
- typeof body === "object" && !(body instanceof FormData)
156
- ? JSON.stringify(body)
157
- : body,
158
- headers: {
159
- ...(cfg.headers || {}),
160
- "Content-Type":
161
- body instanceof FormData ? undefined : "application/json",
162
- },
163
- ...cfg,
164
- }),
165
- put: (url, body, cfg = {}) =>
166
- request({
167
- method: "PUT",
168
- url,
169
- body:
170
- typeof body === "object" && !(body instanceof FormData)
171
- ? JSON.stringify(body)
172
- : body,
173
- headers: {
174
- ...(cfg.headers || {}),
175
- "Content-Type":
176
- body instanceof FormData ? undefined : "application/json",
177
- },
178
- ...cfg,
179
- }),
180
- patch: (url, body, cfg = {}) =>
181
- request({
182
- method: "PATCH",
183
- url,
184
- body:
185
- typeof body === "object" && !(body instanceof FormData)
186
- ? JSON.stringify(body)
187
- : body,
188
- headers: {
189
- ...(cfg.headers || {}),
190
- "Content-Type":
191
- body instanceof FormData ? undefined : "application/json",
192
- },
193
- ...cfg,
194
- }),
195
- delete: (url, cfg = {}) => request({ method: "DELETE", url, ...cfg }),
196
- };
197
-
198
- return instance;
199
- }
200
-
201
- export function requestWithRetry(
202
- fn,
203
- { retries = 3, retryDelay = 1000, retryOn = (err) => true } = {}
204
- ) {
205
- return new Promise(async (resolve, reject) => {
206
- let attempt = 0;
207
- while (attempt < retries) {
208
- try {
209
- // fn should be a function returning a promise
210
- const res = await fn();
211
- return resolve(res);
212
- } catch (err) {
213
- attempt += 1;
214
- if (attempt >= retries || !retryOn(err)) return reject(err);
215
- // exponential backoff
216
- // eslint-disable-next-line no-await-in-loop
217
- await new Promise((r) => setTimeout(r, retryDelay * attempt));
218
- }
219
- }
220
- reject(new Error("Retries exhausted"));
221
- });
222
- }
223
-
224
- export const instance = createInstance({
225
- baseURL: apiBase,
226
- timeout: 60000,
227
- headers: { "Content-Type": "application/json" },
228
- withCredentials: true,
229
- });
230
-
231
- // expose defaults for logging/compatibility
232
- instance.defaults = { baseURL: apiBase, timeout: 60000 };
233
-
234
- // request logging interceptor
235
- instance.interceptors.request.use((config) => {
236
- try {
237
- console.log(
238
- `API Request -> ${(
239
- (config.method || "").toString() || "GET"
240
- ).toUpperCase()} ${config.url || config.path} (base: ${
241
- instance.defaults.baseURL
242
- }) (timeout: ${config.timeout || instance.defaults.timeout}ms)`
243
- );
244
- } catch (e) {
245
- /* ignore */
246
- }
247
- return config;
248
- });
249
-
250
- // response / error logging interceptor
251
- instance.interceptors.response.use(
252
- (response) => response,
253
- (error) => {
254
- if (!error || !error.status) {
255
- console.error(
256
- "Network or CORS error when calling API:",
257
- error && error.message ? error.message : error
258
- );
259
- } else {
260
- console.warn("API response error:", error.status, error.data);
261
- }
262
- return Promise.reject(error);
263
- }
264
- );
265
-
266
- export default instance;
1
+ // Lightweight fetch-based API instance with interceptors and retry helper
2
+ const apiBase =
3
+ (typeof process !== "undefined" &&
4
+ process.env &&
5
+ process.env.REACT_APP_API_BASE) ||
6
+ (typeof window !== "undefined" &&
7
+ window.__env &&
8
+ window.__env.REACT_APP_API_BASE) ||
9
+ "http://localhost:4000/api/v1";
10
+
11
+ function isAbsoluteUrl(u) {
12
+ return /^https?:\/\//i.test(u);
13
+ }
14
+
15
+ function buildUrl(base, url, params) {
16
+ const full = isAbsoluteUrl(url) ? url : `${base}${url}`;
17
+ if (!params) return full;
18
+ const search = new URLSearchParams(params).toString();
19
+ return search ? `${full}${full.includes("?") ? "&" : "?"}${search}` : full;
20
+ }
21
+
22
+ function createInstance({
23
+ baseURL = apiBase,
24
+ timeout = 60000,
25
+ headers = { "Content-Type": "application/json" },
26
+ withCredentials = true,
27
+ } = {}) {
28
+ const requestHandlers = [];
29
+ const responseHandlers = [];
30
+
31
+ const interceptors = {
32
+ request: {
33
+ use: (fn) => {
34
+ requestHandlers.push(fn);
35
+ return requestHandlers.length - 1;
36
+ },
37
+ },
38
+ response: {
39
+ use: (onFulfilled, onRejected) => {
40
+ responseHandlers.push({ onFulfilled, onRejected });
41
+ return responseHandlers.length - 1;
42
+ },
43
+ },
44
+ };
45
+
46
+ async function runRequestHandlers(cfg) {
47
+ let c = { ...cfg };
48
+ for (const h of requestHandlers) {
49
+ // handlers may be sync or async
50
+ // allow them to modify/return the config
51
+ // if they return undefined, assume they mutated in place
52
+ // otherwise use returned value
53
+ // eslint-disable-next-line no-await-in-loop
54
+ const out = await h(c);
55
+ if (typeof out !== "undefined") c = out;
56
+ }
57
+ return c;
58
+ }
59
+
60
+ async function runResponseHandlers(resOrErr, success = true) {
61
+ let acc = resOrErr;
62
+ for (const h of responseHandlers) {
63
+ try {
64
+ if (success && typeof h.onFulfilled === "function") {
65
+ // eslint-disable-next-line no-await-in-loop
66
+ const out = await h.onFulfilled(acc);
67
+ if (typeof out !== "undefined") acc = out;
68
+ } else if (!success && typeof h.onRejected === "function") {
69
+ // eslint-disable-next-line no-await-in-loop
70
+ const out = await h.onRejected(acc);
71
+ if (typeof out !== "undefined") acc = out;
72
+ }
73
+ } catch (e) {
74
+ // if a handler throws, treat as rejection
75
+ acc = e;
76
+ success = false;
77
+ }
78
+ }
79
+ if (success) return acc;
80
+ throw acc;
81
+ }
82
+
83
+ async function request(cfg) {
84
+ const finalCfg = await runRequestHandlers({
85
+ baseURL,
86
+ timeout,
87
+ headers: { ...headers },
88
+ withCredentials,
89
+ ...cfg,
90
+ });
91
+
92
+ const url = buildUrl(
93
+ finalCfg.baseURL || baseURL,
94
+ finalCfg.url || finalCfg.path || "/",
95
+ finalCfg.params
96
+ );
97
+
98
+ const controller = new AbortController();
99
+ const to = finalCfg.timeout || timeout;
100
+ const timer = setTimeout(() => controller.abort(), to);
101
+
102
+ const fetchOpts = {
103
+ method: (finalCfg.method || "GET").toUpperCase(),
104
+ headers: finalCfg.headers || {},
105
+ signal: controller.signal,
106
+ };
107
+ if (finalCfg.withCredentials || finalCfg.withCredentials === undefined)
108
+ fetchOpts.credentials = "include";
109
+ if (finalCfg.body !== undefined && finalCfg.body !== null) {
110
+ fetchOpts.body = finalCfg.body;
111
+ }
112
+
113
+ try {
114
+ // log request for convenience
115
+ // allow user interceptors to already log as requested
116
+ const raw = await fetch(url, fetchOpts);
117
+ clearTimeout(timer);
118
+
119
+ // try to parse JSON, fallback to text
120
+ let data = null;
121
+ const ct = raw.headers.get("content-type") || "";
122
+ if (ct.includes("application/json")) {
123
+ try {
124
+ data = await raw.json();
125
+ } catch (e) {
126
+ data = null;
127
+ }
128
+ } else {
129
+ try {
130
+ data = await raw.text();
131
+ } catch (e) {
132
+ data = null;
133
+ }
134
+ }
135
+
136
+ const response = { ok: raw.ok, status: raw.status, data, raw };
137
+ return await runResponseHandlers(response, true);
138
+ } catch (err) {
139
+ clearTimeout(timer);
140
+ // network or abort
141
+ return await runResponseHandlers(err, false);
142
+ }
143
+ }
144
+
145
+ // convenience methods
146
+ const instance = {
147
+ interceptors,
148
+ request,
149
+ get: (url, cfg = {}) => request({ method: "GET", url, ...cfg }),
150
+ post: (url, body, cfg = {}) =>
151
+ request({
152
+ method: "POST",
153
+ url,
154
+ body:
155
+ typeof body === "object" && !(body instanceof FormData)
156
+ ? JSON.stringify(body)
157
+ : body,
158
+ headers: {
159
+ ...(cfg.headers || {}),
160
+ "Content-Type":
161
+ body instanceof FormData ? undefined : "application/json",
162
+ },
163
+ ...cfg,
164
+ }),
165
+ put: (url, body, cfg = {}) =>
166
+ request({
167
+ method: "PUT",
168
+ url,
169
+ body:
170
+ typeof body === "object" && !(body instanceof FormData)
171
+ ? JSON.stringify(body)
172
+ : body,
173
+ headers: {
174
+ ...(cfg.headers || {}),
175
+ "Content-Type":
176
+ body instanceof FormData ? undefined : "application/json",
177
+ },
178
+ ...cfg,
179
+ }),
180
+ patch: (url, body, cfg = {}) =>
181
+ request({
182
+ method: "PATCH",
183
+ url,
184
+ body:
185
+ typeof body === "object" && !(body instanceof FormData)
186
+ ? JSON.stringify(body)
187
+ : body,
188
+ headers: {
189
+ ...(cfg.headers || {}),
190
+ "Content-Type":
191
+ body instanceof FormData ? undefined : "application/json",
192
+ },
193
+ ...cfg,
194
+ }),
195
+ delete: (url, cfg = {}) => request({ method: "DELETE", url, ...cfg }),
196
+ };
197
+
198
+ return instance;
199
+ }
200
+
201
+ export function requestWithRetry(
202
+ fn,
203
+ { retries = 3, retryDelay = 1000, retryOn = (err) => true } = {}
204
+ ) {
205
+ return new Promise(async (resolve, reject) => {
206
+ let attempt = 0;
207
+ while (attempt < retries) {
208
+ try {
209
+ // fn should be a function returning a promise
210
+ const res = await fn();
211
+ return resolve(res);
212
+ } catch (err) {
213
+ attempt += 1;
214
+ if (attempt >= retries || !retryOn(err)) return reject(err);
215
+ // exponential backoff
216
+ // eslint-disable-next-line no-await-in-loop
217
+ await new Promise((r) => setTimeout(r, retryDelay * attempt));
218
+ }
219
+ }
220
+ reject(new Error("Retries exhausted"));
221
+ });
222
+ }
223
+
224
+ export const instance = createInstance({
225
+ baseURL: apiBase,
226
+ timeout: 60000,
227
+ headers: { "Content-Type": "application/json" },
228
+ withCredentials: true,
229
+ });
230
+
231
+ // expose defaults for logging/compatibility
232
+ instance.defaults = { baseURL: apiBase, timeout: 60000 };
233
+
234
+ // request logging interceptor
235
+ instance.interceptors.request.use((config) => {
236
+ try {
237
+ console.log(
238
+ `API Request -> ${(
239
+ (config.method || "").toString() || "GET"
240
+ ).toUpperCase()} ${config.url || config.path} (base: ${
241
+ instance.defaults.baseURL
242
+ }) (timeout: ${config.timeout || instance.defaults.timeout}ms)`
243
+ );
244
+ } catch (e) {
245
+ /* ignore */
246
+ }
247
+ return config;
248
+ });
249
+
250
+ // response / error logging interceptor
251
+ instance.interceptors.response.use(
252
+ (response) => response,
253
+ (error) => {
254
+ if (!error || !error.status) {
255
+ console.error(
256
+ "Network or CORS error when calling API:",
257
+ error && error.message ? error.message : error
258
+ );
259
+ } else {
260
+ console.warn("API response error:", error.status, error.data);
261
+ }
262
+ return Promise.reject(error);
263
+ }
264
+ );
265
+
266
+ export default instance;
@@ -1,44 +1,44 @@
1
- import api from "./api.config.js";
2
-
3
- const BASE = "/auth";
4
-
5
- export async function login({ email, password }) {
6
- return api.post(
7
- `${BASE}/login`,
8
- { email, password },
9
- { withCredentials: true }
10
- );
11
- }
12
-
13
- export async function signup({
14
- email,
15
- password,
16
- name,
17
- accountType,
18
- companyName,
19
- }) {
20
- return api.post(
21
- `${BASE}/signup`,
22
- { email, password, name, accountType, companyName },
23
- { withCredentials: true }
24
- );
25
- }
26
-
27
- export async function checkSignup({ email }) {
28
- return api.post(`${BASE}/check`, { email }, { withCredentials: true });
29
- }
30
-
31
- export async function logout() {
32
- try {
33
- await api.post(`${BASE}/logout`, null, { withCredentials: true });
34
- } catch (e) {
35
- /* ignore */
36
- }
37
- try {
38
- localStorage.setItem("auth-event", String(Date.now()));
39
- } catch (e) {}
40
- window.dispatchEvent(new Event("auth-changed"));
41
- return { ok: true };
42
- }
43
-
44
- export default { login, signup, logout, checkSignup };
1
+ import api from "./api.config.js";
2
+
3
+ const BASE = "/auth";
4
+
5
+ export async function login({ email, password }) {
6
+ return api.post(
7
+ `${BASE}/login`,
8
+ { email, password },
9
+ { withCredentials: true }
10
+ );
11
+ }
12
+
13
+ export async function signup({
14
+ email,
15
+ password,
16
+ name,
17
+ accountType,
18
+ companyName,
19
+ }) {
20
+ return api.post(
21
+ `${BASE}/signup`,
22
+ { email, password, name, accountType, companyName },
23
+ { withCredentials: true }
24
+ );
25
+ }
26
+
27
+ export async function checkSignup({ email }) {
28
+ return api.post(`${BASE}/check`, { email }, { withCredentials: true });
29
+ }
30
+
31
+ export async function logout() {
32
+ try {
33
+ await api.post(`${BASE}/logout`, null, { withCredentials: true });
34
+ } catch (e) {
35
+ /* ignore */
36
+ }
37
+ try {
38
+ localStorage.setItem("auth-event", String(Date.now()));
39
+ } catch (e) {}
40
+ window.dispatchEvent(new Event("auth-changed"));
41
+ return { ok: true };
42
+ }
43
+
44
+ export default { login, signup, logout, checkSignup };
package/src/App.js CHANGED
@@ -1,29 +1,29 @@
1
- import React, { useState } from "react";
2
- import ARoutes from "./Routes/ARoutes";
3
- import LoadingContext from "./Utils/LoadingContext";
4
-
5
- const isProduction = process.env.NODE_ENV === "production";
6
-
7
- const Tail = () => (
8
- <asggen
9
- className="hidden"
10
- dangerouslySetInnerHTML={{
11
- __html: `Rendering Asggen DOM...</asggen></asggenapp></body></html>`,
12
- }}
13
- />
14
- );
15
-
16
- function App({ context }) {
17
- const [loading, setLoading] = useState(false);
18
- return (
19
- <>
20
- <LoadingContext.Provider value={{ loading, setLoading }}>
21
- {loading && <LoadingIndicator />}
22
- <ARoutes context={context} />
23
- {isProduction ? <Tail /> : null}
24
- </LoadingContext.Provider>
25
- </>
26
- );
27
- }
28
-
1
+ import React, { useState } from "react";
2
+ import ARoutes from "./Routes/ARoutes";
3
+ import LoadingContext from "./Utils/LoadingContext";
4
+
5
+ const isProduction = process.env.NODE_ENV === "production";
6
+
7
+ const Tail = () => (
8
+ <asggen
9
+ className="hidden"
10
+ dangerouslySetInnerHTML={{
11
+ __html: `Rendering Asggen DOM...</asggen></asggenapp></body></html>`,
12
+ }}
13
+ />
14
+ );
15
+
16
+ function App({ context }) {
17
+ const [loading, setLoading] = useState(false);
18
+ return (
19
+ <>
20
+ <LoadingContext.Provider value={{ loading, setLoading }}>
21
+ {loading && <LoadingIndicator />}
22
+ <ARoutes context={context} />
23
+ {isProduction ? <Tail /> : null}
24
+ </LoadingContext.Provider>
25
+ </>
26
+ );
27
+ }
28
+
29
29
  export default App;