@simsustech/quasar-components 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (301) hide show
  1. package/.eslintignore +2 -0
  2. package/.eslintrc.cjs +19 -0
  3. package/.prettierignore +2 -0
  4. package/.prettierrc.json +22 -0
  5. package/CHANGELOG.md +7 -0
  6. package/LICENSE +21 -0
  7. package/StandardComponent.vue +50 -0
  8. package/package.json +81 -0
  9. package/src/shims-vue.d.ts +6 -0
  10. package/src/ui/authentication/ConsentList.vue +89 -0
  11. package/src/ui/authentication/EmailChangeForm.vue +128 -0
  12. package/src/ui/authentication/EmailChangeStepper.vue +153 -0
  13. package/src/ui/authentication/LoginButton.vue +56 -0
  14. package/src/ui/authentication/LoginForm.vue +162 -0
  15. package/src/ui/authentication/OtpInput.vue +30 -0
  16. package/src/ui/authentication/PasswordChangeForm.vue +161 -0
  17. package/src/ui/authentication/PasswordChangeStepper.vue +153 -0
  18. package/src/ui/authentication/README.md +15 -0
  19. package/src/ui/authentication/RegisterForm.vue +218 -0
  20. package/src/ui/authentication/RequestOtpForm.vue +99 -0
  21. package/src/ui/authentication/UserMenuButton.vue +54 -0
  22. package/src/ui/authentication/VerificationSlider.vue +57 -0
  23. package/src/ui/authentication/index.ts +12 -0
  24. package/src/ui/authentication/lang/en-US.ts +94 -0
  25. package/src/ui/authentication/lang/index.ts +124 -0
  26. package/src/ui/authentication/lang/nl.ts +94 -0
  27. package/src/ui/flags/README.md +30 -0
  28. package/src/ui/flags/assets/en-US.svg +26 -0
  29. package/src/ui/flags/assets/nl.svg +8 -0
  30. package/src/ui/flags/index.ts +4 -0
  31. package/src/ui/flags/lang/en-US.ts +135 -0
  32. package/src/ui/flags/lang/index.ts +169 -0
  33. package/src/ui/flags/lang/nl.ts +135 -0
  34. package/src/ui/flags/vue-flags/ad.svg +12 -0
  35. package/src/ui/flags/vue-flags/ae.svg +9 -0
  36. package/src/ui/flags/vue-flags/af.svg +11 -0
  37. package/src/ui/flags/vue-flags/ag.svg +12 -0
  38. package/src/ui/flags/vue-flags/ai.svg +25 -0
  39. package/src/ui/flags/vue-flags/al.svg +7 -0
  40. package/src/ui/flags/vue-flags/am.svg +7 -0
  41. package/src/ui/flags/vue-flags/ao.svg +11 -0
  42. package/src/ui/flags/vue-flags/aq.svg +13 -0
  43. package/src/ui/flags/vue-flags/ar.svg +10 -0
  44. package/src/ui/flags/vue-flags/as.svg +9 -0
  45. package/src/ui/flags/vue-flags/at.svg +9 -0
  46. package/src/ui/flags/vue-flags/au.svg +28 -0
  47. package/src/ui/flags/vue-flags/aw.svg +11 -0
  48. package/src/ui/flags/vue-flags/ax.svg +7 -0
  49. package/src/ui/flags/vue-flags/az.svg +11 -0
  50. package/src/ui/flags/vue-flags/ba.svg +20 -0
  51. package/src/ui/flags/vue-flags/bb.svg +10 -0
  52. package/src/ui/flags/vue-flags/bd.svg +6 -0
  53. package/src/ui/flags/vue-flags/be.svg +7 -0
  54. package/src/ui/flags/vue-flags/bf.svg +8 -0
  55. package/src/ui/flags/vue-flags/bg.svg +8 -0
  56. package/src/ui/flags/vue-flags/bh.svg +6 -0
  57. package/src/ui/flags/vue-flags/bi.svg +20 -0
  58. package/src/ui/flags/vue-flags/bj.svg +7 -0
  59. package/src/ui/flags/vue-flags/bl.svg +14 -0
  60. package/src/ui/flags/vue-flags/bm.svg +43 -0
  61. package/src/ui/flags/vue-flags/bn.svg +16 -0
  62. package/src/ui/flags/vue-flags/bo.svg +7 -0
  63. package/src/ui/flags/vue-flags/bq.svg +9 -0
  64. package/src/ui/flags/vue-flags/br.svg +11 -0
  65. package/src/ui/flags/vue-flags/bs.svg +10 -0
  66. package/src/ui/flags/vue-flags/bt.svg +7 -0
  67. package/src/ui/flags/vue-flags/bv.svg +8 -0
  68. package/src/ui/flags/vue-flags/bw.svg +10 -0
  69. package/src/ui/flags/vue-flags/by.svg +17 -0
  70. package/src/ui/flags/vue-flags/bz.svg +14 -0
  71. package/src/ui/flags/vue-flags/ca.svg +11 -0
  72. package/src/ui/flags/vue-flags/cc.svg +46 -0
  73. package/src/ui/flags/vue-flags/cd.svg +9 -0
  74. package/src/ui/flags/vue-flags/cf.svg +19 -0
  75. package/src/ui/flags/vue-flags/cg.svg +8 -0
  76. package/src/ui/flags/vue-flags/ch.svg +7 -0
  77. package/src/ui/flags/vue-flags/ci.svg +8 -0
  78. package/src/ui/flags/vue-flags/ck.svg +27 -0
  79. package/src/ui/flags/vue-flags/cl.svg +9 -0
  80. package/src/ui/flags/vue-flags/cm.svg +11 -0
  81. package/src/ui/flags/vue-flags/cn.svg +13 -0
  82. package/src/ui/flags/vue-flags/co.svg +8 -0
  83. package/src/ui/flags/vue-flags/cr.svg +11 -0
  84. package/src/ui/flags/vue-flags/cu.svg +14 -0
  85. package/src/ui/flags/vue-flags/cv.svg +23 -0
  86. package/src/ui/flags/vue-flags/cw.svg +11 -0
  87. package/src/ui/flags/vue-flags/cx.svg +17 -0
  88. package/src/ui/flags/vue-flags/cy.svg +8 -0
  89. package/src/ui/flags/vue-flags/cz.svg +8 -0
  90. package/src/ui/flags/vue-flags/de.svg +8 -0
  91. package/src/ui/flags/vue-flags/dj.svg +9 -0
  92. package/src/ui/flags/vue-flags/dk.svg +7 -0
  93. package/src/ui/flags/vue-flags/dm.svg +26 -0
  94. package/src/ui/flags/vue-flags/do.svg +13 -0
  95. package/src/ui/flags/vue-flags/dz.svg +10 -0
  96. package/src/ui/flags/vue-flags/ec.svg +11 -0
  97. package/src/ui/flags/vue-flags/ee.svg +8 -0
  98. package/src/ui/flags/vue-flags/eg.svg +9 -0
  99. package/src/ui/flags/vue-flags/eh.svg +13 -0
  100. package/src/ui/flags/vue-flags/er.svg +9 -0
  101. package/src/ui/flags/vue-flags/es.svg +10 -0
  102. package/src/ui/flags/vue-flags/et.svg +13 -0
  103. package/src/ui/flags/vue-flags/fi.svg +7 -0
  104. package/src/ui/flags/vue-flags/fj.svg +18 -0
  105. package/src/ui/flags/vue-flags/fk.svg +26 -0
  106. package/src/ui/flags/vue-flags/fm.svg +12 -0
  107. package/src/ui/flags/vue-flags/fo.svg +8 -0
  108. package/src/ui/flags/vue-flags/fr.svg +8 -0
  109. package/src/ui/flags/vue-flags/ga.svg +8 -0
  110. package/src/ui/flags/vue-flags/gb.svg +31 -0
  111. package/src/ui/flags/vue-flags/gd.svg +26 -0
  112. package/src/ui/flags/vue-flags/ge.svg +13 -0
  113. package/src/ui/flags/vue-flags/gf.svg +8 -0
  114. package/src/ui/flags/vue-flags/gg.svg +8 -0
  115. package/src/ui/flags/vue-flags/gh.svg +9 -0
  116. package/src/ui/flags/vue-flags/gi.svg +11 -0
  117. package/src/ui/flags/vue-flags/gl.svg +11 -0
  118. package/src/ui/flags/vue-flags/gm.svg +9 -0
  119. package/src/ui/flags/vue-flags/gn.svg +8 -0
  120. package/src/ui/flags/vue-flags/gp.svg +8 -0
  121. package/src/ui/flags/vue-flags/gq.svg +12 -0
  122. package/src/ui/flags/vue-flags/gr.svg +17 -0
  123. package/src/ui/flags/vue-flags/gs.svg +159 -0
  124. package/src/ui/flags/vue-flags/gt.svg +12 -0
  125. package/src/ui/flags/vue-flags/gu.svg +13 -0
  126. package/src/ui/flags/vue-flags/gw.svg +9 -0
  127. package/src/ui/flags/vue-flags/gy.svg +14 -0
  128. package/src/ui/flags/vue-flags/hk.svg +13 -0
  129. package/src/ui/flags/vue-flags/hm.svg +28 -0
  130. package/src/ui/flags/vue-flags/hn.svg +15 -0
  131. package/src/ui/flags/vue-flags/hr.svg +31 -0
  132. package/src/ui/flags/vue-flags/ht.svg +13 -0
  133. package/src/ui/flags/vue-flags/hu.svg +8 -0
  134. package/src/ui/flags/vue-flags/id.svg +7 -0
  135. package/src/ui/flags/vue-flags/ie.svg +8 -0
  136. package/src/ui/flags/vue-flags/il.svg +11 -0
  137. package/src/ui/flags/vue-flags/im.svg +7 -0
  138. package/src/ui/flags/vue-flags/in.svg +11 -0
  139. package/src/ui/flags/vue-flags/io.svg +60 -0
  140. package/src/ui/flags/vue-flags/iq.svg +13 -0
  141. package/src/ui/flags/vue-flags/ir.svg +37 -0
  142. package/src/ui/flags/vue-flags/is.svg +8 -0
  143. package/src/ui/flags/vue-flags/it.svg +8 -0
  144. package/src/ui/flags/vue-flags/je.svg +12 -0
  145. package/src/ui/flags/vue-flags/jm.svg +10 -0
  146. package/src/ui/flags/vue-flags/jo.svg +10 -0
  147. package/src/ui/flags/vue-flags/jp.svg +7 -0
  148. package/src/ui/flags/vue-flags/ke.svg +19 -0
  149. package/src/ui/flags/vue-flags/kg.svg +17 -0
  150. package/src/ui/flags/vue-flags/kh.svg +11 -0
  151. package/src/ui/flags/vue-flags/ki.svg +21 -0
  152. package/src/ui/flags/vue-flags/km.svg +17 -0
  153. package/src/ui/flags/vue-flags/kn.svg +13 -0
  154. package/src/ui/flags/vue-flags/kp.svg +14 -0
  155. package/src/ui/flags/vue-flags/kr.svg +26 -0
  156. package/src/ui/flags/vue-flags/kw.svg +9 -0
  157. package/src/ui/flags/vue-flags/ky.svg +25 -0
  158. package/src/ui/flags/vue-flags/kz.svg +9 -0
  159. package/src/ui/flags/vue-flags/la.svg +11 -0
  160. package/src/ui/flags/vue-flags/lb.svg +11 -0
  161. package/src/ui/flags/vue-flags/lc.svg +9 -0
  162. package/src/ui/flags/vue-flags/li.svg +8 -0
  163. package/src/ui/flags/vue-flags/lk.svg +19 -0
  164. package/src/ui/flags/vue-flags/lr.svg +16 -0
  165. package/src/ui/flags/vue-flags/ls.svg +9 -0
  166. package/src/ui/flags/vue-flags/lt.svg +8 -0
  167. package/src/ui/flags/vue-flags/lu.svg +8 -0
  168. package/src/ui/flags/vue-flags/lv.svg +10 -0
  169. package/src/ui/flags/vue-flags/ly.svg +12 -0
  170. package/src/ui/flags/vue-flags/ma.svg +7 -0
  171. package/src/ui/flags/vue-flags/mc.svg +7 -0
  172. package/src/ui/flags/vue-flags/md.svg +11 -0
  173. package/src/ui/flags/vue-flags/me.svg +13 -0
  174. package/src/ui/flags/vue-flags/mf.svg +8 -0
  175. package/src/ui/flags/vue-flags/mg.svg +8 -0
  176. package/src/ui/flags/vue-flags/mh.svg +11 -0
  177. package/src/ui/flags/vue-flags/mk.svg +18 -0
  178. package/src/ui/flags/vue-flags/ml.svg +8 -0
  179. package/src/ui/flags/vue-flags/mm.svg +9 -0
  180. package/src/ui/flags/vue-flags/mn.svg +19 -0
  181. package/src/ui/flags/vue-flags/mo.svg +18 -0
  182. package/src/ui/flags/vue-flags/mp.svg +10 -0
  183. package/src/ui/flags/vue-flags/mq.svg +13 -0
  184. package/src/ui/flags/vue-flags/mr.svg +10 -0
  185. package/src/ui/flags/vue-flags/ms.svg +23 -0
  186. package/src/ui/flags/vue-flags/mt.svg +8 -0
  187. package/src/ui/flags/vue-flags/mu.svg +9 -0
  188. package/src/ui/flags/vue-flags/mv.svg +8 -0
  189. package/src/ui/flags/vue-flags/mw.svg +9 -0
  190. package/src/ui/flags/vue-flags/mx.svg +10 -0
  191. package/src/ui/flags/vue-flags/my.svg +17 -0
  192. package/src/ui/flags/vue-flags/mz.svg +13 -0
  193. package/src/ui/flags/vue-flags/na.svg +10 -0
  194. package/src/ui/flags/vue-flags/nc.svg +8 -0
  195. package/src/ui/flags/vue-flags/ne.svg +9 -0
  196. package/src/ui/flags/vue-flags/nf.svg +11 -0
  197. package/src/ui/flags/vue-flags/ng.svg +10 -0
  198. package/src/ui/flags/vue-flags/ni.svg +14 -0
  199. package/src/ui/flags/vue-flags/nl.svg +8 -0
  200. package/src/ui/flags/vue-flags/no.svg +8 -0
  201. package/src/ui/flags/vue-flags/np.svg +13 -0
  202. package/src/ui/flags/vue-flags/nr.svg +8 -0
  203. package/src/ui/flags/vue-flags/nu.svg +48 -0
  204. package/src/ui/flags/vue-flags/nz.svg +26 -0
  205. package/src/ui/flags/vue-flags/om.svg +14 -0
  206. package/src/ui/flags/vue-flags/pa.svg +10 -0
  207. package/src/ui/flags/vue-flags/pe.svg +10 -0
  208. package/src/ui/flags/vue-flags/pf.svg +17 -0
  209. package/src/ui/flags/vue-flags/pg.svg +15 -0
  210. package/src/ui/flags/vue-flags/ph.svg +16 -0
  211. package/src/ui/flags/vue-flags/pk.svg +14 -0
  212. package/src/ui/flags/vue-flags/pl.svg +10 -0
  213. package/src/ui/flags/vue-flags/pm.svg +8 -0
  214. package/src/ui/flags/vue-flags/pn.svg +24 -0
  215. package/src/ui/flags/vue-flags/pr.svg +13 -0
  216. package/src/ui/flags/vue-flags/ps.svg +9 -0
  217. package/src/ui/flags/vue-flags/pt.svg +10 -0
  218. package/src/ui/flags/vue-flags/pw.svg +7 -0
  219. package/src/ui/flags/vue-flags/py.svg +10 -0
  220. package/src/ui/flags/vue-flags/qa.svg +7 -0
  221. package/src/ui/flags/vue-flags/re.svg +8 -0
  222. package/src/ui/flags/vue-flags/ro.svg +8 -0
  223. package/src/ui/flags/vue-flags/rs.svg +14 -0
  224. package/src/ui/flags/vue-flags/ru.svg +9 -0
  225. package/src/ui/flags/vue-flags/rw.svg +9 -0
  226. package/src/ui/flags/vue-flags/sa.svg +14 -0
  227. package/src/ui/flags/vue-flags/sb.svg +15 -0
  228. package/src/ui/flags/vue-flags/sc.svg +10 -0
  229. package/src/ui/flags/vue-flags/sd.svg +9 -0
  230. package/src/ui/flags/vue-flags/se.svg +7 -0
  231. package/src/ui/flags/vue-flags/sg.svg +15 -0
  232. package/src/ui/flags/vue-flags/sh.svg +31 -0
  233. package/src/ui/flags/vue-flags/si.svg +11 -0
  234. package/src/ui/flags/vue-flags/sj.svg +8 -0
  235. package/src/ui/flags/vue-flags/sk.svg +12 -0
  236. package/src/ui/flags/vue-flags/sl.svg +8 -0
  237. package/src/ui/flags/vue-flags/sm.svg +12 -0
  238. package/src/ui/flags/vue-flags/sn.svg +11 -0
  239. package/src/ui/flags/vue-flags/so.svg +7 -0
  240. package/src/ui/flags/vue-flags/sr.svg +12 -0
  241. package/src/ui/flags/vue-flags/ss.svg +11 -0
  242. package/src/ui/flags/vue-flags/st.svg +13 -0
  243. package/src/ui/flags/vue-flags/sv.svg +13 -0
  244. package/src/ui/flags/vue-flags/sx.svg +15 -0
  245. package/src/ui/flags/vue-flags/sy.svg +12 -0
  246. package/src/ui/flags/vue-flags/sz.svg +27 -0
  247. package/src/ui/flags/vue-flags/tc.svg +25 -0
  248. package/src/ui/flags/vue-flags/td.svg +8 -0
  249. package/src/ui/flags/vue-flags/tf.svg +9 -0
  250. package/src/ui/flags/vue-flags/tg.svg +13 -0
  251. package/src/ui/flags/vue-flags/th.svg +11 -0
  252. package/src/ui/flags/vue-flags/tj.svg +18 -0
  253. package/src/ui/flags/vue-flags/tk.svg +16 -0
  254. package/src/ui/flags/vue-flags/tl.svg +9 -0
  255. package/src/ui/flags/vue-flags/tm.svg +35 -0
  256. package/src/ui/flags/vue-flags/tn.svg +11 -0
  257. package/src/ui/flags/vue-flags/to.svg +8 -0
  258. package/src/ui/flags/vue-flags/tr.svg +10 -0
  259. package/src/ui/flags/vue-flags/tt.svg +8 -0
  260. package/src/ui/flags/vue-flags/tv.svg +9 -0
  261. package/src/ui/flags/vue-flags/tw.svg +10 -0
  262. package/src/ui/flags/vue-flags/tz.svg +9 -0
  263. package/src/ui/flags/vue-flags/ua.svg +7 -0
  264. package/src/ui/flags/vue-flags/ug.svg +12 -0
  265. package/src/ui/flags/vue-flags/um.svg +26 -0
  266. package/src/ui/flags/vue-flags/unknown.svg +7 -0
  267. package/src/ui/flags/vue-flags/us.svg +26 -0
  268. package/src/ui/flags/vue-flags/uy.svg +14 -0
  269. package/src/ui/flags/vue-flags/uz.svg +27 -0
  270. package/src/ui/flags/vue-flags/va.svg +9 -0
  271. package/src/ui/flags/vue-flags/vc.svg +13 -0
  272. package/src/ui/flags/vue-flags/ve.svg +18 -0
  273. package/src/ui/flags/vue-flags/vg.svg +34 -0
  274. package/src/ui/flags/vue-flags/vi.svg +20 -0
  275. package/src/ui/flags/vue-flags/vn.svg +7 -0
  276. package/src/ui/flags/vue-flags/vu.svg +15 -0
  277. package/src/ui/flags/vue-flags/wf.svg +8 -0
  278. package/src/ui/flags/vue-flags/ws.svg +14 -0
  279. package/src/ui/flags/vue-flags/ye.svg +8 -0
  280. package/src/ui/flags/vue-flags/yt.svg +8 -0
  281. package/src/ui/flags/vue-flags/za.svg +11 -0
  282. package/src/ui/flags/vue-flags/zm.svg +10 -0
  283. package/src/ui/flags/vue-flags/zw.svg +20 -0
  284. package/src/ui/general/QStyledCard.vue +77 -0
  285. package/src/ui/general/QStyledLayout.vue +108 -0
  286. package/src/ui/general/QSubmitButton.vue +70 -0
  287. package/src/ui/general/index.ts +2 -0
  288. package/src/ui/general/lang/en-US.ts +10 -0
  289. package/src/ui/general/lang/index.ts +44 -0
  290. package/src/ui/general/lang/nl.ts +10 -0
  291. package/src/ui/icons/README.md +3 -0
  292. package/src/ui/icons/assets/microsoft.svg +10 -0
  293. package/src/ui/icons/icons.ts +5 -0
  294. package/src/ui/icons/index.ts +3 -0
  295. package/src/ui/index.ts +2 -0
  296. package/src/vite-plugin.ts +30 -0
  297. package/tsconfig.build.plugin.json +7 -0
  298. package/tsconfig.json +23 -0
  299. package/tsconfig.node.json +10 -0
  300. package/tsconfig.types.json +17 -0
  301. package/vite.config.ts +136 -0
