en.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. import formatTimeToString from '../utils/formatTimeToString'
  2. const general = {
  3. timeFormats: {
  4. days: {
  5. 1: () => `day`,
  6. 2: () => `days`,
  7. },
  8. hours: {
  9. 1: () => `hour`,
  10. 2: () => `hours`,
  11. },
  12. minutes: {
  13. 1: () => `minute`,
  14. 2: () => `minutes`,
  15. },
  16. seconds: {
  17. 1: () => `second`,
  18. 2: () => `seconds`,
  19. },
  20. },
  21. dateFormats: {
  22. months: {
  23. [`01`]: () => `January`,
  24. [`02`]: () => `February`,
  25. [`03`]: () => `March`,
  26. [`04`]: () => `April`,
  27. [`05`]: () => `May`,
  28. [`06`]: () => `June`,
  29. [`07`]: () => `July`,
  30. [`08`]: () => `August`,
  31. [`09`]: () => `September`,
  32. [`10`]: () => `October`,
  33. [`11`]: () => `November`,
  34. [`12`]: () => `December`,
  35. }
  36. },
  37. functionWords: {
  38. and: () => `and`,
  39. },
  40. errors: {
  41. turnstile: {
  42. unavailable: () => `cannot connect to Turnstile. please try again.`,
  43. noToken: () => `Turnstile token was not provided. please try again.`,
  44. invalidResponse: () => `invalid Turnstile response. please try again.`,
  45. keyUsedOrExpired: () => `Turnstile key already used or expired. please try again.`
  46. },
  47. },
  48. }
  49. const icons = {
  50. tempIcon: () => `
  51. <svg class="icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
  52. <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 4v10.54a4 4 0 1 1-4 0V4a2 2 0 0 1 4 0" />
  53. </svg>
  54. `,
  55. pressureIcon: () => `
  56. <svg class="icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
  57. <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m12 14l4-4M3.34 19a10 10 0 1 1 17.32 0" />
  58. </svg>
  59. `,
  60. humidityIcon: () => `
  61. <svg class="icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
  62. <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 22a7 7 0 0 0 7-7c0-2-1-3.9-3-5.5s-3.5-4-4-6.5c-.5 2.5-2 4.9-4 6.5S5 13 5 15a7 7 0 0 0 7 7" />
  63. </svg>
  64. `,
  65. bluetoothConnectionIcon: () => `
  66. <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
  67. <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m7 7l10 10l-5 5V2l5 5L7 17m11-5h3M3 12h3" />
  68. </svg>
  69. `
  70. }
  71. export default {
  72. general,
  73. icons,
  74. emails: {
  75. auth: {
  76. subject: () => `login link`,
  77. text: (details) => `
  78. hi!
  79. you can login using the following code: ${details?.code}
  80. or the following link: ${details?.link}
  81. if you did not request this email, feel free to ignore it.
  82. ${process.env.APP_NAME}
  83. `,
  84. },
  85. },
  86. auth: {
  87. errors: {
  88. invalidEmail: () => `you need to provide a valid email.`,
  89. noVerificationToken: () => `verification token was not provided. please try again.`,
  90. verificationTokenUsedOrExpired: () => `verification token already used or expired. please try again.`,
  91. invalidVerificationCode: () => `invalid verification code. please try again.`,
  92. loginNeeded: () => `please log in first.`,
  93. ratelimits: {
  94. email: (details) => {
  95. if (!Number.parseInt(details?.duration)) return `too many requests for this email. try again later.`
  96. return `too many requests for this email. try again in ${formatTimeToString(general.timeFormats, general.functionWords.and(), details?.duration * 1000)}.`
  97. },
  98. ip: (details) => {
  99. if (!Number.parseInt(details?.duration)) return `you made too many requests. try again later.`
  100. return `you made too many requests. try again in ${formatTimeToString(general.timeFormats, general.functionWords.and(), details?.duration * 1000)}.`
  101. },
  102. code: () => `you entered too many wrong codes. you need to request a new verification.`,
  103. },
  104. turnstile: general.errors.turnstile,
  105. },
  106. },
  107. settings: {
  108. errors: {
  109. invalidEmail: () => `you need to provide a valid email.`,
  110. emailTaken: (details) => `a user with the provided email (${details?.newEmail}) already exists.`,
  111. turnstile: general.errors.turnstile,
  112. },
  113. },
  114. stations: {
  115. errors: {
  116. noName: () => `you need to provide a name.`,
  117. invalidOwner: () => `you need to provide a valid owner email.`,
  118. ownerUserNotFound: (details) => `a user with the provided email (${details?.newOwnerEmail}) does not exist.`,
  119. turnstile: general.errors.turnstile,
  120. },
  121. history: {
  122. properties: {
  123. indoorTemp: () => `${icons.tempIcon()} indoor temperature`,
  124. indoorPressure: () => `${icons.pressureIcon()} indoor pressure`,
  125. indoorHumidity: () => `${icons.humidityIcon()} indoor humidity`,
  126. outdoorConnected: () => `${icons.bluetoothConnectionIcon()} external unit connection`,
  127. outdoorTemp: () => `${icons.tempIcon()} outdoor temperature`,
  128. outdoorPressure: () => `${icons.pressureIcon()} outdoor pressure`,
  129. outdoorHumidity: () => `${icons.humidityIcon()} outdoor humidity`,
  130. },
  131. },
  132. },
  133. websocket: {
  134. keepalive: () => `free ferris`,
  135. dataSaved: (details) => `successfully saved data for ${details?.meteostanica?.name}`,
  136. errors: {
  137. missingFields: () => `missing required fields: indoorTemp, indoorPressure, indoorHumidity, indoorAltitude, outdoorConnected, outdoorTemp, outdoorPressure, outdoorHumidity, outdoorAltitude`,
  138. invalidKey: (details) => `invalid station websocket key (${details.key}) provided`,
  139. },
  140. }
  141. }