General.svelte 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. <script lang="ts">
  2. import {
  3. getCommunitySharingEnabledStatus,
  4. getWebhookUrl,
  5. toggleCommunitySharingEnabledStatus,
  6. updateWebhookUrl
  7. } from '$lib/apis';
  8. import {
  9. getDefaultUserRole,
  10. getJWTExpiresDuration,
  11. getSignUpEnabledStatus,
  12. toggleSignUpEnabledStatus,
  13. updateDefaultUserRole,
  14. updateJWTExpiresDuration
  15. } from '$lib/apis/auths';
  16. import { onMount, getContext } from 'svelte';
  17. const i18n = getContext('i18n');
  18. export let saveHandler: Function;
  19. let signUpEnabled = true;
  20. let defaultUserRole = 'pending';
  21. let JWTExpiresIn = '';
  22. let webhookUrl = '';
  23. let communitySharingEnabled = true;
  24. const toggleSignUpEnabled = async () => {
  25. signUpEnabled = await toggleSignUpEnabledStatus(localStorage.token);
  26. };
  27. const updateDefaultUserRoleHandler = async (role) => {
  28. defaultUserRole = await updateDefaultUserRole(localStorage.token, role);
  29. };
  30. const updateJWTExpiresDurationHandler = async (duration) => {
  31. JWTExpiresIn = await updateJWTExpiresDuration(localStorage.token, duration);
  32. };
  33. const updateWebhookUrlHandler = async () => {
  34. webhookUrl = await updateWebhookUrl(localStorage.token, webhookUrl);
  35. };
  36. const toggleCommunitySharingEnabled = async () => {
  37. communitySharingEnabled = await toggleCommunitySharingEnabledStatus(localStorage.token);
  38. };
  39. onMount(async () => {
  40. await Promise.all([
  41. (async () => {
  42. signUpEnabled = await getSignUpEnabledStatus(localStorage.token);
  43. })(),
  44. (async () => {
  45. defaultUserRole = await getDefaultUserRole(localStorage.token);
  46. })(),
  47. (async () => {
  48. JWTExpiresIn = await getJWTExpiresDuration(localStorage.token);
  49. })(),
  50. (async () => {
  51. webhookUrl = await getWebhookUrl(localStorage.token);
  52. })(),
  53. (async () => {
  54. communitySharingEnabled = await getCommunitySharingEnabledStatus(localStorage.token);
  55. })()
  56. ]);
  57. });
  58. </script>
  59. <form
  60. class="flex flex-col h-full justify-between space-y-3 text-sm"
  61. on:submit|preventDefault={() => {
  62. updateJWTExpiresDurationHandler(JWTExpiresIn);
  63. updateWebhookUrlHandler();
  64. saveHandler();
  65. }}
  66. >
  67. <div class=" space-y-3 pr-1.5 overflow-y-scroll max-h-80">
  68. <div>
  69. <div class=" mb-2 text-sm font-medium">{$i18n.t('General Settings')}</div>
  70. <div class=" flex w-full justify-between">
  71. <div class=" self-center text-xs font-medium">{$i18n.t('Enable New Sign Ups')}</div>
  72. <button
  73. class="p-1 px-3 text-xs flex rounded transition"
  74. on:click={() => {
  75. toggleSignUpEnabled();
  76. }}
  77. type="button"
  78. >
  79. {#if signUpEnabled}
  80. <svg
  81. xmlns="http://www.w3.org/2000/svg"
  82. viewBox="0 0 16 16"
  83. fill="currentColor"
  84. class="w-4 h-4"
  85. >
  86. <path
  87. d="M11.5 1A3.5 3.5 0 0 0 8 4.5V7H2.5A1.5 1.5 0 0 0 1 8.5v5A1.5 1.5 0 0 0 2.5 15h7a1.5 1.5 0 0 0 1.5-1.5v-5A1.5 1.5 0 0 0 9.5 7V4.5a2 2 0 1 1 4 0v1.75a.75.75 0 0 0 1.5 0V4.5A3.5 3.5 0 0 0 11.5 1Z"
  88. />
  89. </svg>
  90. <span class="ml-2 self-center">{$i18n.t('Enabled')}</span>
  91. {:else}
  92. <svg
  93. xmlns="http://www.w3.org/2000/svg"
  94. viewBox="0 0 16 16"
  95. fill="currentColor"
  96. class="w-4 h-4"
  97. >
  98. <path
  99. fill-rule="evenodd"
  100. d="M8 1a3.5 3.5 0 0 0-3.5 3.5V7A1.5 1.5 0 0 0 3 8.5v5A1.5 1.5 0 0 0 4.5 15h7a1.5 1.5 0 0 0 1.5-1.5v-5A1.5 1.5 0 0 0 11.5 7V4.5A3.5 3.5 0 0 0 8 1Zm2 6V4.5a2 2 0 1 0-4 0V7h4Z"
  101. clip-rule="evenodd"
  102. />
  103. </svg>
  104. <span class="ml-2 self-center">{$i18n.t('Disabled')}</span>
  105. {/if}
  106. </button>
  107. </div>
  108. <div class=" flex w-full justify-between">
  109. <div class=" self-center text-xs font-medium">{$i18n.t('Default User Role')}</div>
  110. <div class="flex items-center relative">
  111. <select
  112. class="dark:bg-gray-900 w-fit pr-8 rounded py-2 px-2 text-xs bg-transparent outline-none text-right"
  113. bind:value={defaultUserRole}
  114. placeholder="Select a theme"
  115. on:change={(e) => {
  116. updateDefaultUserRoleHandler(e.target.value);
  117. }}
  118. >
  119. <option value="pending">{$i18n.t('pending')}</option>
  120. <option value="user">{$i18n.t('user')}</option>
  121. <option value="admin">{$i18n.t('admin')}</option>
  122. </select>
  123. </div>
  124. </div>
  125. <div class=" flex w-full justify-between">
  126. <div class=" self-center text-xs font-medium">{$i18n.t('Enable Community Sharing')}</div>
  127. <button
  128. class="p-1 px-3 text-xs flex rounded transition"
  129. on:click={() => {
  130. toggleCommunitySharingEnabled();
  131. }}
  132. type="button"
  133. >
  134. {#if communitySharingEnabled}
  135. <svg
  136. xmlns="http://www.w3.org/2000/svg"
  137. viewBox="0 0 16 16"
  138. fill="currentColor"
  139. class="w-4 h-4"
  140. >
  141. <path
  142. d="M11.5 1A3.5 3.5 0 0 0 8 4.5V7H2.5A1.5 1.5 0 0 0 1 8.5v5A1.5 1.5 0 0 0 2.5 15h7a1.5 1.5 0 0 0 1.5-1.5v-5A1.5 1.5 0 0 0 9.5 7V4.5a2 2 0 1 1 4 0v1.75a.75.75 0 0 0 1.5 0V4.5A3.5 3.5 0 0 0 11.5 1Z"
  143. />
  144. </svg>
  145. <span class="ml-2 self-center">{$i18n.t('Enabled')}</span>
  146. {:else}
  147. <svg
  148. xmlns="http://www.w3.org/2000/svg"
  149. viewBox="0 0 16 16"
  150. fill="currentColor"
  151. class="w-4 h-4"
  152. >
  153. <path
  154. fill-rule="evenodd"
  155. d="M8 1a3.5 3.5 0 0 0-3.5 3.5V7A1.5 1.5 0 0 0 3 8.5v5A1.5 1.5 0 0 0 4.5 15h7a1.5 1.5 0 0 0 1.5-1.5v-5A1.5 1.5 0 0 0 11.5 7V4.5A3.5 3.5 0 0 0 8 1Zm2 6V4.5a2 2 0 1 0-4 0V7h4Z"
  156. clip-rule="evenodd"
  157. />
  158. </svg>
  159. <span class="ml-2 self-center">{$i18n.t('Disabled')}</span>
  160. {/if}
  161. </button>
  162. </div>
  163. <hr class=" dark:border-gray-700 my-3" />
  164. <div class=" w-full justify-between">
  165. <div class="flex w-full justify-between">
  166. <div class=" self-center text-xs font-medium">{$i18n.t('Webhook URL')}</div>
  167. </div>
  168. <div class="flex mt-2 space-x-2">
  169. <input
  170. class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
  171. type="text"
  172. placeholder={`https://example.com/webhook`}
  173. bind:value={webhookUrl}
  174. />
  175. </div>
  176. </div>
  177. <hr class=" dark:border-gray-700 my-3" />
  178. <div class=" w-full justify-between">
  179. <div class="flex w-full justify-between">
  180. <div class=" self-center text-xs font-medium">{$i18n.t('JWT Expiration')}</div>
  181. </div>
  182. <div class="flex mt-2 space-x-2">
  183. <input
  184. class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
  185. type="text"
  186. placeholder={`e.g.) "30m","1h", "10d". `}
  187. bind:value={JWTExpiresIn}
  188. />
  189. </div>
  190. <div class="mt-2 text-xs text-gray-400 dark:text-gray-500">
  191. {$i18n.t('Valid time units:')}
  192. <span class=" text-gray-300 font-medium"
  193. >{$i18n.t("'s', 'm', 'h', 'd', 'w' or '-1' for no expiration.")}</span
  194. >
  195. </div>
  196. </div>
  197. </div>
  198. </div>
  199. <div class="flex justify-end pt-3 text-sm font-medium">
  200. <button
  201. class=" px-4 py-2 bg-emerald-700 hover:bg-emerald-800 text-gray-100 transition rounded-lg"
  202. type="submit"
  203. >
  204. {$i18n.t('Save')}
  205. </button>
  206. </div>
  207. </form>