afront 1.0.24 → 1.0.25

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 (48) 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/index.html +1 -1
  6. package/build-prod/manifest.json +25 -25
  7. package/build-prod/offline.html +1023 -1023
  8. package/build-prod/robots.txt +3 -3
  9. package/build-prod-static/index.html +1 -1
  10. package/build-prod-static/manifest.json +25 -25
  11. package/build-prod-static/offline.html +1023 -1023
  12. package/build-prod-static/robots.txt +3 -3
  13. package/install.js +415 -415
  14. package/package.json +102 -96
  15. package/server.js +40 -40
  16. package/src/ARoutes/AFRoutes.js +28 -28
  17. package/src/Api/api.config.js +266 -266
  18. package/src/Api/login.service.js +44 -44
  19. package/src/App.js +28 -28
  20. package/src/Components/Background/MeshGradient.js +18 -18
  21. package/src/Components/Footer/Footer.js +108 -108
  22. package/src/Components/Header/Header.js +149 -149
  23. package/src/Components/Loading/LoadingIndicator.js +12 -12
  24. package/src/Components/Loading/LoadingIndicator.module.css +34 -34
  25. package/src/Components/Loading/LoadingSpinner.js +27 -27
  26. package/src/Components/Loading/LoadingSpinner.module.css +100 -100
  27. package/src/Components/RequireAuth.js +29 -29
  28. package/src/LoadingFallback.js +13 -13
  29. package/src/PageNotFound.js +19 -19
  30. package/src/Pages/Home.js +50 -50
  31. package/src/Pages/Signup.js +230 -230
  32. package/src/Pages/Support.js +68 -68
  33. package/src/Routes/ARoutes.js +66 -66
  34. package/src/Routes/ARoutesStatic.js +83 -83
  35. package/src/Static/appStatic.js +16 -16
  36. package/src/Static/indexStatic.js +13 -13
  37. package/src/Style/App.module.css +11 -11
  38. package/src/Style/MeshGradient.module.css +130 -130
  39. package/src/Style/PageNotFound.module.css +37 -37
  40. package/src/Style/Style.module.css +686 -686
  41. package/src/Style/Support.module.css +185 -185
  42. package/src/Utils/LoadingContext.js +5 -5
  43. package/src/index.js +25 -25
  44. package/webpack.build-prod.js +141 -140
  45. package/webpack.dev.js +127 -127
  46. package/webpack.prod.js +148 -147
  47. package/webpack.ssr.prod.js +97 -97
  48. package/npm-shrinkwrap.json +0 -9641
