@nocios/crudify-components 2.0.32 → 2.0.38

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 (178) hide show
  1. package/coverage/base.css +224 -0
  2. package/coverage/block-navigation.js +87 -0
  3. package/coverage/components/CrudiaAutoGenerate.tsx.html +583 -0
  4. package/coverage/components/CrudiaFileField/CrudiaFileField.tsx.html +1276 -0
  5. package/coverage/components/CrudiaFileField/components/DeleteConfirmationDialog.tsx.html +355 -0
  6. package/coverage/components/CrudiaFileField/components/DropZone.tsx.html +433 -0
  7. package/coverage/components/CrudiaFileField/components/FileItemRow.tsx.html +751 -0
  8. package/coverage/components/CrudiaFileField/components/FileThumbnail.tsx.html +1195 -0
  9. package/coverage/components/CrudiaFileField/components/index.html +176 -0
  10. package/coverage/components/CrudiaFileField/components/index.ts.html +115 -0
  11. package/coverage/components/CrudiaFileField/hooks/index.html +146 -0
  12. package/coverage/components/CrudiaFileField/hooks/index.ts.html +112 -0
  13. package/coverage/components/CrudiaFileField/hooks/useDeleteConfirmation.ts.html +421 -0
  14. package/coverage/components/CrudiaFileField/hooks/useDragDrop.ts.html +403 -0
  15. package/coverage/components/CrudiaFileField/index.html +131 -0
  16. package/coverage/components/CrudiaFileField/index.ts.html +112 -0
  17. package/coverage/components/CrudiaFileField/utils/formatters.ts.html +163 -0
  18. package/coverage/components/CrudiaFileField/utils/icons.tsx.html +253 -0
  19. package/coverage/components/CrudiaFileField/utils/index.html +131 -0
  20. package/coverage/components/CrudiaMarkdownField.tsx.html +619 -0
  21. package/coverage/components/CrudifyLogin/Forms/CheckCodeForm.tsx.html +586 -0
  22. package/coverage/components/CrudifyLogin/Forms/ForgotPasswordForm.tsx.html +694 -0
  23. package/coverage/components/CrudifyLogin/Forms/LoginForm.tsx.html +835 -0
  24. package/coverage/components/CrudifyLogin/Forms/ResetPasswordForm.tsx.html +1180 -0
  25. package/coverage/components/CrudifyLogin/Forms/components/CodeInput.tsx.html +283 -0
  26. package/coverage/components/CrudifyLogin/Forms/components/FormAlert.tsx.html +202 -0
  27. package/coverage/components/CrudifyLogin/Forms/components/PasswordInput.tsx.html +340 -0
  28. package/coverage/components/CrudifyLogin/Forms/components/index.html +161 -0
  29. package/coverage/components/CrudifyLogin/Forms/components/index.ts.html +106 -0
  30. package/coverage/components/CrudifyLogin/Forms/index.html +161 -0
  31. package/coverage/components/CrudifyLogin/Forms/utils/errorTranslation.ts.html +268 -0
  32. package/coverage/components/CrudifyLogin/Forms/utils/index.html +161 -0
  33. package/coverage/components/CrudifyLogin/Forms/utils/index.ts.html +106 -0
  34. package/coverage/components/CrudifyLogin/Forms/utils/paramUtils.ts.html +478 -0
  35. package/coverage/components/CrudifyLogin/Forms/utils/validation.ts.html +289 -0
  36. package/coverage/components/CrudifyLogin/components/CrudifyInitializer.tsx.html +262 -0
  37. package/coverage/components/CrudifyLogin/components/index.html +116 -0
  38. package/coverage/components/CrudifyLogin/context/CrudifyProvider.tsx.html +382 -0
  39. package/coverage/components/CrudifyLogin/context/I18nProvider.tsx.html +397 -0
  40. package/coverage/components/CrudifyLogin/context/LoginStateProvider.tsx.html +1249 -0
  41. package/coverage/components/CrudifyLogin/context/index.html +146 -0
  42. package/coverage/components/CrudifyLogin/hooks/index.html +116 -0
  43. package/coverage/components/CrudifyLogin/hooks/useTranslationsFromUrl.ts.html +292 -0
  44. package/coverage/components/CrudifyLogin/index.html +116 -0
  45. package/coverage/components/CrudifyLogin/index.tsx.html +475 -0
  46. package/coverage/components/GlobalNotificationProvider.tsx.html +781 -0
  47. package/coverage/components/LoginComponent.tsx.html +727 -0
  48. package/coverage/components/PasswordRequirements/index.html +116 -0
  49. package/coverage/components/PasswordRequirements/index.tsx.html +226 -0
  50. package/coverage/components/PublicPolicies/FieldSelector/FieldSelector.tsx.html +982 -0
  51. package/coverage/components/PublicPolicies/FieldSelector/index.html +131 -0
  52. package/coverage/components/PublicPolicies/FieldSelector/index.ts.html +85 -0
  53. package/coverage/components/PublicPolicies/Policies.tsx.html +610 -0
  54. package/coverage/components/PublicPolicies/PolicyItem/PolicyItem.tsx.html +856 -0
  55. package/coverage/components/PublicPolicies/PolicyItem/index.html +131 -0
  56. package/coverage/components/PublicPolicies/PolicyItem/index.ts.html +85 -0
  57. package/coverage/components/PublicPolicies/constants.ts.html +127 -0
  58. package/coverage/components/PublicPolicies/index.html +131 -0
  59. package/coverage/components/SessionTimeIndicator/index.html +116 -0
  60. package/coverage/components/SessionTimeIndicator/index.tsx.html +505 -0
  61. package/coverage/components/UserProfile/UserProfileDisplay.tsx.html +826 -0
  62. package/coverage/components/UserProfile/index.html +131 -0
  63. package/coverage/components/UserProfile/index.ts.html +85 -0
  64. package/coverage/components/index.html +176 -0
  65. package/coverage/components/index.ts.html +160 -0
  66. package/coverage/core/CrossTabSyncManager.ts.html +814 -0
  67. package/coverage/core/CrudifyInitializationManager.ts.html +1132 -0
  68. package/coverage/core/SessionManager.ts.html +2764 -0
  69. package/coverage/core/index.html +146 -0
  70. package/coverage/coverage-final.json +87 -0
  71. package/coverage/favicon.png +0 -0
  72. package/coverage/hooks/index.html +131 -0
  73. package/coverage/hooks/useAutoGenerate.ts.html +562 -0
  74. package/coverage/hooks/useFileUpload/index.html +131 -0
  75. package/coverage/hooks/useFileUpload/index.ts.html +112 -0
  76. package/coverage/hooks/useFileUpload/services/index.html +116 -0
  77. package/coverage/hooks/useFileUpload/services/uploadService.ts.html +610 -0
  78. package/coverage/hooks/useFileUpload/useFileUpload.ts.html +1870 -0
  79. package/coverage/hooks/useFileUpload/utils/fileUtils.ts.html +271 -0
  80. package/coverage/hooks/useFileUpload/utils/index.html +146 -0
  81. package/coverage/hooks/useFileUpload/utils/mimeTypes.ts.html +235 -0
  82. package/coverage/hooks/useFileUpload/utils/validation.ts.html +379 -0
  83. package/coverage/hooks/useSession/constants.ts.html +217 -0
  84. package/coverage/hooks/useSession/hooks/index.html +176 -0
  85. package/coverage/hooks/useSession/hooks/useAuthEventSubscriber.ts.html +331 -0
  86. package/coverage/hooks/useSession/hooks/useCrossTabSync.ts.html +433 -0
  87. package/coverage/hooks/useSession/hooks/useSessionActions.ts.html +664 -0
  88. package/coverage/hooks/useSession/hooks/useSessionState.ts.html +295 -0
  89. package/coverage/hooks/useSession/hooks/useTokenRefreshScheduler.ts.html +490 -0
  90. package/coverage/hooks/useSession/index.html +161 -0
  91. package/coverage/hooks/useSession/index.ts.html +127 -0
  92. package/coverage/hooks/useSession/types.ts.html +427 -0
  93. package/coverage/hooks/useSession/useSession.ts.html +526 -0
  94. package/coverage/hooks/useSession/utils/index.html +131 -0
  95. package/coverage/hooks/useSession/utils/initializeSession.ts.html +424 -0
  96. package/coverage/hooks/useSession/utils/tokenUtils.ts.html +280 -0
  97. package/coverage/hooks/useUserProfile.ts.html +658 -0
  98. package/coverage/index.html +566 -0
  99. package/coverage/prettify.css +1 -0
  100. package/coverage/prettify.js +2 -0
  101. package/coverage/providers/SessionProvider.tsx.html +1150 -0
  102. package/coverage/providers/TranslationsProvider.tsx.html +1450 -0
  103. package/coverage/providers/index.html +131 -0
  104. package/coverage/services/credentialsEventBus.ts.html +310 -0
  105. package/coverage/services/index.html +131 -0
  106. package/coverage/services/translationService.ts.html +1318 -0
  107. package/coverage/sort-arrow-sprite.png +0 -0
  108. package/coverage/sorter.js +210 -0
  109. package/coverage/translations/critical.ts.html +1195 -0
  110. package/coverage/translations/index.html +116 -0
  111. package/coverage/types/index.html +116 -0
  112. package/coverage/types/password.ts.html +178 -0
  113. package/coverage/utils/authEventBus.ts.html +454 -0
  114. package/coverage/utils/configResolver.ts.html +460 -0
  115. package/coverage/utils/cookieSync.ts.html +580 -0
  116. package/coverage/utils/errorHandler.ts.html +1264 -0
  117. package/coverage/utils/errorTranslation.ts.html +862 -0
  118. package/coverage/utils/index.html +296 -0
  119. package/coverage/utils/jwtUtils.ts.html +301 -0
  120. package/coverage/utils/logger.ts.html +901 -0
  121. package/coverage/utils/navigationTracker.ts.html +565 -0
  122. package/coverage/utils/passwordValidation.ts.html +259 -0
  123. package/coverage/utils/redirectSecurity.ts.html +715 -0
  124. package/coverage/utils/tenantConfig.ts.html +700 -0
  125. package/coverage/utils/tokenStorage.ts.html +1768 -0
  126. package/coverage/utils/webCrypto.ts.html +472 -0
  127. package/dist/{CrudiaMarkdownField-C54-A_J3.d.mts → CrudiaMarkdownField-BvJn2GL8.d.mts} +17 -7
  128. package/dist/{CrudiaMarkdownField-C8HQh7s5.d.ts → CrudiaMarkdownField-CggOpcBM.d.ts} +17 -7
  129. package/dist/chunk-44VU4TSP.mjs +1 -0
  130. package/dist/chunk-4LMFQECS.js +1 -0
  131. package/dist/chunk-77UKXG5L.mjs +1 -0
  132. package/dist/{chunk-4VN5YRYZ.js → chunk-BXFEQ6KP.js} +1 -1
  133. package/dist/{chunk-6ONAT4QU.js → chunk-H6XXWDUT.js} +1 -1
  134. package/dist/chunk-NIRLP2TC.js +1 -0
  135. package/dist/chunk-O4FUHIQG.mjs +1 -0
  136. package/dist/chunk-SYHNHKFA.mjs +1 -0
  137. package/dist/chunk-W4ZYKPOK.js +1 -0
  138. package/dist/{chunk-RJBX4MWF.mjs → chunk-WMLIOPUC.mjs} +1 -1
  139. package/dist/components.d.mts +1 -1
  140. package/dist/components.d.ts +1 -1
  141. package/dist/components.js +1 -1
  142. package/dist/components.mjs +1 -1
  143. package/dist/errorTranslation-D-Y7uNN_.d.mts +141 -0
  144. package/dist/errorTranslation-DDlAXpMl.d.ts +141 -0
  145. package/dist/hooks.d.mts +2 -2
  146. package/dist/hooks.d.ts +2 -2
  147. package/dist/hooks.js +1 -1
  148. package/dist/hooks.mjs +1 -1
  149. package/dist/{index-DY90WVQQ.d.mts → index-U--xRr8A.d.mts} +225 -191
  150. package/dist/{index-d1vE803G.d.ts → index-dXVRVcEB.d.ts} +225 -191
  151. package/dist/index.d.mts +179 -6
  152. package/dist/index.d.ts +179 -6
  153. package/dist/index.js +2 -2
  154. package/dist/index.mjs +1 -1
  155. package/dist/{errorTranslation-By5Av0tL.d.ts → tenantConfig-DqJqQkoR.d.mts} +116 -139
  156. package/dist/{errorTranslation-DeeDj7Vt.d.mts → tenantConfig-DqJqQkoR.d.ts} +116 -139
  157. package/dist/utils.d.mts +2 -2
  158. package/dist/utils.d.ts +2 -2
  159. package/dist/utils.js +1 -1
  160. package/dist/utils.mjs +1 -1
  161. package/package.json +1 -1
  162. package/coverage/.tmp/coverage-102.json +0 -1
  163. package/coverage/.tmp/coverage-103.json +0 -1
  164. package/coverage/.tmp/coverage-104.json +0 -1
  165. package/coverage/.tmp/coverage-105.json +0 -1
  166. package/coverage/.tmp/coverage-106.json +0 -1
  167. package/coverage/.tmp/coverage-107.json +0 -1
  168. package/dist/api-B4uXiHF0.d.mts +0 -118
  169. package/dist/api-B4uXiHF0.d.ts +0 -118
  170. package/dist/chunk-4ILUXVPW.mjs +0 -1
  171. package/dist/chunk-5XBTRBE5.js +0 -1
  172. package/dist/chunk-CR5KJUST.js +0 -1
  173. package/dist/chunk-H5M2Q6PB.mjs +0 -1
  174. package/dist/chunk-JAPL7EZJ.mjs +0 -1
  175. package/dist/chunk-L7GKP6XY.mjs +0 -1
  176. package/dist/chunk-NSV6ECYO.js +0 -1
  177. package/dist/chunk-PTUSZGL4.mjs +0 -1
  178. package/dist/chunk-T6R65ROU.js +0 -1
