RateComment.svelte 2.9 KB

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