@learnpack/learnpack 5.0.309 → 5.0.311

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 (88) hide show
  1. package/README.md +409 -409
  2. package/lib/commands/audit.js +15 -15
  3. package/lib/commands/breakToken.js +19 -19
  4. package/lib/commands/clean.js +3 -3
  5. package/lib/commands/logout.js +3 -3
  6. package/lib/commands/publish.js +16 -6
  7. package/lib/commands/serve.js +16 -16
  8. package/lib/creatorDist/assets/{index-B37w_ZhT.js → index-BI7U47zy.js} +13186 -13013
  9. package/lib/creatorDist/index.html +1 -1
  10. package/lib/managers/config/index.js +77 -77
  11. package/lib/utils/creatorUtilities.js +14 -14
  12. package/lib/utils/templates/isolated/exercises/01-hello-world/README.es.md +26 -26
  13. package/lib/utils/templates/isolated/exercises/01-hello-world/README.md +26 -26
  14. package/lib/utils/templates/scorm/adlcp_rootv1p2.xsd +110 -110
  15. package/lib/utils/templates/scorm/config/index.html +209 -209
  16. package/lib/utils/templates/scorm/ims_xml.xsd +1 -1
  17. package/lib/utils/templates/scorm/imscp_rootv1p1p2.xsd +345 -345
  18. package/lib/utils/templates/scorm/imsmanifest.xml +38 -38
  19. package/lib/utils/templates/scorm/imsmd_rootv1p2p1.xsd +573 -573
  20. package/package.json +1 -1
  21. package/src/commands/audit.ts +487 -487
  22. package/src/commands/breakToken.ts +67 -67
  23. package/src/commands/clean.ts +30 -30
  24. package/src/commands/logout.ts +38 -38
  25. package/src/commands/publish.ts +39 -23
  26. package/src/commands/serve.ts +3179 -3179
  27. package/src/commands/start.ts +333 -333
  28. package/src/commands/translate.ts +123 -123
  29. package/src/creator/README.md +54 -54
  30. package/src/creator/package-lock.json +6621 -6621
  31. package/src/creator/package.json +55 -55
  32. package/src/creator/src/App.tsx +611 -608
  33. package/src/creator/src/components/FileUploader.tsx +340 -302
  34. package/src/creator/src/components/Icon.tsx +18 -18
  35. package/src/creator/src/components/LessonItem.tsx +152 -152
  36. package/src/creator/src/components/Login.tsx +259 -259
  37. package/src/creator/src/components/ParamsChecker.tsx +25 -25
  38. package/src/creator/src/components/Uploader.tsx +3 -6
  39. package/src/creator/src/components/syllabus/ContentIndex.tsx +323 -323
  40. package/src/creator/src/components/syllabus/SyllabusEditor.tsx +341 -337
  41. package/src/creator/src/i18n.ts +28 -28
  42. package/src/creator/src/locales/en.json +139 -138
  43. package/src/creator/src/locales/es.json +139 -138
  44. package/src/creator/src/utils/configTypes.ts +122 -122
  45. package/src/creator/src/utils/constants.ts +13 -13
  46. package/src/creator/src/utils/creatorUtils.ts +46 -46
  47. package/src/creator/src/utils/eventBus.ts +2 -2
  48. package/src/creator/src/utils/rigo.ts +1 -1
  49. package/src/creator/src/utils/socket.ts +61 -61
  50. package/src/creator/src/utils/store.ts +222 -222
  51. package/src/creator/src/vite-env.d.ts +1 -1
  52. package/src/creator/vite.config.ts +13 -13
  53. package/src/creatorDist/assets/{index-B37w_ZhT.js → index-BI7U47zy.js} +13186 -13013
  54. package/src/creatorDist/index.html +1 -1
  55. package/src/managers/config/defaults.ts +49 -49
  56. package/src/managers/config/exercise.ts +364 -364
  57. package/src/managers/config/index.ts +775 -775
  58. package/src/managers/file.ts +236 -236
  59. package/src/managers/server/routes.ts +554 -554
  60. package/src/managers/telemetry.ts +188 -188
  61. package/src/models/action.ts +13 -13
  62. package/src/models/config-manager.ts +28 -28
  63. package/src/models/config.ts +106 -106
  64. package/src/models/exercise-obj.ts +30 -30
  65. package/src/models/session.ts +39 -39
  66. package/src/models/socket.ts +61 -61
  67. package/src/models/status.ts +16 -16
  68. package/src/ui/_app/app.css +1 -1
  69. package/src/ui/_app/app.js +477 -407
  70. package/src/ui/app.tar.gz +0 -0
  71. package/src/utils/BaseCommand.ts +56 -56
  72. package/src/utils/api.ts +665 -665
  73. package/src/utils/audit.ts +392 -392
  74. package/src/utils/checkNotInstalled.ts +267 -267
  75. package/src/utils/convertCreds.js +34 -34
  76. package/src/utils/creatorUtilities.ts +504 -504
  77. package/src/utils/export/README.md +178 -178
  78. package/src/utils/incrementVersion.js +74 -74
  79. package/src/utils/misc.ts +58 -58
  80. package/src/utils/sidebarGenerator.ts +195 -195
  81. package/src/utils/templates/isolated/exercises/01-hello-world/README.es.md +26 -26
  82. package/src/utils/templates/isolated/exercises/01-hello-world/README.md +26 -26
  83. package/src/utils/templates/scorm/adlcp_rootv1p2.xsd +110 -110
  84. package/src/utils/templates/scorm/config/index.html +209 -209
  85. package/src/utils/templates/scorm/ims_xml.xsd +1 -1
  86. package/src/utils/templates/scorm/imscp_rootv1p1p2.xsd +345 -345
  87. package/src/utils/templates/scorm/imsmanifest.xml +38 -38
  88. package/src/utils/templates/scorm/imsmd_rootv1p2p1.xsd +573 -573
