@asd20/ui-next 2.6.0 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ # [2.7.0](https://github.com/academydistrict20/asd20-ui-next/compare/ui-next-v2.6.0...ui-next-v2.7.0) (2026-05-05)
4
+
5
+
6
+ ### Features
7
+
8
+ * implement AI evaluation of email messages ([4ed90b4](https://github.com/academydistrict20/asd20-ui-next/commit/4ed90b413da2b2690b3655c1c701003cbdbb7bd6))
9
+
3
10
  # [2.6.0](https://github.com/academydistrict20/asd20-ui-next/compare/ui-next-v2.5.0...ui-next-v2.6.0) (2026-05-04)
4
11
 
5
12
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asd20/ui-next",
3
- "version": "2.6.0",
3
+ "version": "2.7.0",
4
4
  "private": false,
5
5
  "description": "ASD20 UI component library for Vue 3.",
6
6
  "license": "MIT",
@@ -9,59 +9,90 @@
9
9
  @dismiss="$emit('dismiss')"
10
10
  >
11
11
  <Asd20Viewport scrollable>
12
- <asd20-text-input
13
- id="senderName"
14
- v-model="emailMessage.senderName"
15
- label="Your Full Name"
16
- required
17
- @validated="validationErrors.senderName = $event"
18
- />
19
- <asd20-text-input
20
- id="senderEmail"
21
- v-model="emailMessage.senderEmail"
22
- type="email"
23
- :validator="validateEmailAddress"
24
- label="Your Email Address"
25
- required
26
- @validated="validationErrors.senderEmail = $event"
27
- />
28
- <asd20-text-area-input
29
- id="messageBody"
30
- v-model="emailMessage.messageBody"
31
- label="Message"
32
- required
33
- @validated="validationErrors.messageBody = $event"
34
- />
12
+ <template v-if="!sendRejected">
13
+ <asd20-text-input
14
+ id="senderName"
15
+ v-model="emailMessage.senderName"
16
+ label="Your Full Name"
17
+ required
18
+ @validated="validationErrors.senderName = $event"
19
+ />
20
+ <asd20-text-input
21
+ id="senderEmail"
22
+ v-model="emailMessage.senderEmail"
23
+ type="email"
24
+ :validator="validateEmailAddress"
25
+ label="Your Email Address"
26
+ required
27
+ @validated="validationErrors.senderEmail = $event"
28
+ />
29
+ <asd20-text-area-input
30
+ id="messageBody"
31
+ v-model="emailMessage.messageBody"
32
+ label="Message"
33
+ required
34
+ @validated="validationErrors.messageBody = $event"
35
+ />
36
+ <div
37
+ class="asd20-compose-email-modal__submit"
38
+ aria-live="polite"
39
+ >
40
+ <Recaptcha
41
+ v-if="!sending && !sendSucceeded"
42
+ sitekey="6LfidKoUAAAAAFqr3QEbia3jIkecsZyxBYlMvWrX"
43
+ :load-recaptcha-script="true"
44
+ size="invisible"
45
+ @verify="captchaVerified"
46
+ >
47
+ <asd20-button
48
+ :disabled="!isValid"
49
+ label="Send"
50
+ horizontal
51
+ centered
52
+ bordered
53
+ />
54
+ </Recaptcha>
55
+ <asd20-spinner
56
+ v-else-if="sending"
57
+ size="sm"
58
+ />
59
+ <p
60
+ v-else
61
+ class="asd20-compose-email-modal__success"
62
+ role="status"
63
+ >
64
+ Your message was sent.
65
+ </p>
66
+ </div>
67
+ </template>
35
68
  <div
36
- class="asd20-compose-email-modal__submit"
37
- aria-live="polite"
69
+ v-else
70
+ class="asd20-compose-email-modal__rejection"
71
+ role="status"
38
72
  >
39
- <Recaptcha
40
- v-if="!sending && !sendSucceeded"
41
- sitekey="6LfidKoUAAAAAFqr3QEbia3jIkecsZyxBYlMvWrX"
42
- :load-recaptcha-script="true"
43
- size="invisible"
44
- @verify="captchaVerified"
73
+ <p
74
+ class="asd20-compose-email-modal__rejection-message"
45
75
  >
76
+ Please contact the Academy District 20 Help Desk who can evaluate your
77
+ request and route it appropriately.
78
+ </p>
79
+ <div class="asd20-compose-email-modal__rejection-actions">
46
80
  <asd20-button
47
- :disabled="!isValid"
48
- label="Send"
81
+ label="Contact Our Help Desk"
82
+ :link="helpDeskUrl"
49
83
  horizontal
50
84
  centered
51
85
  bordered
52
86
  />
53
- </Recaptcha>
54
- <asd20-spinner
55
- v-else-if="sending"
56
- size="sm"
57
- />
58
- <p
59
- v-else
60
- class="asd20-compose-email-modal__success"
61
- role="status"
62
- >
63
- Your message was sent.
64
- </p>
87
+ <asd20-button
88
+ label="Cancel"
89
+ horizontal
90
+ centered
91
+ bordered
92
+ transparent
93
+ @click="$emit('dismiss')"
94
+ />
95
+ </div>
65
96
  </div>
66
97
  </Asd20Viewport>
67
98
  </asd20-modal>
@@ -101,6 +132,8 @@ export default {
101
132
  composing: false,
102
133
  sending: false,
103
134
  sendSucceeded: false,
135
+ sendRejected: false,
136
+ helpDeskUrl: 'https://asd20.org/help-desk',
104
137
  emailMessage: {
105
138
  senderName: '',
106
139
  senderEmail: '',
@@ -172,6 +205,7 @@ export default {
172
205
  resetSendState() {
173
206
  this.sending = false
174
207
  this.sendSucceeded = false
208
+ this.sendRejected = false
175
209
  },
176
210
  waitForSuccessMessage() {
177
211
  return new Promise(resolve => {
@@ -192,6 +226,9 @@ export default {
192
226
 
193
227
  return 'Something went wrong while sending your email. Please try again later.'
194
228
  },
229
+ isHelpDeskRejection(error) {
230
+ return error?.response?.data?.code === 'moderation_rejected'
231
+ },
195
232
  async sendEmail(captchaToken = '') {
196
233
  if (!this.isValid) return
197
234
 
@@ -224,6 +261,12 @@ export default {
224
261
  } catch (error) {
225
262
  this.sendSucceeded = false
226
263
  console.error('Email send failed:', error?.message || error)
264
+ if (this.isHelpDeskRejection(error)) {
265
+ this.helpDeskUrl =
266
+ error?.response?.data?.helpDeskUrl || 'https://asd20.org/help-desk'
267
+ this.sendRejected = true
268
+ return
269
+ }
227
270
  alert(this.getSendEmailFailureMessage(error))
228
271
  } finally {
229
272
  this.sending = false
@@ -253,6 +296,22 @@ export default {
253
296
  margin: 0;
254
297
  text-align: center;
255
298
  }
299
+
300
+ &__rejection {
301
+ display: flex;
302
+ flex-direction: column;
303
+ gap: space(1);
304
+ }
305
+
306
+ &__rejection-message {
307
+ margin: 0;
308
+ }
309
+
310
+ &__rejection-actions {
311
+ display: flex;
312
+ flex-wrap: wrap;
313
+ gap: space(0.75);
314
+ }
256
315
  }
257
316
 
258
317
  @media (min-width: 1024px) {