RateComment.svelte 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. <script lang="ts">
  2. import { toast } from 'svelte-sonner';
  3. import { createEventDispatcher, onMount, getContext } from 'svelte';
  4. const i18n = getContext('i18n');
  5. const dispatch = createEventDispatcher();
  6. export let messageId = null;
  7. export let show = false;
  8. export let message;
  9. let LIKE_REASONS = [];
  10. let DISLIKE_REASONS = [];
  11. function loadReasons() {
  12. LIKE_REASONS = [
  13. $i18n.t('Accurate information'),
  14. $i18n.t('Followed instructions perfectly'),
  15. $i18n.t('Showcased creativity'),
  16. $i18n.t('Positive attitude'),
  17. $i18n.t('Attention to detail'),
  18. $i18n.t('Thorough explanation'),
  19. $i18n.t('Other')
  20. ];
  21. DISLIKE_REASONS = [
  22. $i18n.t("Don't like the style"),
  23. $i18n.t('Not factually correct'),
  24. $i18n.t("Didn't fully follow instructions"),
  25. $i18n.t("Refused when it shouldn't have"),
  26. $i18n.t('Being lazy'),
  27. $i18n.t('Other')
  28. ];
  29. }
  30. let reasons = [];
  31. let selectedReason = null;
  32. let comment = '';
  33. $: if (message?.annotation?.rating === 1) {
  34. reasons = LIKE_REASONS;
  35. } else if (message?.annotation?.rating === -1) {
  36. reasons = DISLIKE_REASONS;
  37. }
  38. onMount(() => {
  39. selectedReason = message?.annotation?.reason ?? '';
  40. comment = message?.annotation?.comment ?? '';
  41. loadReasons();
  42. });
  43. const submitHandler = () => {
  44. console.log('submitHandler');
  45. message.annotation.reason = selectedReason;
  46. message.annotation.comment = comment;
  47. dispatch('submit', {
  48. reason: selectedReason,
  49. comment: comment
  50. });
  51. toast.success($i18n.t('Thanks for your feedback!'));
  52. show = false;
  53. };
  54. </script>
  55. <div
  56. class=" my-2.5 rounded-xl px-4 py-3 border dark:border-gray-850"
  57. id="message-feedback-{messageId}"
  58. >
  59. <div class="flex justify-between items-center">
  60. <div class=" text-sm">{$i18n.t('Tell us more:')}</div>
  61. <button
  62. on:click={() => {
  63. show = false;
  64. }}
  65. >
  66. <svg
  67. xmlns="http://www.w3.org/2000/svg"
  68. fill="none"
  69. viewBox="0 0 24 24"
  70. stroke-width="1.5"
  71. stroke="currentColor"
  72. class="size-4"
  73. >
  74. <path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" />
  75. </svg>
  76. </button>
  77. </div>
  78. {#if reasons.length > 0}
  79. <div class="flex flex-wrap gap-2 text-sm mt-2.5">
  80. {#each reasons as reason}
  81. <button
  82. class="px-3.5 py-1 border dark:border-gray-850 hover:bg-gray-100 dark:hover:bg-gray-850 {selectedReason ===
  83. reason
  84. ? 'bg-gray-200 dark:bg-gray-800'
  85. : ''} transition rounded-lg"
  86. on:click={() => {
  87. selectedReason = reason;
  88. }}
  89. >
  90. {reason}
  91. </button>
  92. {/each}
  93. </div>
  94. {/if}
  95. <div class="mt-2">
  96. <textarea
  97. bind:value={comment}
  98. class="w-full text-sm px-1 py-2 bg-transparent outline-none resize-none rounded-xl"
  99. placeholder={$i18n.t('Feel free to add specific details')}
  100. rows="2"
  101. />
  102. </div>
  103. <div class="mt-2 flex justify-end">
  104. <button
  105. class=" bg-emerald-700 text-white text-sm font-medium rounded-lg px-3.5 py-1.5"
  106. on:click={() => {
  107. submitHandler();
  108. }}
  109. >
  110. {$i18n.t('Submit')}
  111. </button>
  112. </div>
  113. </div>