@@ -0,0 +1,694 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for components/CrudifyLogin/Forms/ForgotPasswordForm.tsx</title>
7
+ <meta charset="utf-8" />
8
+ <link rel="stylesheet" href="../../../prettify.css" />
9
+ <link rel="stylesheet" href="../../../base.css" />
10
+ <link rel="shortcut icon" type="image/x-icon" href="../../../favicon.png" />
11
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
12
+ <style type='text/css'>
13
+ .coverage-summary .sorter {
14
+ background-image: url(../../../sort-arrow-sprite.png);
15
+ }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <div class='wrapper'>
21
+ <div class='pad1'>
22
+ <h1><a href="../../../index.html">All files</a> / <a href="index.html">components/CrudifyLogin/Forms</a> ForgotPasswordForm.tsx</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">100% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>203/203</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">97.56% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>40/41</span>
36
+ </div>
37
+
38
+
39
+ <div class='fl pad1y space-right2'>
40
+ <span class="strong">100% </span>
41
+ <span class="quiet">Functions</span>
42
+ <span class='fraction'>6/6</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">100% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>203/203</span>
50
+ </div>
51
+
52
+
53
+ </div>
54
+ <p class="quiet">
55
+ Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
56
+ </p>
57
+ <template id="filterTemplate">
58
+ <div class="quiet">
59
+ Filter:
60
+ <input type="search" id="fileSearch">
61
+ </div>
62
+ </template>
63
+ </div>
64
+ <div class='status-line high'></div>
65
+ <pre><table class="coverage">
66
+ <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
+ <a name='L2'></a><a href='#L2'>2</a>
68
+ <a name='L3'></a><a href='#L3'>3</a>
69
+ <a name='L4'></a><a href='#L4'>4</a>
70
+ <a name='L5'></a><a href='#L5'>5</a>
71
+ <a name='L6'></a><a href='#L6'>6</a>
72
+ <a name='L7'></a><a href='#L7'>7</a>
73
+ <a name='L8'></a><a href='#L8'>8</a>
74
+ <a name='L9'></a><a href='#L9'>9</a>
75
+ <a name='L10'></a><a href='#L10'>10</a>
76
+ <a name='L11'></a><a href='#L11'>11</a>
77
+ <a name='L12'></a><a href='#L12'>12</a>
78
+ <a name='L13'></a><a href='#L13'>13</a>
79
+ <a name='L14'></a><a href='#L14'>14</a>
80
+ <a name='L15'></a><a href='#L15'>15</a>
81
+ <a name='L16'></a><a href='#L16'>16</a>
82
+ <a name='L17'></a><a href='#L17'>17</a>
83
+ <a name='L18'></a><a href='#L18'>18</a>
84
+ <a name='L19'></a><a href='#L19'>19</a>
85
+ <a name='L20'></a><a href='#L20'>20</a>
86
+ <a name='L21'></a><a href='#L21'>21</a>
87
+ <a name='L22'></a><a href='#L22'>22</a>
88
+ <a name='L23'></a><a href='#L23'>23</a>
89
+ <a name='L24'></a><a href='#L24'>24</a>
90
+ <a name='L25'></a><a href='#L25'>25</a>
91
+ <a name='L26'></a><a href='#L26'>26</a>
92
+ <a name='L27'></a><a href='#L27'>27</a>
93
+ <a name='L28'></a><a href='#L28'>28</a>
94
+ <a name='L29'></a><a href='#L29'>29</a>
95
+ <a name='L30'></a><a href='#L30'>30</a>
96
+ <a name='L31'></a><a href='#L31'>31</a>
97
+ <a name='L32'></a><a href='#L32'>32</a>
98
+ <a name='L33'></a><a href='#L33'>33</a>
99
+ <a name='L34'></a><a href='#L34'>34</a>
100
+ <a name='L35'></a><a href='#L35'>35</a>
101
+ <a name='L36'></a><a href='#L36'>36</a>
102
+ <a name='L37'></a><a href='#L37'>37</a>
103
+ <a name='L38'></a><a href='#L38'>38</a>
104
+ <a name='L39'></a><a href='#L39'>39</a>
105
+ <a name='L40'></a><a href='#L40'>40</a>
106
+ <a name='L41'></a><a href='#L41'>41</a>
107
+ <a name='L42'></a><a href='#L42'>42</a>
108
+ <a name='L43'></a><a href='#L43'>43</a>
109
+ <a name='L44'></a><a href='#L44'>44</a>
110
+ <a name='L45'></a><a href='#L45'>45</a>
111
+ <a name='L46'></a><a href='#L46'>46</a>
112
+ <a name='L47'></a><a href='#L47'>47</a>
113
+ <a name='L48'></a><a href='#L48'>48</a>
114
+ <a name='L49'></a><a href='#L49'>49</a>
115
+ <a name='L50'></a><a href='#L50'>50</a>
116
+ <a name='L51'></a><a href='#L51'>51</a>
117
+ <a name='L52'></a><a href='#L52'>52</a>
118
+ <a name='L53'></a><a href='#L53'>53</a>
119
+ <a name='L54'></a><a href='#L54'>54</a>
120
+ <a name='L55'></a><a href='#L55'>55</a>
121
+ <a name='L56'></a><a href='#L56'>56</a>
122
+ <a name='L57'></a><a href='#L57'>57</a>
123
+ <a name='L58'></a><a href='#L58'>58</a>
124
+ <a name='L59'></a><a href='#L59'>59</a>
125
+ <a name='L60'></a><a href='#L60'>60</a>
126
+ <a name='L61'></a><a href='#L61'>61</a>
127
+ <a name='L62'></a><a href='#L62'>62</a>
128
+ <a name='L63'></a><a href='#L63'>63</a>
129
+ <a name='L64'></a><a href='#L64'>64</a>
130
+ <a name='L65'></a><a href='#L65'>65</a>
131
+ <a name='L66'></a><a href='#L66'>66</a>
132
+ <a name='L67'></a><a href='#L67'>67</a>
133
+ <a name='L68'></a><a href='#L68'>68</a>
134
+ <a name='L69'></a><a href='#L69'>69</a>
135
+ <a name='L70'></a><a href='#L70'>70</a>
136
+ <a name='L71'></a><a href='#L71'>71</a>
137
+ <a name='L72'></a><a href='#L72'>72</a>
138
+ <a name='L73'></a><a href='#L73'>73</a>
139
+ <a name='L74'></a><a href='#L74'>74</a>
140
+ <a name='L75'></a><a href='#L75'>75</a>
141
+ <a name='L76'></a><a href='#L76'>76</a>
142
+ <a name='L77'></a><a href='#L77'>77</a>
143
+ <a name='L78'></a><a href='#L78'>78</a>
144
+ <a name='L79'></a><a href='#L79'>79</a>
145
+ <a name='L80'></a><a href='#L80'>80</a>
146
+ <a name='L81'></a><a href='#L81'>81</a>
147
+ <a name='L82'></a><a href='#L82'>82</a>
148
+ <a name='L83'></a><a href='#L83'>83</a>
149
+ <a name='L84'></a><a href='#L84'>84</a>
150
+ <a name='L85'></a><a href='#L85'>85</a>
151
+ <a name='L86'></a><a href='#L86'>86</a>
152
+ <a name='L87'></a><a href='#L87'>87</a>
153
+ <a name='L88'></a><a href='#L88'>88</a>
154
+ <a name='L89'></a><a href='#L89'>89</a>
155
+ <a name='L90'></a><a href='#L90'>90</a>
156
+ <a name='L91'></a><a href='#L91'>91</a>
157
+ <a name='L92'></a><a href='#L92'>92</a>
158
+ <a name='L93'></a><a href='#L93'>93</a>
159
+ <a name='L94'></a><a href='#L94'>94</a>
160
+ <a name='L95'></a><a href='#L95'>95</a>
161
+ <a name='L96'></a><a href='#L96'>96</a>
162
+ <a name='L97'></a><a href='#L97'>97</a>
163
+ <a name='L98'></a><a href='#L98'>98</a>
164
+ <a name='L99'></a><a href='#L99'>99</a>
165
+ <a name='L100'></a><a href='#L100'>100</a>
166
+ <a name='L101'></a><a href='#L101'>101</a>
167
+ <a name='L102'></a><a href='#L102'>102</a>
168
+ <a name='L103'></a><a href='#L103'>103</a>
169
+ <a name='L104'></a><a href='#L104'>104</a>
170
+ <a name='L105'></a><a href='#L105'>105</a>
171
+ <a name='L106'></a><a href='#L106'>106</a>
172
+ <a name='L107'></a><a href='#L107'>107</a>
173
+ <a name='L108'></a><a href='#L108'>108</a>
174
+ <a name='L109'></a><a href='#L109'>109</a>
175
+ <a name='L110'></a><a href='#L110'>110</a>
176
+ <a name='L111'></a><a href='#L111'>111</a>
177
+ <a name='L112'></a><a href='#L112'>112</a>
178
+ <a name='L113'></a><a href='#L113'>113</a>
179
+ <a name='L114'></a><a href='#L114'>114</a>
180
+ <a name='L115'></a><a href='#L115'>115</a>
181
+ <a name='L116'></a><a href='#L116'>116</a>
182
+ <a name='L117'></a><a href='#L117'>117</a>
183
+ <a name='L118'></a><a href='#L118'>118</a>
184
+ <a name='L119'></a><a href='#L119'>119</a>
185
+ <a name='L120'></a><a href='#L120'>120</a>
186
+ <a name='L121'></a><a href='#L121'>121</a>
187
+ <a name='L122'></a><a href='#L122'>122</a>
188
+ <a name='L123'></a><a href='#L123'>123</a>
189
+ <a name='L124'></a><a href='#L124'>124</a>
190
+ <a name='L125'></a><a href='#L125'>125</a>
191
+ <a name='L126'></a><a href='#L126'>126</a>
192
+ <a name='L127'></a><a href='#L127'>127</a>
193
+ <a name='L128'></a><a href='#L128'>128</a>
194
+ <a name='L129'></a><a href='#L129'>129</a>
195
+ <a name='L130'></a><a href='#L130'>130</a>
196
+ <a name='L131'></a><a href='#L131'>131</a>
197
+ <a name='L132'></a><a href='#L132'>132</a>
198
+ <a name='L133'></a><a href='#L133'>133</a>
199
+ <a name='L134'></a><a href='#L134'>134</a>
200
+ <a name='L135'></a><a href='#L135'>135</a>
201
+ <a name='L136'></a><a href='#L136'>136</a>
202
+ <a name='L137'></a><a href='#L137'>137</a>
203
+ <a name='L138'></a><a href='#L138'>138</a>
204
+ <a name='L139'></a><a href='#L139'>139</a>
205
+ <a name='L140'></a><a href='#L140'>140</a>
206
+ <a name='L141'></a><a href='#L141'>141</a>
207
+ <a name='L142'></a><a href='#L142'>142</a>
208
+ <a name='L143'></a><a href='#L143'>143</a>
209
+ <a name='L144'></a><a href='#L144'>144</a>
210
+ <a name='L145'></a><a href='#L145'>145</a>
211
+ <a name='L146'></a><a href='#L146'>146</a>
212
+ <a name='L147'></a><a href='#L147'>147</a>
213
+ <a name='L148'></a><a href='#L148'>148</a>
214
+ <a name='L149'></a><a href='#L149'>149</a>
215
+ <a name='L150'></a><a href='#L150'>150</a>
216
+ <a name='L151'></a><a href='#L151'>151</a>
217
+ <a name='L152'></a><a href='#L152'>152</a>
218
+ <a name='L153'></a><a href='#L153'>153</a>
219
+ <a name='L154'></a><a href='#L154'>154</a>
220
+ <a name='L155'></a><a href='#L155'>155</a>
221
+ <a name='L156'></a><a href='#L156'>156</a>
222
+ <a name='L157'></a><a href='#L157'>157</a>
223
+ <a name='L158'></a><a href='#L158'>158</a>
224
+ <a name='L159'></a><a href='#L159'>159</a>
225
+ <a name='L160'></a><a href='#L160'>160</a>
226
+ <a name='L161'></a><a href='#L161'>161</a>
227
+ <a name='L162'></a><a href='#L162'>162</a>
228
+ <a name='L163'></a><a href='#L163'>163</a>
229
+ <a name='L164'></a><a href='#L164'>164</a>
230
+ <a name='L165'></a><a href='#L165'>165</a>
231
+ <a name='L166'></a><a href='#L166'>166</a>
232
+ <a name='L167'></a><a href='#L167'>167</a>
233
+ <a name='L168'></a><a href='#L168'>168</a>
234
+ <a name='L169'></a><a href='#L169'>169</a>
235
+ <a name='L170'></a><a href='#L170'>170</a>
236
+ <a name='L171'></a><a href='#L171'>171</a>
237
+ <a name='L172'></a><a href='#L172'>172</a>
238
+ <a name='L173'></a><a href='#L173'>173</a>
239
+ <a name='L174'></a><a href='#L174'>174</a>
240
+ <a name='L175'></a><a href='#L175'>175</a>
241
+ <a name='L176'></a><a href='#L176'>176</a>
242
+ <a name='L177'></a><a href='#L177'>177</a>
243
+ <a name='L178'></a><a href='#L178'>178</a>
244
+ <a name='L179'></a><a href='#L179'>179</a>
245
+ <a name='L180'></a><a href='#L180'>180</a>
246
+ <a name='L181'></a><a href='#L181'>181</a>
247
+ <a name='L182'></a><a href='#L182'>182</a>
248
+ <a name='L183'></a><a href='#L183'>183</a>
249
+ <a name='L184'></a><a href='#L184'>184</a>
250
+ <a name='L185'></a><a href='#L185'>185</a>
251
+ <a name='L186'></a><a href='#L186'>186</a>
252
+ <a name='L187'></a><a href='#L187'>187</a>
253
+ <a name='L188'></a><a href='#L188'>188</a>
254
+ <a name='L189'></a><a href='#L189'>189</a>
255
+ <a name='L190'></a><a href='#L190'>190</a>
256
+ <a name='L191'></a><a href='#L191'>191</a>
257
+ <a name='L192'></a><a href='#L192'>192</a>
258
+ <a name='L193'></a><a href='#L193'>193</a>
259
+ <a name='L194'></a><a href='#L194'>194</a>
260
+ <a name='L195'></a><a href='#L195'>195</a>
261
+ <a name='L196'></a><a href='#L196'>196</a>
262
+ <a name='L197'></a><a href='#L197'>197</a>
263
+ <a name='L198'></a><a href='#L198'>198</a>
264
+ <a name='L199'></a><a href='#L199'>199</a>
265
+ <a name='L200'></a><a href='#L200'>200</a>
266
+ <a name='L201'></a><a href='#L201'>201</a>
267
+ <a name='L202'></a><a href='#L202'>202</a>
268
+ <a name='L203'></a><a href='#L203'>203</a>
269
+ <a name='L204'></a><a href='#L204'>204</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">1x</span>
270
+ <span class="cline-any cline-yes">1x</span>
271
+ <span class="cline-any cline-yes">1x</span>
272
+ <span class="cline-any cline-yes">1x</span>
273
+ <span class="cline-any cline-yes">1x</span>
274
+ <span class="cline-any cline-yes">1x</span>
275
+ <span class="cline-any cline-yes">1x</span>
276
+ <span class="cline-any cline-yes">1x</span>
277
+ <span class="cline-any cline-yes">1x</span>
278
+ <span class="cline-any cline-yes">321x</span>
279
+ <span class="cline-any cline-yes">321x</span>
280
+ <span class="cline-any cline-yes">321x</span>
281
+ <span class="cline-any cline-yes">321x</span>
282
+ <span class="cline-any cline-yes">321x</span>
283
+ <span class="cline-any cline-yes">321x</span>
284
+ <span class="cline-any cline-yes">321x</span>
285
+ <span class="cline-any cline-yes">321x</span>
286
+ <span class="cline-any cline-yes">321x</span>
287
+ <span class="cline-any cline-yes">321x</span>
288
+ <span class="cline-any cline-yes">321x</span>
289
+ <span class="cline-any cline-yes">321x</span>
290
+ <span class="cline-any cline-yes">321x</span>
291
+ <span class="cline-any cline-yes">321x</span>
292
+ <span class="cline-any cline-yes">321x</span>
293
+ <span class="cline-any cline-yes">35x</span>
294
+ <span class="cline-any cline-yes">35x</span>
295
+ <span class="cline-any cline-yes">27x</span>
296
+ <span class="cline-any cline-yes">27x</span>
297
+ <span class="cline-any cline-yes">321x</span>
298
+ <span class="cline-any cline-yes">321x</span>
299
+ <span class="cline-any cline-yes">321x</span>
300
+ <span class="cline-any cline-yes">15x</span>
301
+ <span class="cline-any cline-yes">15x</span>
302
+ <span class="cline-any cline-yes">15x</span>
303
+ <span class="cline-any cline-yes">15x</span>
304
+ <span class="cline-any cline-yes">15x</span>
305
+ <span class="cline-any cline-yes">15x</span>
306
+ <span class="cline-any cline-yes">1x</span>
307
+ <span class="cline-any cline-yes">1x</span>
308
+ <span class="cline-any cline-yes">1x</span>
309
+ <span class="cline-any cline-yes">14x</span>
310
+ <span class="cline-any cline-yes">15x</span>
311
+ <span class="cline-any cline-yes">1x</span>
312
+ <span class="cline-any cline-yes">1x</span>
313
+ <span class="cline-any cline-yes">1x</span>
314
+ <span class="cline-any cline-yes">13x</span>
315
+ <span class="cline-any cline-yes">13x</span>
316
+ <span class="cline-any cline-yes">13x</span>
317
+ <span class="cline-any cline-yes">13x</span>
318
+ <span class="cline-any cline-yes">13x</span>
319
+ <span class="cline-any cline-yes">13x</span>
320
+ <span class="cline-any cline-yes">9x</span>
321
+ <span class="cline-any cline-yes">15x</span>
322
+ <span class="cline-any cline-yes">8x</span>
323
+ <span class="cline-any cline-yes">1x</span>
324
+ <span class="cline-any cline-yes">8x</span>
325
+ <span class="cline-any cline-yes">7x</span>
326
+ <span class="cline-any cline-yes">7x</span>
327
+ <span class="cline-any cline-yes">15x</span>
328
+ <span class="cline-any cline-yes">1x</span>
329
+ <span class="cline-any cline-yes">1x</span>
330
+ <span class="cline-any cline-yes">1x</span>
331
+ <span class="cline-any cline-yes">1x</span>
332
+ <span class="cline-any cline-yes">15x</span>
333
+ <span class="cline-any cline-yes">1x</span>
334
+ <span class="cline-any cline-yes">1x</span>
335
+ <span class="cline-any cline-yes">1x</span>
336
+ <span class="cline-any cline-yes">1x</span>
337
+ <span class="cline-any cline-yes">1x</span>
338
+ <span class="cline-any cline-yes">1x</span>
339
+ <span class="cline-any cline-yes">1x</span>
340
+ <span class="cline-any cline-yes">15x</span>
341
+ <span class="cline-any cline-yes">10x</span>
342
+ <span class="cline-any cline-yes">10x</span>
343
+ <span class="cline-any cline-yes">15x</span>
344
+ <span class="cline-any cline-yes">321x</span>
345
+ <span class="cline-any cline-yes">321x</span>
346
+ <span class="cline-any cline-yes">1x</span>
347
+ <span class="cline-any cline-yes">1x</span>
348
+ <span class="cline-any cline-yes">321x</span>
349
+ <span class="cline-any cline-yes">321x</span>
350
+ <span class="cline-any cline-yes">4x</span>
351
+ <span class="cline-any cline-yes">4x</span>
352
+ <span class="cline-any cline-yes">1x</span>
353
+ <span class="cline-any cline-yes">1x</span>
354
+ <span class="cline-any cline-yes">1x</span>
355
+ <span class="cline-any cline-yes">3x</span>
356
+ <span class="cline-any cline-yes">3x</span>
357
+ <span class="cline-any cline-yes">4x</span>
358
+ <span class="cline-any cline-yes">1x</span>
359
+ <span class="cline-any cline-yes">1x</span>
360
+ <span class="cline-any cline-yes">1x</span>
361
+ <span class="cline-any cline-yes">2x</span>
362
+ <span class="cline-any cline-yes">4x</span>
363
+ <span class="cline-any cline-yes">1x</span>
364
+ <span class="cline-any cline-yes">1x</span>
365
+ <span class="cline-any cline-yes">1x</span>
366
+ <span class="cline-any cline-yes">1x</span>
367
+ <span class="cline-any cline-yes">1x</span>
368
+ <span class="cline-any cline-yes">1x</span>
369
+ <span class="cline-any cline-yes">4x</span>
370
+ <span class="cline-any cline-yes">321x</span>
371
+ <span class="cline-any cline-yes">321x</span>
372
+ <span class="cline-any cline-yes">8x</span>
373
+ <span class="cline-any cline-yes">8x</span>
374
+ <span class="cline-any cline-yes">8x</span>
375
+ <span class="cline-any cline-yes">8x</span>
376
+ <span class="cline-any cline-yes">8x</span>
377
+ <span class="cline-any cline-yes">8x</span>
378
+ <span class="cline-any cline-yes">8x</span>
379
+ <span class="cline-any cline-yes">8x</span>
380
+ <span class="cline-any cline-yes">8x</span>
381
+ <span class="cline-any cline-yes">8x</span>
382
+ <span class="cline-any cline-yes">8x</span>
383
+ <span class="cline-any cline-yes">8x</span>
384
+ <span class="cline-any cline-yes">8x</span>
385
+ <span class="cline-any cline-yes">8x</span>
386
+ <span class="cline-any cline-yes">8x</span>
387
+ <span class="cline-any cline-yes">8x</span>
388
+ <span class="cline-any cline-yes">8x</span>
389
+ <span class="cline-any cline-yes">8x</span>
390
+ <span class="cline-any cline-yes">8x</span>
391
+ <span class="cline-any cline-yes">8x</span>
392
+ <span class="cline-any cline-yes">8x</span>
393
+ <span class="cline-any cline-yes">8x</span>
394
+ <span class="cline-any cline-yes">8x</span>
395
+ <span class="cline-any cline-yes">8x</span>
396
+ <span class="cline-any cline-yes">8x</span>
397
+ <span class="cline-any cline-yes">313x</span>
398
+ <span class="cline-any cline-yes">313x</span>
399
+ <span class="cline-any cline-yes">15x</span>
400
+ <span class="cline-any cline-yes">15x</span>
401
+ <span class="cline-any cline-yes">15x</span>
402
+ <span class="cline-any cline-yes">313x</span>
403
+ <span class="cline-any cline-yes">313x</span>
404
+ <span class="cline-any cline-yes">313x</span>
405
+ <span class="cline-any cline-yes">313x</span>
406
+ <span class="cline-any cline-yes">313x</span>
407
+ <span class="cline-any cline-yes">313x</span>
408
+ <span class="cline-any cline-yes">313x</span>
409
+ <span class="cline-any cline-yes">313x</span>
410
+ <span class="cline-any cline-yes">313x</span>
411
+ <span class="cline-any cline-yes">313x</span>
412
+ <span class="cline-any cline-yes">313x</span>
413
+ <span class="cline-any cline-yes">313x</span>
414
+ <span class="cline-any cline-yes">313x</span>
415
+ <span class="cline-any cline-yes">313x</span>
416
+ <span class="cline-any cline-yes">313x</span>
417
+ <span class="cline-any cline-yes">313x</span>
418
+ <span class="cline-any cline-yes">313x</span>
419
+ <span class="cline-any cline-yes">313x</span>
420
+ <span class="cline-any cline-yes">313x</span>
421
+ <span class="cline-any cline-yes">313x</span>
422
+ <span class="cline-any cline-yes">313x</span>
423
+ <span class="cline-any cline-yes">313x</span>
424
+ <span class="cline-any cline-yes">313x</span>
425
+ <span class="cline-any cline-yes">313x</span>
426
+ <span class="cline-any cline-yes">313x</span>
427
+ <span class="cline-any cline-yes">313x</span>
428
+ <span class="cline-any cline-yes">313x</span>
429
+ <span class="cline-any cline-yes">313x</span>
430
+ <span class="cline-any cline-yes">313x</span>
431
+ <span class="cline-any cline-yes">313x</span>
432
+ <span class="cline-any cline-yes">313x</span>
433
+ <span class="cline-any cline-yes">313x</span>
434
+ <span class="cline-any cline-yes">313x</span>
435
+ <span class="cline-any cline-yes">313x</span>
436
+ <span class="cline-any cline-yes">313x</span>
437
+ <span class="cline-any cline-yes">313x</span>
438
+ <span class="cline-any cline-yes">313x</span>
439
+ <span class="cline-any cline-yes">313x</span>
440
+ <span class="cline-any cline-yes">313x</span>
441
+ <span class="cline-any cline-yes">313x</span>
442
+ <span class="cline-any cline-yes">313x</span>
443
+ <span class="cline-any cline-yes">321x</span>
444
+ <span class="cline-any cline-yes">321x</span>
445
+ <span class="cline-any cline-yes">321x</span>
446
+ <span class="cline-any cline-yes">321x</span>
447
+ <span class="cline-any cline-yes">321x</span>
448
+ <span class="cline-any cline-yes">321x</span>
449
+ <span class="cline-any cline-yes">321x</span>
450
+ <span class="cline-any cline-yes">321x</span>
451
+ <span class="cline-any cline-yes">321x</span>
452
+ <span class="cline-any cline-yes">321x</span>
453
+ <span class="cline-any cline-yes">321x</span>
454
+ <span class="cline-any cline-yes">321x</span>
455
+ <span class="cline-any cline-yes">321x</span>
456
+ <span class="cline-any cline-yes">321x</span>
457
+ <span class="cline-any cline-yes">321x</span>
458
+ <span class="cline-any cline-yes">321x</span>
459
+ <span class="cline-any cline-yes">321x</span>
460
+ <span class="cline-any cline-yes">321x</span>
461
+ <span class="cline-any cline-yes">2x</span>
462
+ <span class="cline-any cline-yes">2x</span>
463
+ <span class="cline-any cline-yes">2x</span>
464
+ <span class="cline-any cline-yes">2x</span>
465
+ <span class="cline-any cline-yes">2x</span>
466
+ <span class="cline-any cline-yes">321x</span>
467
+ <span class="cline-any cline-yes">321x</span>
468
+ <span class="cline-any cline-yes">321x</span>
469
+ <span class="cline-any cline-yes">321x</span>
470
+ <span class="cline-any cline-yes">1x</span>
471
+ <span class="cline-any cline-yes">1x</span>
472
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import { useTranslation } from "../context/I18nProvider";
473
+ import { useCrudify } from "../context/CrudifyProvider";
474
+ import { useState, useEffect, useRef } from "react";
475
+ import { Typography, TextField, Button, Box, CircularProgress, Alert, Link } from "@mui/material";
476
+ import { handleCrudifyError } from "../../../utils/errorHandler";
477
+ import { createFormErrorTranslator, validateEmail } from "./utils";
478
+ import type { LoginFormProps } from "../types";
479
+ &nbsp;
480
+ const ForgotPasswordForm: React.FC&lt;LoginFormProps&gt; = ({ onScreenChange, onError }) =&gt; {
481
+ const { crudify } = useCrudify();
482
+ const [email, setEmail] = useState("");
483
+ const [loading, setLoading] = useState(false);
484
+ const [errors, setErrors] = useState&lt;string[]&gt;([]);
485
+ const [helperTextEmail, setHelperTextEmail] = useState&lt;string | null&gt;(null);
486
+ const [emailSent, setEmailSent] = useState(false);
487
+ const [codeAlreadyExists, setCodeAlreadyExists] = useState(false);
488
+ const emailInputRef = useRef&lt;HTMLInputElement | null&gt;(null);
489
+ &nbsp;
490
+ const { t } = useTranslation();
491
+ &nbsp;
492
+ // Create error translator for this form's namespace
493
+ const translateError = createFormErrorTranslator(t, "forgotPassword");
494
+ &nbsp;
495
+ useEffect(() =&gt; {
496
+ // Focus email input when component mounts
497
+ if (emailInputRef.current &amp;&amp; !emailSent &amp;&amp; !codeAlreadyExists) {
498
+ emailInputRef.current.focus();
499
+ }
500
+ }, [emailSent, codeAlreadyExists]);
501
+ &nbsp;
502
+ const handleSubmit = async () =&gt; {
503
+ if (loading || !crudify) <span class="branch-0 cbranch-no" title="branch not covered" >return;</span>
504
+ &nbsp;
505
+ setErrors([]);
506
+ setHelperTextEmail(null);
507
+ &nbsp;
508
+ if (!email) {
509
+ setHelperTextEmail(t("forgotPassword.emailRequired"));
510
+ return;
511
+ }
512
+ &nbsp;
513
+ if (!validateEmail(email)) {
514
+ setHelperTextEmail(t("forgotPassword.invalidEmail"));
515
+ return;
516
+ }
517
+ &nbsp;
518
+ setLoading(true);
519
+ &nbsp;
520
+ try {
521
+ const data = [{ operation: "requestPasswordReset", data: { email } }];
522
+ const response = await crudify.transaction(data);
523
+ &nbsp;
524
+ if (response.success) {
525
+ if (response.data &amp;&amp; (response.data as { existingCodeValid?: boolean }).existingCodeValid) {
526
+ setCodeAlreadyExists(true);
527
+ } else {
528
+ setEmailSent(true);
529
+ }
530
+ } else {
531
+ const parsedErrors = handleCrudifyError(response);
532
+ const translatedErrors = parsedErrors.map(translateError);
533
+ setErrors(translatedErrors);
534
+ }
535
+ } catch (error) {
536
+ const parsedErrors = handleCrudifyError(error);
537
+ const translatedErrors = parsedErrors.map(translateError);
538
+ setErrors(translatedErrors);
539
+ &nbsp;
540
+ if (onError) {
541
+ onError(translatedErrors.join(", "));
542
+ }
543
+ } finally {
544
+ setLoading(false);
545
+ }
546
+ };
547
+ &nbsp;
548
+ const handleBack = () =&gt; {
549
+ onScreenChange?.("login");
550
+ };
551
+ &nbsp;
552
+ const handleGoToCheckCode = () =&gt; {
553
+ // If email was already sent or code exists, navigate with current email
554
+ if (emailSent || codeAlreadyExists) {
555
+ onScreenChange?.("checkCode", { email });
556
+ return;
557
+ }
558
+ &nbsp;
559
+ // Validate email when called from initial form
560
+ if (!email) {
561
+ setHelperTextEmail(t("forgotPassword.emailRequired"));
562
+ return;
563
+ }
564
+ &nbsp;
565
+ if (!validateEmail(email)) {
566
+ setHelperTextEmail(t("forgotPassword.invalidEmail"));
567
+ return;
568
+ }
569
+ &nbsp;
570
+ // Email is valid, proceed with navigation
571
+ onScreenChange?.("checkCode", { email });
572
+ };
573
+ &nbsp;
574
+ if (emailSent || codeAlreadyExists) {
575
+ return (
576
+ &lt;&gt;
577
+ &lt;Box sx={{ width: "100%", display: "flex", flexDirection: "column", gap: 2, textAlign: "center" }}&gt;
578
+ &lt;Box sx={{ mb: 2 }}&gt;
579
+ &lt;Typography variant="h5" component="h1" sx={{ mb: 1, fontWeight: 600 }}&gt;
580
+ {codeAlreadyExists ? t("forgotPassword.codeAlreadyExistsMessage") : t("forgotPassword.emailSentMessage")}
581
+ &lt;/Typography&gt;
582
+ &lt;Typography variant="body2" sx={{ color: codeAlreadyExists ? "success.main" : "grey.600" }}&gt;
583
+ {codeAlreadyExists ? t("forgotPassword.checkEmailInstructions") : t("forgotPassword.checkEmailInstructions")}
584
+ &lt;/Typography&gt;
585
+ &lt;/Box&gt;
586
+ &nbsp;
587
+ &lt;Button type="button" onClick={handleGoToCheckCode} fullWidth variant="contained" color="primary" sx={{ mt: 2, mb: 2 }}&gt;
588
+ {t("forgotPassword.enterCodeLink")}
589
+ &lt;/Button&gt;
590
+ &nbsp;
591
+ &lt;Box sx={{ display: "flex", justifyContent: "center", alignItems: "center" }}&gt;
592
+ &lt;Link sx={{ cursor: "pointer" }} onClick={handleBack} variant="body2" color="secondary"&gt;
593
+ {t("base.btn.back")}
594
+ &lt;/Link&gt;
595
+ &lt;/Box&gt;
596
+ &lt;/Box&gt;
597
+ &lt;/&gt;
598
+ );
599
+ }
600
+ &nbsp;
601
+ const handleFormSubmit = (e: React.FormEvent) =&gt; {
602
+ e.preventDefault();
603
+ handleSubmit();
604
+ };
605
+ &nbsp;
606
+ return (
607
+ &lt;&gt;
608
+ &lt;Box component="form" noValidate onSubmit={handleFormSubmit} sx={{ width: "100%", display: "flex", flexDirection: "column", gap: 2 }}&gt;
609
+ &lt;Box sx={{ mb: 2 }}&gt;
610
+ &lt;Typography variant="h5" component="h1" sx={{ mb: 1, fontWeight: 600 }}&gt;
611
+ {t("forgotPassword.title")}
612
+ &lt;/Typography&gt;
613
+ &lt;Typography variant="body2" sx={{ color: "grey.600" }}&gt;
614
+ {t("forgotPassword.instructions")}
615
+ &lt;/Typography&gt;
616
+ &lt;/Box&gt;
617
+ &nbsp;
618
+ &lt;Box sx={{ mb: 1 }}&gt;
619
+ &lt;Typography
620
+ variant="body2"
621
+ component="label"
622
+ htmlFor="email"
623
+ sx={{ display: "block", fontWeight: 500, color: "grey.700", mb: 0.5 }}
624
+ &gt;
625
+ {t("forgotPassword.emailLabel")}
626
+ &lt;/Typography&gt;
627
+ &lt;TextField
628
+ fullWidth
629
+ id="email"
630
+ name="email"
631
+ type="email"
632
+ value={email}
633
+ disabled={loading}
634
+ onChange={(e) =&gt; setEmail(e.target.value)}
635
+ error={!!helperTextEmail}
636
+ helperText={helperTextEmail}
637
+ autoComplete="email"
638
+ placeholder={t("forgotPassword.emailPlaceholder")}
639
+ required
640
+ autoFocus
641
+ inputRef={emailInputRef}
642
+ /&gt;
643
+ &lt;/Box&gt;
644
+ &nbsp;
645
+ &lt;Button disabled={loading} type="submit" fullWidth variant="contained" color="primary" sx={{ mt: 2, mb: 2 }}&gt;
646
+ {loading ? &lt;CircularProgress size={20} /&gt; : t("forgotPassword.sendCodeButton")}
647
+ &lt;/Button&gt;
648
+ &nbsp;
649
+ &lt;Box sx={{ display: "flex", justifyContent: "center", alignItems: "center", gap: 2 }}&gt;
650
+ &lt;Link sx={{ cursor: "pointer" }} onClick={handleBack} variant="body2" color="secondary"&gt;
651
+ {t("base.btn.back")}
652
+ &lt;/Link&gt;
653
+ &lt;Typography variant="body2" sx={{ color: "grey.400" }}&gt;
654
+
655
+ &lt;/Typography&gt;
656
+ &lt;Link sx={{ cursor: "pointer" }} onClick={handleGoToCheckCode} variant="body2" color="secondary"&gt;
657
+ {t("login.alreadyHaveCodeLink")}
658
+ &lt;/Link&gt;
659
+ &lt;/Box&gt;
660
+ &lt;/Box&gt;
661
+ &nbsp;
662
+ &lt;Box&gt;
663
+ {errors.length &gt; 0 &amp;&amp;
664
+ errors.map((error, index) =&gt; (
665
+ &lt;Alert variant="filled" key={index} sx={{ mt: 2 }} severity="error"&gt;
666
+ {error}
667
+ &lt;/Alert&gt;
668
+ ))}
669
+ &lt;/Box&gt;
670
+ &lt;/&gt;
671
+ );
672
+ };
673
+ &nbsp;
674
+ export default ForgotPasswordForm;
675
+ &nbsp;</pre></td></tr></table></pre>
676
+
677
+ <div class='push'></div><!-- for sticky footer -->
678
+ </div><!-- /wrapper -->
679
+ <div class='footer quiet pad2 space-top1 center small'>
680
+ Code coverage generated by
681
+ <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
682
+ at 2026-01-28T06:22:15.683Z
683
+ </div>
684
+ <script src="../../../prettify.js"></script>
685
+ <script>
686
+ window.onload = function () {
687
+ prettyPrint();
688
+ };
689
+ </script>
690
+ <script src="../../../sorter.js"></script>
691
+ <script src="../../../block-navigation.js"></script>
692
+ </body>
693
+ </html>
694
+