@@ -1,259 +1,259 @@
1
- import { useState } from "react"
2
- import { BREATHECODE_HOST } from "../utils/constants"
3
- import { SVGS } from "../assets/svgs"
4
- import toast from "react-hot-toast"
5
- import useStore from "../utils/store"
6
- import { useShallow } from "zustand/react/shallow"
7
- import { login4Geeks, registerUserWithFormData } from "../utils/lib"
8
- import { useTranslation } from "react-i18next"
9
-
10
- export default function Login({ onFinish }: { onFinish: () => void }) {
11
- // Login states
12
- const { t } = useTranslation()
13
-
14
- const [email, setEmail] = useState("")
15
- const [password, setPassword] = useState("")
16
- const [isLoading, setIsLoading] = useState(false)
17
- const [showForm, setShowForm] = useState(false)
18
- // Signup states
19
- const [showSignup, setShowSignup] = useState(false)
20
- const [signupData, setSignupData] = useState({
21
- firstName: "",
22
- lastName: "",
23
- email: "",
24
- })
25
- // const planToRedirect = useStore((state) => state.planToRedirect)
26
- const { setAuth } = useStore(
27
- useShallow((state) => ({ setAuth: state.setAuth }))
28
- )
29
-
30
- // Login handler
31
- const login = async (e: React.FormEvent<HTMLFormElement>) => {
32
- e.preventDefault()
33
- setIsLoading(true)
34
- const tid = toast.loading(t("login.loggingIn"))
35
- try {
36
- if (!email || !password) {
37
- setIsLoading(false)
38
- toast.error(t("login.pleaseFillAllFields"), { id: tid })
39
- return
40
- }
41
- const resp = await login4Geeks({ email, password })
42
- if (!resp) {
43
- setIsLoading(false)
44
- toast.error(t("login.invalidCredentials"), { id: tid })
45
- return
46
- }
47
- toast.success(t("login.loggedInSuccessfully"), { id: tid })
48
- setAuth({
49
- bcToken: resp.token,
50
- userId: resp.user.id,
51
- rigoToken: resp.rigobot.key,
52
- user: resp.user,
53
- publicToken: "",
54
- })
55
- setIsLoading(false)
56
- onFinish()
57
- } catch (error) {
58
- console.error(error)
59
- toast.error("Invalid credentials", { id: tid })
60
- setIsLoading(false)
61
- }
62
- }
63
-
64
- // Signup handler
65
- const handleSignup = async (e: React.FormEvent<HTMLFormElement>) => {
66
- e.preventDefault()
67
- setIsLoading(true)
68
- const tid = toast.loading(t("login.creatingAccount"))
69
- const { firstName, lastName, email } = signupData
70
- if (!firstName || !lastName || !email) {
71
- setIsLoading(false)
72
- toast.error(t("login.pleaseFillAllFields"), { id: tid })
73
- return
74
- }
75
- try {
76
- await registerUserWithFormData(firstName, lastName, email)
77
- toast.success(t("login.accountCreated"), { id: tid })
78
- setShowSignup(false)
79
- setShowForm(true)
80
- setEmail(email)
81
- } catch (err) {
82
- toast.error(t("login.registrationFailed"), { id: tid })
83
- } finally {
84
- setIsLoading(false)
85
- }
86
- }
87
-
88
- function stringToBase64(str: string) {
89
- return btoa(unescape(encodeURIComponent(str)))
90
- }
91
- function getCurrentUrlWithQueryParams() {
92
- return window.location.href
93
- }
94
- const redirectGithub = () => {
95
- const url = stringToBase64(getCurrentUrlWithQueryParams())
96
- window.location.href = `${BREATHECODE_HOST}/v1/auth/github/?url=${url}`
97
- }
98
- const redirectGoogle = () => {
99
- const url = stringToBase64(getCurrentUrlWithQueryParams())
100
- window.location.href = `${BREATHECODE_HOST}/v1/auth/google?url=${url}`
101
- }
102
-
103
- return (
104
- <div
105
- className="fixed inset-0 bg-black/50 flex items-center justify-center z-1000"
106
- onClick={onFinish}
107
- >
108
- <div
109
- className="bg-white p-8 rounded-xl shadow-md max-w-sm w-full"
110
- onClick={(e) => e.stopPropagation()}
111
- >
112
- {showSignup ? (
113
- <>
114
- <h2 className="mb-4 text-xl font-semibold text-center">
115
- {t("login.createYourAccount")}
116
- </h2>
117
- <form className="space-y-3" onSubmit={handleSignup}>
118
- <input
119
- type="text"
120
- placeholder={t("login.firstName")}
121
- className="w-full border border-gray-300 px-3 py-2 rounded-md"
122
- value={signupData.firstName}
123
- onChange={(e) =>
124
- setSignupData({ ...signupData, firstName: e.target.value })
125
- }
126
- />
127
- <input
128
- type="text"
129
- placeholder={t("login.lastName")}
130
- className="w-full border border-gray-300 px-3 py-2 rounded-md"
131
- value={signupData.lastName}
132
- onChange={(e) =>
133
- setSignupData({ ...signupData, lastName: e.target.value })
134
- }
135
- />
136
- <input
137
- type="email"
138
- placeholder="Email"
139
- className="w-full border border-gray-300 px-3 py-2 rounded-md"
140
- value={signupData.email}
141
- onChange={(e) =>
142
- setSignupData({ ...signupData, email: e.target.value })
143
- }
144
- />
145
- <button
146
- type="submit"
147
- className="w-full bg-blue-600 text-white py-2 rounded-md font-semibold cursor-pointer"
148
- disabled={isLoading}
149
- >
150
- {isLoading ? t("login.creating") : t("login.signUp")}
151
- </button>
152
- </form>
153
- <div className="mt-4 text-sm text-center">
154
- {t("login.alreadyHaveAnAccount")}
155
- <button
156
- className="text-blue-600 font-medium"
157
- onClick={() => {
158
- setShowSignup(false)
159
- setShowForm(true)
160
- }}
161
- >
162
- {t("login.logInHere")}
163
- </button>
164
- </div>
165
- </>
166
- ) : (
167
- <>
168
- <p className="mb-4 text-center text-gray-700">
169
- {t("login.youNeedToHaveAnAccount")}
170
- </p>
171
- <button
172
- onClick={redirectGithub}
173
- className="w-full border border-gray-300 py-2 rounded-md font-semibold flex items-center justify-center gap-2 mb-4 cursor-pointer"
174
- >
175
- {SVGS.github} {t("login.loginWithGithub")}
176
- </button>
177
- <button
178
- onClick={redirectGoogle}
179
- className="w-full border border-gray-300 py-2 rounded-md font-semibold flex items-center justify-center gap-2 mb-4 cursor-pointer"
180
- >
181
- {SVGS.google} {t("login.loginWithGoogle")}
182
- </button>
183
- <div className="flex items-center mb-4">
184
- <hr className="flex-grow border-gray-300" />
185
- <span className="mx-2 text-gray-400 text-sm">
186
- {t("login.or")}
187
- </span>
188
- <hr className="flex-grow border-gray-300" />
189
- </div>
190
- {showForm ? (
191
- <form className="space-y-3" onSubmit={login}>
192
- <input
193
- type="email"
194
- placeholder="Email"
195
- className="w-full border border-gray-300 px-3 py-2 rounded-md"
196
- value={email}
197
- onChange={(e) => setEmail(e.target.value)}
198
- />
199
- <input
200
- type="password"
201
- placeholder={t("login.password")}
202
- className="w-full border border-gray-300 px-3 py-2 rounded-md"
203
- value={password}
204
- onChange={(e) => setPassword(e.target.value)}
205
- />
206
- <div className="flex gap-2 mt-4">
207
- <button
208
- type="submit"
209
- className="flex-1 bg-blue-500 text-white py-2 rounded-md font-semibold cursor-pointer"
210
- >
211
- {isLoading ? t("login.loggingIn") : t("login.logIn")}
212
- </button>
213
- <button
214
- type="button"
215
- onClick={() => setShowForm(false)}
216
- className="flex-1 border border-blue-500 text-blue-600 py-2 rounded-md font-semibold cursor-pointer"
217
- >
218
- {t("login.skip")}
219
- </button>
220
- </div>
221
- <div className="text-sm text-gray-600 mt-2">
222
- {t("login.forgotPassword")}
223
- <a
224
- href={`${BREATHECODE_HOST}/v1/auth/password/reset?url=${getCurrentUrlWithQueryParams()}`}
225
- className="text-blue-600 font-medium"
226
- >
227
- {t("login.recoverItHere")}
228
- </a>
229
- </div>
230
- </form>
231
- ) : (
232
- <button
233
- onClick={() => setShowForm(true)}
234
- className="w-full bg-blue-600 text-white py-2 rounded-md font-semibold cursor-pointer"
235
- >
236
- {t("login.loginWithEmail")}
237
- </button>
238
- )}
239
- <div className="flex justify-between items-center mt-4">
240
- <div className="bg-blue-50 text-sm p-2 rounded text-left">
241
- <p className="text-gray-700 m-0">
242
- {t("login.youDontHaveAnAccount")}
243
- </p>
244
- <a
245
- href={`https://learn.learnpack.co/signup?callback=${encodeURIComponent(window.location.href)}`}
246
- target="_blank"
247
- rel="noopener noreferrer"
248
- className="text-blue-600 font-medium"
249
- >
250
- {t("login.registerHere")}
251
- </a>
252
- </div>
253
- </div>
254
- </>
255
- )}
256
- </div>
257
- </div>
258
- )
259
- }
1
+ import { useState } from "react"
2
+ import { BREATHECODE_HOST } from "../utils/constants"
3
+ import { SVGS } from "../assets/svgs"
4
+ import toast from "react-hot-toast"
5
+ import useStore from "../utils/store"
6
+ import { useShallow } from "zustand/react/shallow"
7
+ import { login4Geeks, registerUserWithFormData } from "../utils/lib"
8
+ import { useTranslation } from "react-i18next"
9
+
10
+ export default function Login({ onFinish }: { onFinish: () => void }) {
11
+ // Login states
12
+ const { t } = useTranslation()
13
+
14
+ const [email, setEmail] = useState("")
15
+ const [password, setPassword] = useState("")
16
+ const [isLoading, setIsLoading] = useState(false)
17
+ const [showForm, setShowForm] = useState(false)
18
+ // Signup states
19
+ const [showSignup, setShowSignup] = useState(false)
20
+ const [signupData, setSignupData] = useState({
21
+ firstName: "",
22
+ lastName: "",
23
+ email: "",
24
+ })
25
+ // const planToRedirect = useStore((state) => state.planToRedirect)
26
+ const { setAuth } = useStore(
27
+ useShallow((state) => ({ setAuth: state.setAuth }))
28
+ )
29
+
30
+ // Login handler
31
+ const login = async (e: React.FormEvent<HTMLFormElement>) => {
32
+ e.preventDefault()
33
+ setIsLoading(true)
34
+ const tid = toast.loading(t("login.loggingIn"))
35
+ try {
36
+ if (!email || !password) {
37
+ setIsLoading(false)
38
+ toast.error(t("login.pleaseFillAllFields"), { id: tid })
39
+ return
40
+ }
41
+ const resp = await login4Geeks({ email, password })
42
+ if (!resp) {
43
+ setIsLoading(false)
44
+ toast.error(t("login.invalidCredentials"), { id: tid })
45
+ return
46
+ }
47
+ toast.success(t("login.loggedInSuccessfully"), { id: tid })
48
+ setAuth({
49
+ bcToken: resp.token,
50
+ userId: resp.user.id,
51
+ rigoToken: resp.rigobot.key,
52
+ user: resp.user,
53
+ publicToken: "",
54
+ })
55
+ setIsLoading(false)
56
+ onFinish()
57
+ } catch (error) {
58
+ console.error(error)
59
+ toast.error("Invalid credentials", { id: tid })
60
+ setIsLoading(false)
61
+ }
62
+ }
63
+
64
+ // Signup handler
65
+ const handleSignup = async (e: React.FormEvent<HTMLFormElement>) => {
66
+ e.preventDefault()
67
+ setIsLoading(true)
68
+ const tid = toast.loading(t("login.creatingAccount"))
69
+ const { firstName, lastName, email } = signupData
70
+ if (!firstName || !lastName || !email) {
71
+ setIsLoading(false)
72
+ toast.error(t("login.pleaseFillAllFields"), { id: tid })
73
+ return
74
+ }
75
+ try {
76
+ await registerUserWithFormData(firstName, lastName, email)
77
+ toast.success(t("login.accountCreated"), { id: tid })
78
+ setShowSignup(false)
79
+ setShowForm(true)
80
+ setEmail(email)
81
+ } catch (err) {
82
+ toast.error(t("login.registrationFailed"), { id: tid })
83
+ } finally {
84
+ setIsLoading(false)
85
+ }
86
+ }
87
+
88
+ function stringToBase64(str: string) {
89
+ return btoa(unescape(encodeURIComponent(str)))
90
+ }
91
+ function getCurrentUrlWithQueryParams() {
92
+ return window.location.href
93
+ }
94
+ const redirectGithub = () => {
95
+ const url = stringToBase64(getCurrentUrlWithQueryParams())
96
+ window.location.href = `${BREATHECODE_HOST}/v1/auth/github/?url=${url}`
97
+ }
98
+ const redirectGoogle = () => {
99
+ const url = stringToBase64(getCurrentUrlWithQueryParams())
100
+ window.location.href = `${BREATHECODE_HOST}/v1/auth/google?url=${url}`
101
+ }
102
+
103
+ return (
104
+ <div
105
+ className="fixed inset-0 bg-black/50 flex items-center justify-center z-1000"
106
+ onClick={onFinish}
107
+ >
108
+ <div
109
+ className="bg-white p-8 rounded-xl shadow-md max-w-sm w-full"
110
+ onClick={(e) => e.stopPropagation()}
111
+ >
112
+ {showSignup ? (
113
+ <>
114
+ <h2 className="mb-4 text-xl font-semibold text-center">
115
+ {t("login.createYourAccount")}
116
+ </h2>
117
+ <form className="space-y-3" onSubmit={handleSignup}>
118
+ <input
119
+ type="text"
120
+ placeholder={t("login.firstName")}
121
+ className="w-full border border-gray-300 px-3 py-2 rounded-md"
122
+ value={signupData.firstName}
123
+ onChange={(e) =>
124
+ setSignupData({ ...signupData, firstName: e.target.value })
125
+ }
126
+ />
127
+ <input
128
+ type="text"
129
+ placeholder={t("login.lastName")}
130
+ className="w-full border border-gray-300 px-3 py-2 rounded-md"
131
+ value={signupData.lastName}
132
+ onChange={(e) =>
133
+ setSignupData({ ...signupData, lastName: e.target.value })
134
+ }
135
+ />
136
+ <input
137
+ type="email"
138
+ placeholder="Email"
139
+ className="w-full border border-gray-300 px-3 py-2 rounded-md"
140
+ value={signupData.email}
141
+ onChange={(e) =>
142
+ setSignupData({ ...signupData, email: e.target.value })
143
+ }
144
+ />
145
+ <button
146
+ type="submit"
147
+ className="w-full bg-blue-600 text-white py-2 rounded-md font-semibold cursor-pointer"
148
+ disabled={isLoading}
149
+ >
150
+ {isLoading ? t("login.creating") : t("login.signUp")}
151
+ </button>
152
+ </form>
153
+ <div className="mt-4 text-sm text-center">
154
+ {t("login.alreadyHaveAnAccount")}
155
+ <button
156
+ className="text-blue-600 font-medium"
157
+ onClick={() => {
158
+ setShowSignup(false)
159
+ setShowForm(true)
160
+ }}
161
+ >
162
+ {t("login.logInHere")}
163
+ </button>
164
+ </div>
165
+ </>
166
+ ) : (
167
+ <>
168
+ <p className="mb-4 text-center text-gray-700">
169
+ {t("login.youNeedToHaveAnAccount")}
170
+ </p>
171
+ <button
172
+ onClick={redirectGithub}
173
+ className="w-full border border-gray-300 py-2 rounded-md font-semibold flex items-center justify-center gap-2 mb-4 cursor-pointer"
174
+ >
175
+ {SVGS.github} {t("login.loginWithGithub")}
176
+ </button>
177
+ <button
178
+ onClick={redirectGoogle}
179
+ className="w-full border border-gray-300 py-2 rounded-md font-semibold flex items-center justify-center gap-2 mb-4 cursor-pointer"
180
+ >
181
+ {SVGS.google} {t("login.loginWithGoogle")}
182
+ </button>
183
+ <div className="flex items-center mb-4">
184
+ <hr className="flex-grow border-gray-300" />
185
+ <span className="mx-2 text-gray-400 text-sm">
186
+ {t("login.or")}
187
+ </span>
188
+ <hr className="flex-grow border-gray-300" />
189
+ </div>
190
+ {showForm ? (
191
+ <form className="space-y-3" onSubmit={login}>
192
+ <input
193
+ type="email"
194
+ placeholder="Email"
195
+ className="w-full border border-gray-300 px-3 py-2 rounded-md"
196
+ value={email}
197
+ onChange={(e) => setEmail(e.target.value)}
198
+ />
199
+ <input
200
+ type="password"
201
+ placeholder={t("login.password")}
202
+ className="w-full border border-gray-300 px-3 py-2 rounded-md"
203
+ value={password}
204
+ onChange={(e) => setPassword(e.target.value)}
205
+ />
206
+ <div className="flex gap-2 mt-4">
207
+ <button
208
+ type="submit"
209
+ className="flex-1 bg-blue-500 text-white py-2 rounded-md font-semibold cursor-pointer"
210
+ >
211
+ {isLoading ? t("login.loggingIn") : t("login.logIn")}
212
+ </button>
213
+ <button
214
+ type="button"
215
+ onClick={() => setShowForm(false)}
216
+ className="flex-1 border border-blue-500 text-blue-600 py-2 rounded-md font-semibold cursor-pointer"
217
+ >
218
+ {t("login.skip")}
219
+ </button>
220
+ </div>
221
+ <div className="text-sm text-gray-600 mt-2">
222
+ {t("login.forgotPassword")}
223
+ <a
224
+ href={`${BREATHECODE_HOST}/v1/auth/password/reset?url=${getCurrentUrlWithQueryParams()}`}
225
+ className="text-blue-600 font-medium"
226
+ >
227
+ {t("login.recoverItHere")}
228
+ </a>
229
+ </div>
230
+ </form>
231
+ ) : (
232
+ <button
233
+ onClick={() => setShowForm(true)}
234
+ className="w-full bg-blue-600 text-white py-2 rounded-md font-semibold cursor-pointer"
235
+ >
236
+ {t("login.loginWithEmail")}
237
+ </button>
238
+ )}
239
+ <div className="flex justify-between items-center mt-4">
240
+ <div className="bg-blue-50 text-sm p-2 rounded text-left">
241
+ <p className="text-gray-700 m-0">
242
+ {t("login.youDontHaveAnAccount")}
243
+ </p>
244
+ <a
245
+ href={`https://learn.learnpack.co/signup?callback=${encodeURIComponent(window.location.href)}`}
246
+ target="_blank"
247
+ rel="noopener noreferrer"
248
+ className="text-blue-600 font-medium"
249
+ >
250
+ {t("login.registerHere")}
251
+ </a>
252
+ </div>
253
+ </div>
254
+ </>
255
+ )}
256
+ </div>
257
+ </div>
258
+ )
259
+ }
@@ -1,25 +1,25 @@
1
- import { useEffect } from "react"
2
- import useStore from "../utils/store"
3
- import { checkParams } from "../utils/lib"
4
- import { useTranslation } from "react-i18next"
5
-
6
- export const ParamsChecker = () => {
7
- const { i18n } = useTranslation()
8
- const setMode = useStore((state) => state.setMode)
9
-
10
- useEffect(() => {
11
- const params = checkParams(["mode", "language"])
12
- const mode = params.mode
13
- if (mode && ["teacher", "student"].includes(mode.toLowerCase())) {
14
- setMode(mode.toLowerCase() as "teacher" | "student")
15
- }
16
- if (
17
- params.language &&
18
- ["en", "es"].includes(params.language.toLowerCase())
19
- ) {
20
- i18n.changeLanguage(params.language.toLowerCase())
21
- }
22
- }, [])
23
-
24
- return <></>
25
- }
1
+ import { useEffect } from "react"
2
+ import useStore from "../utils/store"
3
+ import { checkParams } from "../utils/lib"
4
+ import { useTranslation } from "react-i18next"
5
+
6
+ export const ParamsChecker = () => {
7
+ const { i18n } = useTranslation()
8
+ const setMode = useStore((state) => state.setMode)
9
+
10
+ useEffect(() => {
11
+ const params = checkParams(["mode", "language"])
12
+ const mode = params.mode
13
+ if (mode && ["teacher", "student"].includes(mode.toLowerCase())) {
14
+ setMode(mode.toLowerCase() as "teacher" | "student")
15
+ }
16
+ if (
17
+ params.language &&
18
+ ["en", "es"].includes(params.language.toLowerCase())
19
+ ) {
20
+ i18n.changeLanguage(params.language.toLowerCase())
21
+ }
22
+ }, [])
23
+
24
+ return <></>
25
+ }
@@ -67,12 +67,9 @@ export const Uploader = ({
67
67
  {selectedOption === "files" && (
68
68
  <FileUploader
69
69
  styledAs="card"
70
- onFinish={(files) => {
71
- const allFilesText = files
72
- .filter((f) => f.status === "SUCCESS")
73
- .map((f) => `<FILE name="${f.name}">${f.text}</FILE>`)
74
- .join("\n")
75
- onFinish(allFilesText)
70
+ onFinish={() => {
71
+ // We'll pass the uploaded files in hte context, no need to fill the content index
72
+ onFinish("")
76
73
  }}
77
74
  />
78
75
  )}