@@ -0,0 +1,218 @@
1
+ <template>
2
+ <q-form ref="formRef" class="q-gutter-md" v-bind="form">
3
+ <q-input
4
+ v-if="!useUsername"
5
+ v-bind="input"
6
+ id="email"
7
+ v-model="email"
8
+ name="email"
9
+ :label="lang.register.fields.email"
10
+ bottom-slots
11
+ :rules="validations['email']"
12
+ lazy-rules
13
+ />
14
+ <q-input
15
+ v-if="useUsername"
16
+ v-bind="input"
17
+ id="username"
18
+ v-model="username"
19
+ name="username"
20
+ :label="lang.register.fields.username"
21
+ bottom-slots
22
+ :rules="validations['username']"
23
+ lazy-rules
24
+ />
25
+ <q-input
26
+ v-for="field in extraFields"
27
+ :key="field.name"
28
+ v-model="extraFieldValues[field.name]"
29
+ type="text"
30
+ :name="field.name"
31
+ :label="field.label"
32
+ :rules="field.rules"
33
+ bottom-slots
34
+ />
35
+ <q-input
36
+ v-bind="input"
37
+ id="password"
38
+ v-model="password"
39
+ name="password"
40
+ :type="showPassword ? 'text' : 'password'"
41
+ :label="lang.register.fields.password"
42
+ :rules="validations['password']"
43
+ lazy-rules
44
+ bottom-slots
45
+ >
46
+ <template #append>
47
+ <q-icon
48
+ :name="showPassword ? 'visibility' : 'visibility_off'"
49
+ class="cursor-pointer"
50
+ @click="showPassword = !showPassword"
51
+ />
52
+ </template>
53
+ </q-input>
54
+ <q-input
55
+ id="repeatPassword"
56
+ v-model="repeatPassword"
57
+ :type="showPassword ? 'text' : 'password'"
58
+ :label="lang.register.fields.repeatPassword"
59
+ bottom-slots
60
+ required
61
+ :rules="validations['repeatPassword']"
62
+ lazy-rules
63
+ >
64
+ <template #append>
65
+ <q-icon
66
+ :name="showPassword ? 'visibility' : 'visibility_off'"
67
+ class="cursor-pointer"
68
+ @click="showPassword = !showPassword"
69
+ />
70
+ </template>
71
+ </q-input>
72
+ <slot name="default" :submit="submit" />
73
+ </q-form>
74
+ </template>
75
+
76
+ <script lang="ts">
77
+ export default {
78
+ name: 'RegisterForm'
79
+ }
80
+ </script>
81
+
82
+ <script setup lang="ts">
83
+ import { ref, computed, watch, toRef } from 'vue'
84
+ import { useQuasar, QFormProps, QForm, QInputProps } from 'quasar'
85
+ import { useLang, loadLang } from './lang'
86
+ import isEmail from 'validator/es/lib/isEmail.js'
87
+ import equals from 'validator/es/lib/equals.js'
88
+ import isAlphanumeric from 'validator/es/lib/isAlphanumeric.js'
89
+
90
+ import QSubmitButton from '../general/QSubmitButton.vue'
91
+
92
+ export interface Props {
93
+ useUsername?: boolean
94
+ extraFields?: {
95
+ name: string
96
+ label: string
97
+ rules?: ((val: string) => boolean)[]
98
+ }[]
99
+ minimumPasswordLength?: number
100
+ form?: QFormProps & HTMLFormElement
101
+ input?: Omit<
102
+ QInputProps,
103
+ | 'id'
104
+ | 'name'
105
+ | 'modelValue'
106
+ | 'label'
107
+ | 'rules'
108
+ | 'type'
109
+ | 'lazy-rules'
110
+ | 'autofocus'
111
+ | ('label' & { style?: Partial<CSSStyleDeclaration> })
112
+ >
113
+ }
114
+ const props = withDefaults(defineProps<Props>(), {
115
+ minimumPasswordLength: 8,
116
+ extraFields: undefined,
117
+ form: undefined,
118
+ input: undefined
119
+ })
120
+ // const attrs = useAttrs();
121
+ const emit = defineEmits<{
122
+ (
123
+ e: 'submit',
124
+ {
125
+ email,
126
+ password,
127
+ username,
128
+ extraFields,
129
+ done
130
+ }: {
131
+ email?: string
132
+ password: string
133
+ username?: string
134
+ extraFields?: Record<string, string>
135
+ done: () => void
136
+ }
137
+ ): void
138
+ }>()
139
+ const $q = useQuasar()
140
+ const lang = useLang()
141
+ if (lang.value.isoName !== $q.lang.isoName) loadLang($q.lang.isoName)
142
+ watch($q.lang, (val) => {
143
+ loadLang($q.lang.isoName)
144
+ })
145
+
146
+ const email = ref('')
147
+ const password = ref('')
148
+ const repeatPassword = ref('')
149
+ const extraFieldValues = ref<Record<string, string>>({})
150
+ const username = ref('')
151
+ const showPassword = ref(false)
152
+ const header = computed(() => lang.value.register.register)
153
+ const forgotPassword = computed(() => lang.value.register.forgotPassword)
154
+ const accountCreated = computed(() => lang.value.register.accountCreated)
155
+ const unprocessableRequest = computed(() => lang.value.unprocessableRequest)
156
+ const alreadyRegistered = computed(() => lang.value.register.alreadyRegistered)
157
+
158
+ const minimumPasswordLength = toRef(props, 'minimumPasswordLength')
159
+ const formRef = ref<QForm>()
160
+ const validations = computed<
161
+ Record<string, ((val: string) => boolean | string)[]>
162
+ >(() => ({
163
+ email: [
164
+ (val) => !!val || lang.value.register.validations.fieldRequired,
165
+ (val) => isEmail(val) || lang.value.register.validations.invalidEmail
166
+ ],
167
+ username: [
168
+ (val) => !!val || lang.value.register.validations.fieldRequired,
169
+ (val) =>
170
+ isAlphanumeric(val) || lang.value.register.validations.notAlphaNumeric
171
+ ],
172
+ password: [
173
+ (val) => !!val || lang.value.password.validations.fieldRequired,
174
+ (val) =>
175
+ val.length >= minimumPasswordLength.value ||
176
+ lang.value.password.validations.minimumPasswordLength(
177
+ minimumPasswordLength.value
178
+ )
179
+ ],
180
+ repeatPassword: [
181
+ (val) => !!val || lang.value.password.validations.fieldRequired,
182
+ (val) =>
183
+ equals(val, password.value) ||
184
+ lang.value.password.validations.passwordsDoNotMatch
185
+ ]
186
+ }))
187
+
188
+ const submit: InstanceType<typeof QSubmitButton>['$props']['onSubmit'] = (
189
+ evt
190
+ ) => {
191
+ formRef.value?.validate().then((success) => {
192
+ if (success) {
193
+ emit('submit', {
194
+ email: email.value,
195
+ password: password.value,
196
+ username: username.value,
197
+ extraFields: extraFieldValues.value,
198
+ done: evt.done
199
+ })
200
+ } else evt.done()
201
+ })
202
+ }
203
+
204
+ const variables = ref({
205
+ header,
206
+ forgotPassword,
207
+ accountCreated,
208
+ unprocessableRequest,
209
+ alreadyRegistered
210
+ })
211
+ const functions = ref({
212
+ submit
213
+ })
214
+ defineExpose({
215
+ variables,
216
+ functions
217
+ })
218
+ </script>
@@ -0,0 +1,99 @@
1
+ <template>
2
+ <q-form ref="formRef" v-bind="form">
3
+ <q-input
4
+ v-bind="input"
5
+ id="email"
6
+ v-model.trim="email"
7
+ name="email"
8
+ type="text"
9
+ :label="lang.otp.fields.email"
10
+ :rules="validations['email']"
11
+ lazy-rules
12
+ autofocus
13
+ />
14
+ <slot name="default" :submit="submit" />
15
+ </q-form>
16
+ </template>
17
+
18
+ <script lang="ts">
19
+ export default {
20
+ name: 'RequestOtpForm'
21
+ }
22
+ </script>
23
+
24
+ <script setup lang="ts">
25
+ import { ref, computed, watch } from 'vue'
26
+ import { useQuasar, QFormProps, QForm, QInputProps } from 'quasar'
27
+ import { useLang, loadLang } from './lang'
28
+ import isEmail from 'validator/es/lib/isEmail.js'
29
+ import QSubmitButton from '../general/QSubmitButton.vue'
30
+
31
+ export interface Props {
32
+ form?: QFormProps & HTMLFormElement
33
+ input?: Omit<
34
+ QInputProps,
35
+ | 'id'
36
+ | 'name'
37
+ | 'modelValue'
38
+ | 'label'
39
+ | 'rules'
40
+ | 'type'
41
+ | 'lazy-rules'
42
+ | 'autofocus'
43
+ | ('label' & { style?: Partial<CSSStyleDeclaration> })
44
+ >
45
+ }
46
+ defineProps<Props>()
47
+ // const attrs = useAttrs();
48
+ const emit = defineEmits<{
49
+ (
50
+ e: 'submit',
51
+ {
52
+ email,
53
+ done
54
+ }: {
55
+ email: string
56
+ done: () => void
57
+ }
58
+ ): void
59
+ }>()
60
+ const $q = useQuasar()
61
+ const lang = useLang()
62
+ if (lang.value.isoName !== $q.lang.isoName) loadLang($q.lang.isoName)
63
+ watch($q.lang, (val) => {
64
+ loadLang($q.lang.isoName)
65
+ })
66
+
67
+ const email = ref('')
68
+ const header = computed(() => lang.value.otp.request)
69
+
70
+ const formRef = ref<QForm>()
71
+ const validations = computed<
72
+ Record<string, ((val: string) => boolean | string)[]>
73
+ >(() => ({
74
+ email: [
75
+ (val) => !!val || lang.value.otp.validations.fieldRequired,
76
+ (val) => isEmail(val) || lang.value.otp.validations.invalidEmail
77
+ ]
78
+ }))
79
+
80
+ const submit: InstanceType<typeof QSubmitButton>['$props']['onSubmit'] = ({
81
+ done
82
+ }) => {
83
+ formRef.value?.validate().then((success) => {
84
+ if (success) {
85
+ emit('submit', {
86
+ email: email.value,
87
+ done: done
88
+ })
89
+ } else done()
90
+ })
91
+ }
92
+
93
+ const variables = ref({ header })
94
+ const functions = ref({ submit })
95
+ defineExpose({
96
+ variables,
97
+ functions
98
+ })
99
+ </script>
@@ -0,0 +1,54 @@
1
+ <template>
2
+ <q-btn icon="person">
3
+ <q-menu>
4
+ <q-list>
5
+ <q-item :to="userRoute">
6
+ <q-item-section>{{ lang.myAccount }}</q-item-section>
7
+ </q-item>
8
+ <slot name="default" />
9
+ <q-item clickable @click="emit('signOut')">
10
+ <q-item-section>{{ lang.signOut }}</q-item-section>
11
+ </q-item>
12
+ </q-list>
13
+ </q-menu>
14
+ </q-btn>
15
+ </template>
16
+
17
+ <script lang="ts">
18
+ export default {
19
+ name: 'UserMenuButton'
20
+ }
21
+ </script>
22
+
23
+ <script setup lang="ts">
24
+ import { ref, watch } from 'vue'
25
+ import { useQuasar } from 'quasar'
26
+ import { useLang, loadLang } from './lang'
27
+ import type { RouteLocationRaw } from 'vue-router'
28
+
29
+ export interface Props {
30
+ userRoute: RouteLocationRaw
31
+ }
32
+ defineProps<Props>()
33
+ // const attrs = useAttrs();
34
+ const emit = defineEmits<{
35
+ (e: 'signOut'): void
36
+ }>()
37
+ const $q = useQuasar()
38
+ const lang = useLang()
39
+ if (lang.value.isoName !== $q.lang.isoName) loadLang($q.lang.isoName)
40
+ watch($q.lang, (val) => {
41
+ loadLang($q.lang.isoName)
42
+ })
43
+
44
+ const variables = ref({
45
+ // header: lang.value.some.nested.prop
46
+ })
47
+ const functions = ref({
48
+ // submit
49
+ })
50
+ defineExpose({
51
+ variables,
52
+ functions
53
+ })
54
+ </script>
@@ -0,0 +1,57 @@
1
+ <template>
2
+ {{ lang.verification.slider }}
3
+ <q-slider v-model="sliderValue" :color="sliderColor" :readonly="completed" />
4
+ </template>
5
+
6
+ <script lang="ts">
7
+ export default {
8
+ name: 'VerificationSlider'
9
+ }
10
+ </script>
11
+
12
+ <script setup lang="ts">
13
+ import { ref, watch } from 'vue'
14
+ import { useQuasar } from 'quasar'
15
+ import { useLang, loadLang } from './lang'
16
+
17
+ export interface Props {
18
+ useVerificationSlider?: boolean
19
+ }
20
+ defineProps<Props>()
21
+ // const attrs = useAttrs();
22
+ const emit = defineEmits<{
23
+ (e: 'verified'): void
24
+ }>()
25
+ const $q = useQuasar()
26
+ const lang = useLang()
27
+ if (lang.value.isoName !== $q.lang.isoName) loadLang($q.lang.isoName)
28
+ watch($q.lang, (val) => {
29
+ loadLang($q.lang.isoName)
30
+ })
31
+
32
+ const sliderValue = ref(0)
33
+ const sliderColor = ref('red')
34
+ const completed = ref(false)
35
+
36
+ watch(sliderValue, (newVal, oldVal) => {
37
+ if (newVal > 80) {
38
+ sliderColor.value = 'green'
39
+ setTimeout(() => {
40
+ sliderValue.value = 100
41
+ completed.value = true
42
+ }, 500)
43
+ emit('verified')
44
+ }
45
+ })
46
+
47
+ const variables = ref({
48
+ // header: lang.value.some.nested.prop
49
+ })
50
+ const functions = ref({
51
+ // submit
52
+ })
53
+ defineExpose({
54
+ variables,
55
+ functions
56
+ })
57
+ </script>
@@ -0,0 +1,12 @@
1
+ export { default as RequestOtpForm } from './RequestOtpForm.vue'
2
+ export { default as OtpInput } from './OtpInput.vue'
3
+ export { default as EmailChangeForm } from './EmailChangeForm.vue'
4
+ export { default as EmailChangeStepper } from './EmailChangeStepper.vue'
5
+ export { default as PasswordChangeForm } from './PasswordChangeForm.vue'
6
+ export { default as PasswordChangeStepper } from './PasswordChangeStepper.vue'
7
+ export { default as LoginForm } from './LoginForm.vue'
8
+ export { default as RegisterForm } from './RegisterForm.vue'
9
+ export { default as VerificationSlider } from './VerificationSlider.vue'
10
+ export { default as ConsentList } from './ConsentList.vue'
11
+ export { default as UserMenuButton } from './UserMenuButton.vue'
12
+ export { default as LoginButton } from './LoginButton.vue'
@@ -0,0 +1,94 @@
1
+ import type { Language } from '../lang'
2
+
3
+ const lang: Language = {
4
+ isoName: 'en-US',
5
+ myAccount: 'Account',
6
+ signOut: 'Sign out',
7
+ unprocessableRequest: 'The server was unable to process the request.',
8
+ consent: {
9
+ message: (name: string) => `${name} is requesting access to your data.`,
10
+ deny: 'Deny',
11
+ allow: 'Allow'
12
+ },
13
+ email: {
14
+ fields: {
15
+ email: 'Email address',
16
+ newEmail: 'Your new email address',
17
+ repeatNewEmail: 'Repeat your new email address'
18
+ },
19
+ validations: {
20
+ fieldRequired: 'Field is required.',
21
+ invalidEmail: 'A valid email address is required.',
22
+ emailsDoNotMatch: 'The email addresses do not match.'
23
+ },
24
+ changeEmail: 'Change your email address.',
25
+ emailChanged: 'Your email address has been changed.'
26
+ },
27
+ otp: {
28
+ fields: {
29
+ email: 'Email'
30
+ },
31
+ validations: {
32
+ fieldRequired: 'Field is required.',
33
+ invalidEmail: 'A valid email address is required.'
34
+ },
35
+ request: 'Request a one-time password',
36
+ checkEmail:
37
+ 'You will receive a verification code in your email. Please use this verification code in the next step.',
38
+ verificationCode: 'Verification code'
39
+ },
40
+ login: {
41
+ fields: {
42
+ email: 'Email',
43
+ password: 'Password',
44
+ username: 'Username'
45
+ },
46
+ validations: {
47
+ fieldRequired: 'Field is required.',
48
+ invalidEmail: 'A valid email address is required.'
49
+ },
50
+ login: 'Login',
51
+ loginWith: 'Login with',
52
+ createAccount: 'Create account',
53
+ forgotPassword: 'Forgot your password?',
54
+ invalidCredentials: 'Email address or password is incorrect.'
55
+ },
56
+ password: {
57
+ fields: {
58
+ password: 'Password',
59
+ repeatPassword: 'Repeat password'
60
+ },
61
+ validations: {
62
+ fieldRequired: 'Field is required',
63
+ minimumPasswordLength: (minimumPasswordLength) =>
64
+ `The minimum length of the password is ${minimumPasswordLength} characters.`,
65
+ passwordsDoNotMatch: 'The password do not match.'
66
+ },
67
+ changePassword: 'Change your password.',
68
+ passwordChanged: 'Your password has been changed.'
69
+ },
70
+ register: {
71
+ fields: {
72
+ email: 'Email',
73
+ password: 'Password',
74
+ username: 'Username',
75
+ repeatPassword: 'Repeat password'
76
+ },
77
+ validations: {
78
+ fieldRequired: 'Field is required',
79
+ invalidEmail: 'A valid email address is required.',
80
+ notAlphaNumeric: 'Veld mag geen speciale tekens bevatten.'
81
+ },
82
+ register: 'Register',
83
+ forgotPassword: 'Forgot your password?',
84
+ accountCreated:
85
+ 'Your account has been sucessfully created. You can now login with your credentials.',
86
+ alreadyRegistered: 'Email address is already registered.'
87
+ },
88
+ verification: {
89
+ slider:
90
+ 'Sleep a.u.b. de onderstaande balk helemaal naar rechts tot deze groen wordt.'
91
+ }
92
+ }
93
+
94
+ export default lang
@@ -0,0 +1,124 @@
1
+ export interface Language {
2
+ isoName: string
3
+ unprocessableRequest: string
4
+ myAccount: string
5
+ signOut: string
6
+ consent: {
7
+ message: (name: string) => string
8
+ deny: string
9
+ allow: string
10
+ }
11
+ email: {
12
+ fields: {
13
+ email: string
14
+ newEmail: string
15
+ repeatNewEmail: string
16
+ }
17
+ validations: {
18
+ fieldRequired: string
19
+ invalidEmail: string
20
+ emailsDoNotMatch: string
21
+ }
22
+ changeEmail: string
23
+ emailChanged: string
24
+ }
25
+ login: {
26
+ fields: {
27
+ email: string
28
+ password: string
29
+ username: string
30
+ }
31
+ validations: {
32
+ fieldRequired: string
33
+ invalidEmail: string
34
+ }
35
+ login: string
36
+ loginWith: string
37
+ forgotPassword: string
38
+ createAccount: string
39
+ invalidCredentials: string
40
+ }
41
+ otp: {
42
+ fields: {
43
+ email: string
44
+ }
45
+ validations: {
46
+ fieldRequired: string
47
+ invalidEmail: string
48
+ }
49
+ request: string
50
+ checkEmail: string
51
+ verificationCode: string
52
+ }
53
+ password: {
54
+ fields: {
55
+ password: string
56
+ repeatPassword: string
57
+ }
58
+ validations: {
59
+ fieldRequired: string
60
+ minimumPasswordLength: (minimumPasswordLength: number) => string
61
+ passwordsDoNotMatch: string
62
+ }
63
+ changePassword: string
64
+ passwordChanged: string
65
+ }
66
+ register: {
67
+ fields: {
68
+ email: string
69
+ password: string
70
+ repeatPassword: string
71
+ username: string
72
+ }
73
+ validations: {
74
+ fieldRequired: string
75
+ invalidEmail: string
76
+ notAlphaNumeric: string
77
+ }
78
+ register: string
79
+ forgotPassword: string
80
+ accountCreated: string
81
+ alreadyRegistered: string
82
+ }
83
+ verification: {
84
+ slider: string
85
+ }
86
+ }
87
+
88
+ import type { Ref } from 'vue'
89
+ import { ref } from 'vue'
90
+ import en from './en-US'
91
+ export const lang = ref(en)
92
+
93
+ const locales = import.meta.glob<{ default: Language }>([
94
+ './*.ts',
95
+ '!./index.ts'
96
+ ])
97
+
98
+ export const defineLang = (lang: Language) => {
99
+ return lang
100
+ }
101
+
102
+ export const useLang = () => {
103
+ return lang as Ref<Language>
104
+ }
105
+
106
+ let loadingLanguage = false
107
+ export const loadLang = async (isoName: string) => {
108
+ if (!loadingLanguage) {
109
+ loadingLanguage = true
110
+ try {
111
+ const data = (await locales[`./${isoName}.ts`]()).default
112
+
113
+ if (data) {
114
+ lang.value = data
115
+ }
116
+ } catch (e) {
117
+ if (import.meta.env.DEBUG) console.error(e)
118
+ throw new Error(
119
+ `[quasar-components] Failed to load ${isoName} language file.`
120
+ )
121
+ }
122
+ loadingLanguage = false
123
+ }
124
+ }