CreateStation.vue 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. <script setup lang="ts">
  2. import { defineAsyncComponent, ref } from "vue";
  3. import Toast from "toasters";
  4. import { useWebsocketsStore } from "@/stores/websockets";
  5. import { useModalsStore } from "@/stores/modals";
  6. import validation from "@/validation";
  7. const Modal = defineAsyncComponent(() => import("@/components/Modal.vue"));
  8. const props = defineProps({
  9. modalUuid: { type: String, required: true },
  10. official: { type: Boolean, default: false }
  11. });
  12. const { socket } = useWebsocketsStore();
  13. const { closeCurrentModal } = useModalsStore();
  14. const newStation = ref({
  15. name: "",
  16. displayName: "",
  17. description: ""
  18. });
  19. const submitModal = () => {
  20. newStation.value.name = newStation.value.name.toLowerCase();
  21. const { name, displayName, description } = newStation.value;
  22. if (!name || !displayName || !description)
  23. return new Toast("Please fill in all fields");
  24. if (!validation.isLength(name, 2, 16))
  25. return new Toast("Name must have between 2 and 16 characters.");
  26. if (!validation.regex.az09_.test(name))
  27. return new Toast(
  28. "Invalid name format. Allowed characters: a-z, 0-9 and _."
  29. );
  30. if (!validation.isLength(displayName, 2, 32))
  31. return new Toast("Display name must have between 2 and 32 characters.");
  32. if (!validation.regex.ascii.test(displayName))
  33. return new Toast(
  34. "Invalid display name format. Only ASCII characters are allowed."
  35. );
  36. if (!validation.isLength(description, 2, 200))
  37. return new Toast("Description must have between 2 and 200 characters.");
  38. let characters = description.split("");
  39. characters = characters.filter(
  40. character => character.charCodeAt(0) === 21328
  41. );
  42. if (characters.length !== 0)
  43. return new Toast("Invalid description format.");
  44. return socket.dispatch(
  45. "stations.create",
  46. {
  47. name,
  48. type: props.official ? "official" : "community",
  49. displayName,
  50. description
  51. },
  52. res => {
  53. if (res.status === "success") {
  54. new Toast(`You have added the station successfully`);
  55. closeCurrentModal();
  56. } else new Toast(res.message);
  57. }
  58. );
  59. };
  60. </script>
  61. <template>
  62. <modal
  63. :title="
  64. official ? 'Create Official Station' : 'Create Community Station'
  65. "
  66. >
  67. <template #body>
  68. <label class="label">Name (unique lowercase station id)</label>
  69. <p class="control">
  70. <input
  71. v-model="newStation.name"
  72. class="input station-id"
  73. type="text"
  74. placeholder="Name..."
  75. autofocus
  76. />
  77. </p>
  78. <label class="label">Display Name</label>
  79. <p class="control">
  80. <input
  81. v-model="newStation.displayName"
  82. class="input"
  83. type="text"
  84. placeholder="Display name..."
  85. />
  86. </p>
  87. <label class="label">Description</label>
  88. <p class="control">
  89. <input
  90. v-model="newStation.description"
  91. class="input"
  92. type="text"
  93. placeholder="Description..."
  94. @keyup.enter="submitModal()"
  95. />
  96. </p>
  97. </template>
  98. <template #footer>
  99. <a class="button is-primary" @click="submitModal()">Create</a>
  100. </template>
  101. </modal>
  102. </template>
  103. <style lang="less" scoped>
  104. .station-id {
  105. text-transform: lowercase;
  106. &::placeholder {
  107. text-transform: none;
  108. }
  109. }
  110. </style>