@@ -1,230 +1,230 @@
1
- import React, { useState } from "react";
2
- import { useNavigate } from "react-router";
3
- import auth from "../Api/login.service";
4
-
5
- function Signup() {
6
- const navigate = useNavigate();
7
- const [step, setStep] = useState(1);
8
- const [email, setEmail] = useState("");
9
- const [password, setPassword] = useState("");
10
- const [name, setName] = useState("");
11
- const [accountType, setAccountType] = useState("personal"); // personal/creator or business
12
- const [companyName, setCompanyName] = useState("");
13
- const [loading, setLoading] = useState(false);
14
- const [error, setError] = useState(null);
15
-
16
- const validateStep = () => {
17
- setError(null);
18
- if (step === 1) {
19
- if (!email) return "Email is required";
20
- // basic email regex
21
- const emailRegex = /^[^@\s]+@[^@\s]+\.[^@\s]+$/;
22
- if (!emailRegex.test(email)) return "Enter a valid email address";
23
- if (!password) return "Password is required";
24
- if (password.length < 8) return "Password must be at least 8 characters";
25
- }
26
- if (step === 2) {
27
- if (!name || name.trim().length === 0) return "Full name is required";
28
- }
29
- if (step === 3) {
30
- if (!accountType) return "Select account type";
31
- if (
32
- accountType === "business" &&
33
- (!companyName || companyName.trim().length === 0)
34
- )
35
- return "Brand / Company Name is required for business accounts";
36
- }
37
- return null;
38
- };
39
-
40
- const handleNext = (e) => {
41
- (async () => {
42
- if (e) e.preventDefault();
43
- const err = validateStep();
44
- if (err) return setError(err);
45
- setError(null);
46
- // On step 1, call backend to check email (exists/disposable)
47
- if (step === 1) {
48
- try {
49
- const res = await auth.checkSignup({ email });
50
- if (!res || !res.ok) {
51
- setError(
52
- (res && res.data && (res.data.error || res.data.message)) ||
53
- "Check failed"
54
- );
55
- return;
56
- }
57
- if (res.data.disposable) {
58
- setError("Disposable email addresses are not allowed");
59
- return;
60
- }
61
- if (res.data.exists) {
62
- setError("An account already exists with this email");
63
- return;
64
- }
65
- } catch (err) {
66
- setError("Email check failed");
67
- return;
68
- }
69
- }
70
- setStep((s) => Math.min(3, s + 1));
71
- })();
72
- };
73
-
74
- const handleBack = (e) => {
75
- if (e) e.preventDefault();
76
- setError(null);
77
- setStep((s) => Math.max(1, s - 1));
78
- };
79
-
80
- const handleSubmit = async (e) => {
81
- if (e) e.preventDefault();
82
- const err = validateStep();
83
- if (err) return setError(err);
84
- setLoading(true);
85
- setError(null);
86
- try {
87
- const payload = {
88
- email,
89
- password,
90
- name,
91
- accountType,
92
- companyName: accountType === "business" ? companyName : undefined,
93
- };
94
- const res = await auth.signup(payload);
95
- if (!res || !res.ok) {
96
- setError(
97
- (res && res.data && (res.data.error || res.data.message)) ||
98
- "Registration failed"
99
- );
100
- setLoading(false);
101
- return;
102
- }
103
-
104
- try {
105
- localStorage.setItem("auth-event", String(Date.now()));
106
- } catch (e) {}
107
- window.dispatchEvent(new Event("auth-changed"));
108
- navigate("/");
109
- } catch (err) {
110
- setError("Registration failed");
111
- } finally {
112
- setLoading(false);
113
- }
114
- };
115
-
116
- return (
117
- <div className="page auth-page signup-page">
118
- <h2>Sign up</h2>
119
- {error && <div className="auth-error">{error}</div>}
120
- <form
121
- className="auth-form"
122
- onSubmit={step === 3 ? handleSubmit : handleNext}>
123
- {step === 1 && (
124
- <>
125
- <label>
126
- Email Address (required)
127
- <input
128
- type="email"
129
- value={email}
130
- onChange={(e) => setEmail(e.target.value)}
131
- disabled={loading}
132
- />
133
- </label>
134
- {/* Work/personal choice removed — backend tracks only personal emails */}
135
- <label>
136
- Password (required, min 8 characters)
137
- <input
138
- type="password"
139
- value={password}
140
- onChange={(e) => setPassword(e.target.value)}
141
- disabled={loading}
142
- />
143
- </label>
144
- <div className="form-actions">
145
- <button type="button" onClick={handleNext} disabled={loading}>
146
- Next
147
- </button>
148
- </div>
149
- </>
150
- )}
151
-
152
- {step === 2 && (
153
- <>
154
- <label>
155
- Full Name (required)
156
- <input
157
- value={name}
158
- onChange={(e) => setName(e.target.value)}
159
- disabled={loading}
160
- />
161
- </label>
162
- <div className="form-actions">
163
- <button type="button" onClick={handleBack} disabled={loading}>
164
- Back
165
- </button>
166
- <button type="button" onClick={handleNext} disabled={loading}>
167
- Next
168
- </button>
169
- </div>
170
- </>
171
- )}
172
-
173
- {step === 3 && (
174
- <>
175
- <label>
176
- Account Type (required)
177
- <div>
178
- <label>
179
- <input
180
- type="radio"
181
- name="accountType"
182
- value="personal"
183
- checked={accountType === "personal"}
184
- onChange={() => setAccountType("personal")}
185
- disabled={loading}
186
- />
187
- Personal / Creator
188
- </label>
189
- <label>
190
- <input
191
- type="radio"
192
- name="accountType"
193
- value="business"
194
- checked={accountType === "business"}
195
- onChange={() => setAccountType("business")}
196
- disabled={loading}
197
- />
198
- Business / Brand / Company
199
- </label>
200
- </div>
201
- </label>
202
- {accountType === "business" && (
203
- <label>
204
- Brand / Company Name (required for business)
205
- <input
206
- value={companyName}
207
- onChange={(e) => setCompanyName(e.target.value)}
208
- disabled={loading}
209
- />
210
- </label>
211
- )}
212
-
213
- {error && <div className="auth-error">{error}</div>}
214
-
215
- <div className="form-actions">
216
- <button type="button" onClick={handleBack} disabled={loading}>
217
- Back
218
- </button>
219
- <button type="submit" disabled={loading}>
220
- {loading ? "Signing up..." : "Sign up"}
221
- </button>
222
- </div>
223
- </>
224
- )}
225
- </form>
226
- </div>
227
- );
228
- }
229
-
230
- export default Signup;
1
+ import React, { useState } from "react";
2
+ import { useNavigate } from "react-router";
3
+ import auth from "../Api/login.service";
4
+
5
+ function Signup() {
6
+ const navigate = useNavigate();
7
+ const [step, setStep] = useState(1);
8
+ const [email, setEmail] = useState("");
9
+ const [password, setPassword] = useState("");
10
+ const [name, setName] = useState("");
11
+ const [accountType, setAccountType] = useState("personal"); // personal/creator or business
12
+ const [companyName, setCompanyName] = useState("");
13
+ const [loading, setLoading] = useState(false);
14
+ const [error, setError] = useState(null);
15
+
16
+ const validateStep = () => {
17
+ setError(null);
18
+ if (step === 1) {
19
+ if (!email) return "Email is required";
20
+ // basic email regex
21
+ const emailRegex = /^[^@\s]+@[^@\s]+\.[^@\s]+$/;
22
+ if (!emailRegex.test(email)) return "Enter a valid email address";
23
+ if (!password) return "Password is required";
24
+ if (password.length < 8) return "Password must be at least 8 characters";
25
+ }
26
+ if (step === 2) {
27
+ if (!name || name.trim().length === 0) return "Full name is required";
28
+ }
29
+ if (step === 3) {
30
+ if (!accountType) return "Select account type";
31
+ if (
32
+ accountType === "business" &&
33
+ (!companyName || companyName.trim().length === 0)
34
+ )
35
+ return "Brand / Company Name is required for business accounts";
36
+ }
37
+ return null;
38
+ };
39
+
40
+ const handleNext = (e) => {
41
+ (async () => {
42
+ if (e) e.preventDefault();
43
+ const err = validateStep();
44
+ if (err) return setError(err);
45
+ setError(null);
46
+ // On step 1, call backend to check email (exists/disposable)
47
+ if (step === 1) {
48
+ try {
49
+ const res = await auth.checkSignup({ email });
50
+ if (!res || !res.ok) {
51
+ setError(
52
+ (res && res.data && (res.data.error || res.data.message)) ||
53
+ "Check failed"
54
+ );
55
+ return;
56
+ }
57
+ if (res.data.disposable) {
58
+ setError("Disposable email addresses are not allowed");
59
+ return;
60
+ }
61
+ if (res.data.exists) {
62
+ setError("An account already exists with this email");
63
+ return;
64
+ }
65
+ } catch (err) {
66
+ setError("Email check failed");
67
+ return;
68
+ }
69
+ }
70
+ setStep((s) => Math.min(3, s + 1));
71
+ })();
72
+ };
73
+
74
+ const handleBack = (e) => {
75
+ if (e) e.preventDefault();
76
+ setError(null);
77
+ setStep((s) => Math.max(1, s - 1));
78
+ };
79
+
80
+ const handleSubmit = async (e) => {
81
+ if (e) e.preventDefault();
82
+ const err = validateStep();
83
+ if (err) return setError(err);
84
+ setLoading(true);
85
+ setError(null);
86
+ try {
87
+ const payload = {
88
+ email,
89
+ password,
90
+ name,
91
+ accountType,
92
+ companyName: accountType === "business" ? companyName : undefined,
93
+ };
94
+ const res = await auth.signup(payload);
95
+ if (!res || !res.ok) {
96
+ setError(
97
+ (res && res.data && (res.data.error || res.data.message)) ||
98
+ "Registration failed"
99
+ );
100
+ setLoading(false);
101
+ return;
102
+ }
103
+
104
+ try {
105
+ localStorage.setItem("auth-event", String(Date.now()));
106
+ } catch (e) {}
107
+ window.dispatchEvent(new Event("auth-changed"));
108
+ navigate("/");
109
+ } catch (err) {
110
+ setError("Registration failed");
111
+ } finally {
112
+ setLoading(false);
113
+ }
114
+ };
115
+
116
+ return (
117
+ <div className="page auth-page signup-page">
118
+ <h2>Sign up</h2>
119
+ {error && <div className="auth-error">{error}</div>}
120
+ <form
121
+ className="auth-form"
122
+ onSubmit={step === 3 ? handleSubmit : handleNext}>
123
+ {step === 1 && (
124
+ <>
125
+ <label>
126
+ Email Address (required)
127
+ <input
128
+ type="email"
129
+ value={email}
130
+ onChange={(e) => setEmail(e.target.value)}
131
+ disabled={loading}
132
+ />
133
+ </label>
134
+ {/* Work/personal choice removed — backend tracks only personal emails */}
135
+ <label>
136
+ Password (required, min 8 characters)
137
+ <input
138
+ type="password"
139
+ value={password}
140
+ onChange={(e) => setPassword(e.target.value)}
141
+ disabled={loading}
142
+ />
143
+ </label>
144
+ <div className="form-actions">
145
+ <button type="button" onClick={handleNext} disabled={loading}>
146
+ Next
147
+ </button>
148
+ </div>
149
+ </>
150
+ )}
151
+
152
+ {step === 2 && (
153
+ <>
154
+ <label>
155
+ Full Name (required)
156
+ <input
157
+ value={name}
158
+ onChange={(e) => setName(e.target.value)}
159
+ disabled={loading}
160
+ />
161
+ </label>
162
+ <div className="form-actions">
163
+ <button type="button" onClick={handleBack} disabled={loading}>
164
+ Back
165
+ </button>
166
+ <button type="button" onClick={handleNext} disabled={loading}>
167
+ Next
168
+ </button>
169
+ </div>
170
+ </>
171
+ )}
172
+
173
+ {step === 3 && (
174
+ <>
175
+ <label>
176
+ Account Type (required)
177
+ <div>
178
+ <label>
179
+ <input
180
+ type="radio"
181
+ name="accountType"
182
+ value="personal"
183
+ checked={accountType === "personal"}
184
+ onChange={() => setAccountType("personal")}
185
+ disabled={loading}
186
+ />
187
+ Personal / Creator
188
+ </label>
189
+ <label>
190
+ <input
191
+ type="radio"
192
+ name="accountType"
193
+ value="business"
194
+ checked={accountType === "business"}
195
+ onChange={() => setAccountType("business")}
196
+ disabled={loading}
197
+ />
198
+ Business / Brand / Company
199
+ </label>
200
+ </div>
201
+ </label>
202
+ {accountType === "business" && (
203
+ <label>
204
+ Brand / Company Name (required for business)
205
+ <input
206
+ value={companyName}
207
+ onChange={(e) => setCompanyName(e.target.value)}
208
+ disabled={loading}
209
+ />
210
+ </label>
211
+ )}
212
+
213
+ {error && <div className="auth-error">{error}</div>}
214
+
215
+ <div className="form-actions">
216
+ <button type="button" onClick={handleBack} disabled={loading}>
217
+ Back
218
+ </button>
219
+ <button type="submit" disabled={loading}>
220
+ {loading ? "Signing up..." : "Sign up"}
221
+ </button>
222
+ </div>
223
+ </>
224
+ )}
225
+ </form>
226
+ </div>
227
+ );
228
+ }
229
+
230
+ export default Signup;
@@ -1,68 +1,68 @@
1
- import React from "react";
2
- import HeadTags from "asggen-headtags";
3
- import * as styles from "../Style/Support.module.css";
4
- import MeshGradient from "../Components/Background/MeshGradient";
5
-
6
- const Support = ({ context }) => {
7
- const title = "Support - AFront";
8
- const description =
9
- "Get support for AFront, a front-end JavaScript library for seamless server-side rendering.";
10
- const keywords = "support, AFront, server-side rendering, JavaScript";
11
- HeadTags({ title, description, keywords, context });
12
-
13
- return (
14
- <MeshGradient>
15
- <div className={styles.supportContainer}>
16
- <h1 className={styles.supportTitle}>Need Assistance?</h1>
17
- <p className={styles.supportDescription}>
18
- AFront is a cutting-edge front-end JavaScript library designed for
19
- seamless server-side rendering (SSR). We're committed to providing you
20
- with top-notch support to ensure your experience is smooth and
21
- productive.
22
- </p>
23
- <div className={styles.supportContent}>
24
- <div className={styles.supportCard}>
25
- <h2 className={styles.supportCardTitle}>Technical Assistance</h2>
26
- <p className={styles.supportCardContent}>
27
- Our dedicated technical support team is available around the clock
28
- to resolve any issues you may face with AFront. Connect with us
29
- through email or our support portal for prompt assistance.
30
- </p>
31
- </div>
32
- <div className={styles.supportCard}>
33
- <h2 className={styles.supportCardTitle}>Product Information</h2>
34
- <p className={styles.supportCardContent}>
35
- Curious about AFront’s capabilities? Reach out to our sales team
36
- for detailed insights on features, benefits, and how our library
37
- can enhance your web development projects.
38
- </p>
39
- </div>
40
- <div className={styles.supportCard}>
41
- <h2 className={styles.supportCardTitle}>Community and Forums</h2>
42
- <p className={styles.supportCardContent}>
43
- Join our vibrant community forums to discuss AFront with fellow
44
- developers, exchange tips, and troubleshoot common issues
45
- collaboratively.
46
- </p>
47
- </div>
48
- </div>
49
- <div className={styles.supportFAQ}>
50
- <h2 className={styles.supportCardTitle}>
51
- Frequently Asked Questions
52
- </h2>
53
- <ul className={styles.faqList}>
54
- <li>What is AFront and how does it work?</li>
55
- <li>How do I get started with AFront?</li>
56
- <li>Where can I find documentation and tutorials?</li>
57
- <li>How can I report a bug or request a feature?</li>
58
- </ul>
59
- </div>
60
- <a href="/" className={styles.footerLink}>
61
- Back to Homepage
62
- </a>
63
- </div>
64
- </MeshGradient>
65
- );
66
- };
67
-
68
- export default Support;
1
+ import React from "react";
2
+ import HeadTags from "asggen-headtags";
3
+ import * as styles from "../Style/Support.module.css";
4
+ import MeshGradient from "../Components/Background/MeshGradient";
5
+
6
+ const Support = ({ context }) => {
7
+ const title = "Support - AFront";
8
+ const description =
9
+ "Get support for AFront, a front-end JavaScript library for seamless server-side rendering.";
10
+ const keywords = "support, AFront, server-side rendering, JavaScript";
11
+ HeadTags({ title, description, keywords, context });
12
+
13
+ return (
14
+ <MeshGradient>
15
+ <div className={styles.supportContainer}>
16
+ <h1 className={styles.supportTitle}>Need Assistance?</h1>
17
+ <p className={styles.supportDescription}>
18
+ AFront is a cutting-edge front-end JavaScript library designed for
19
+ seamless server-side rendering (SSR). We're committed to providing you
20
+ with top-notch support to ensure your experience is smooth and
21
+ productive.
22
+ </p>
23
+ <div className={styles.supportContent}>
24
+ <div className={styles.supportCard}>
25
+ <h2 className={styles.supportCardTitle}>Technical Assistance</h2>
26
+ <p className={styles.supportCardContent}>
27
+ Our dedicated technical support team is available around the clock
28
+ to resolve any issues you may face with AFront. Connect with us
29
+ through email or our support portal for prompt assistance.
30
+ </p>
31
+ </div>
32
+ <div className={styles.supportCard}>
33
+ <h2 className={styles.supportCardTitle}>Product Information</h2>
34
+ <p className={styles.supportCardContent}>
35
+ Curious about AFront’s capabilities? Reach out to our sales team
36
+ for detailed insights on features, benefits, and how our library
37
+ can enhance your web development projects.
38
+ </p>
39
+ </div>
40
+ <div className={styles.supportCard}>
41
+ <h2 className={styles.supportCardTitle}>Community and Forums</h2>
42
+ <p className={styles.supportCardContent}>
43
+ Join our vibrant community forums to discuss AFront with fellow
44
+ developers, exchange tips, and troubleshoot common issues
45
+ collaboratively.
46
+ </p>
47
+ </div>
48
+ </div>
49
+ <div className={styles.supportFAQ}>
50
+ <h2 className={styles.supportCardTitle}>
51
+ Frequently Asked Questions
52
+ </h2>
53
+ <ul className={styles.faqList}>
54
+ <li>What is AFront and how does it work?</li>
55
+ <li>How do I get started with AFront?</li>
56
+ <li>Where can I find documentation and tutorials?</li>
57
+ <li>How can I report a bug or request a feature?</li>
58
+ </ul>
59
+ </div>
60
+ <a href="/" className={styles.footerLink}>
61
+ Back to Homepage
62
+ </a>
63
+ </div>
64
+ </MeshGradient>
65
+ );
66
+ };
67
+
68
+ export default Support;