teraprox-ui-kit 0.1.0 → 0.1.1

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/dist/index.d.mts CHANGED
@@ -68,6 +68,36 @@ interface GenericDisplayProps {
68
68
  }
69
69
  declare const GenericDisplay: React.FC<GenericDisplayProps>;
70
70
 
71
+ interface MailSenderProps {
72
+ /** Conteúdo HTML a ser enviado no corpo do e-mail */
73
+ htmlContent: string;
74
+ /** Nome da empresa para o assunto/corpo padrão */
75
+ companyName: string;
76
+ /** Callback para buscar a lista de e-mails da companhia */
77
+ onFetchEmails: () => Promise<Array<{
78
+ email: string;
79
+ }>>;
80
+ /** Callback para enviar o e-mail consolidado */
81
+ onSendEmail: (emailData: {
82
+ to: string;
83
+ subject: string;
84
+ text: string;
85
+ html: string;
86
+ }) => Promise<void>;
87
+ /** Flag para ocultar o componente */
88
+ hide?: boolean;
89
+ /** Render prop opcional para o botão de ativação customizado */
90
+ renderTrigger?: (props: {
91
+ onClick: () => void;
92
+ loading: boolean;
93
+ }) => React.ReactNode;
94
+ }
95
+ /**
96
+ * Componente para seleção de destinatários e envio de e-mails.
97
+ * Refatorado para ser agnóstico a implementações de hooks/endpoints específicos das apps.
98
+ */
99
+ declare const MailSender: React.FC<MailSenderProps>;
100
+
71
101
  interface SelectOption {
72
102
  label: string;
73
103
  value: string | number;
@@ -131,4 +161,4 @@ declare class GenericSelectOps {
131
161
  }
132
162
  declare const GenericSelect: React.FC<GenericSelectProps>;
133
163
 
134
- export { AddButton, ConfigObject, DeleteButton, GenericDisplay, GenericForm, GenericSelect, GenericSelectOps, ResponsiveContainer, UuidPill };
164
+ export { AddButton, ConfigObject, DeleteButton, GenericDisplay, GenericForm, GenericSelect, GenericSelectOps, MailSender, type MailSenderProps, ResponsiveContainer, UuidPill };
package/dist/index.d.ts CHANGED
@@ -68,6 +68,36 @@ interface GenericDisplayProps {
68
68
  }
69
69
  declare const GenericDisplay: React.FC<GenericDisplayProps>;
70
70
 
71
+ interface MailSenderProps {
72
+ /** Conteúdo HTML a ser enviado no corpo do e-mail */
73
+ htmlContent: string;
74
+ /** Nome da empresa para o assunto/corpo padrão */
75
+ companyName: string;
76
+ /** Callback para buscar a lista de e-mails da companhia */
77
+ onFetchEmails: () => Promise<Array<{
78
+ email: string;
79
+ }>>;
80
+ /** Callback para enviar o e-mail consolidado */
81
+ onSendEmail: (emailData: {
82
+ to: string;
83
+ subject: string;
84
+ text: string;
85
+ html: string;
86
+ }) => Promise<void>;
87
+ /** Flag para ocultar o componente */
88
+ hide?: boolean;
89
+ /** Render prop opcional para o botão de ativação customizado */
90
+ renderTrigger?: (props: {
91
+ onClick: () => void;
92
+ loading: boolean;
93
+ }) => React.ReactNode;
94
+ }
95
+ /**
96
+ * Componente para seleção de destinatários e envio de e-mails.
97
+ * Refatorado para ser agnóstico a implementações de hooks/endpoints específicos das apps.
98
+ */
99
+ declare const MailSender: React.FC<MailSenderProps>;
100
+
71
101
  interface SelectOption {
72
102
  label: string;
73
103
  value: string | number;
@@ -131,4 +161,4 @@ declare class GenericSelectOps {
131
161
  }
132
162
  declare const GenericSelect: React.FC<GenericSelectProps>;
133
163
 
134
- export { AddButton, ConfigObject, DeleteButton, GenericDisplay, GenericForm, GenericSelect, GenericSelectOps, ResponsiveContainer, UuidPill };
164
+ export { AddButton, ConfigObject, DeleteButton, GenericDisplay, GenericForm, GenericSelect, GenericSelectOps, MailSender, type MailSenderProps, ResponsiveContainer, UuidPill };
package/dist/index.js CHANGED
@@ -37,6 +37,7 @@ __export(index_exports, {
37
37
  GenericForm: () => GenericForm_default,
38
38
  GenericSelect: () => GenericSelect_default,
39
39
  GenericSelectOps: () => GenericSelectOps,
40
+ MailSender: () => MailSender,
40
41
  ResponsiveContainer: () => ResponsiveContainer_default,
41
42
  UuidPill: () => UuidPill_default
42
43
  });
@@ -269,13 +270,373 @@ var GenericDisplay = ({
269
270
  };
270
271
  var GenericDisplay_default = GenericDisplay;
271
272
 
272
- // src/forms/GenericForm.tsx
273
+ // src/forms/MailSender.tsx
273
274
  var import_react3 = require("react");
274
275
  var import_react_bootstrap6 = require("react-bootstrap");
276
+ var import_fi = require("react-icons/fi");
275
277
  var import_jsx_runtime6 = require("react/jsx-runtime");
278
+ var MailSender = ({
279
+ htmlContent,
280
+ companyName,
281
+ onFetchEmails,
282
+ onSendEmail,
283
+ hide = false,
284
+ renderTrigger
285
+ }) => {
286
+ const [opened, setOpened] = (0, import_react3.useState)(false);
287
+ const [addingEmail, setAddingEmail] = (0, import_react3.useState)(false);
288
+ const [selectedEmails, setSelectedEmails] = (0, import_react3.useState)([]);
289
+ const [emails, setEmails] = (0, import_react3.useState)([]);
290
+ const [loading, setLoading] = (0, import_react3.useState)(false);
291
+ const [postLoading, setPostLoading] = (0, import_react3.useState)(false);
292
+ const [customEmail, setCustomEmail] = (0, import_react3.useState)("");
293
+ const [emailError, setEmailError] = (0, import_react3.useState)("");
294
+ const [searchFilter, setSearchFilter] = (0, import_react3.useState)("");
295
+ const handleOpen = async () => {
296
+ setLoading(true);
297
+ try {
298
+ const data = await onFetchEmails();
299
+ setEmails(data || []);
300
+ setOpened(true);
301
+ } catch (err) {
302
+ console.error("Erro ao buscar e-mails:", err);
303
+ } finally {
304
+ setLoading(false);
305
+ }
306
+ };
307
+ const mailListLinter = () => {
308
+ const result = [];
309
+ const seen = /* @__PURE__ */ new Set();
310
+ if (emails) {
311
+ for (const item of emails) {
312
+ if (item.email && !seen.has(item.email)) {
313
+ seen.add(item.email);
314
+ result.push({ email: item.email });
315
+ }
316
+ }
317
+ }
318
+ return result;
319
+ };
320
+ const filteredEmails = emails ? mailListLinter().filter(
321
+ (email) => email.email.toLowerCase().includes(searchFilter.toLowerCase()) && !selectedEmails.some((selected) => (selected.email || selected) === email.email)
322
+ ) : [];
323
+ const sendEmail = async () => {
324
+ const emailString = selectedEmails.map((email) => email.email ? email.email : email).join(", ");
325
+ const emailData = {
326
+ to: emailString,
327
+ subject: `Relat\xF3rio - ${companyName}`,
328
+ text: `Relat\xF3rio de processo da empresa ${companyName}`,
329
+ html: htmlContent
330
+ };
331
+ setPostLoading(true);
332
+ try {
333
+ await onSendEmail(emailData);
334
+ setSelectedEmails([]);
335
+ setCustomEmail("");
336
+ setOpened(false);
337
+ } catch (err) {
338
+ console.error("Erro ao enviar e-mail:", err);
339
+ } finally {
340
+ setPostLoading(false);
341
+ }
342
+ };
343
+ const validateEmail = (email) => {
344
+ const re = /\S+@\S+\.\S+/;
345
+ return re.test(email);
346
+ };
347
+ const handleEmailAdd = () => {
348
+ if (!customEmail.trim()) {
349
+ setEmailError("Por favor, digite um e-mail");
350
+ return;
351
+ }
352
+ if (!validateEmail(customEmail)) {
353
+ setEmailError("Formato de e-mail inv\xE1lido");
354
+ return;
355
+ }
356
+ if (selectedEmails.some((email) => (email.email || email) === customEmail)) {
357
+ setEmailError("Este e-mail j\xE1 foi selecionado");
358
+ return;
359
+ }
360
+ setSelectedEmails([...selectedEmails, customEmail]);
361
+ setCustomEmail("");
362
+ setEmailError("");
363
+ setAddingEmail(false);
364
+ };
365
+ const handleEmailRemove = (emailToRemove) => {
366
+ setSelectedEmails(
367
+ selectedEmails.filter(
368
+ (email) => (email.email || email) !== (emailToRemove.email || emailToRemove)
369
+ )
370
+ );
371
+ };
372
+ if (hide) return null;
373
+ if (!opened) {
374
+ if (renderTrigger) {
375
+ return renderTrigger({ onClick: handleOpen, loading });
376
+ }
377
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_bootstrap6.Button, { disabled: loading, className: "w-100", onClick: handleOpen, children: loading ? "Carregando..." : "Enviar por E-mail" });
378
+ }
379
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
380
+ "div",
381
+ {
382
+ style: {
383
+ backgroundColor: "#f8f9fa",
384
+ borderRadius: "12px",
385
+ overflow: "hidden",
386
+ border: "1px solid #dee2e6",
387
+ boxShadow: "0 4px 6px rgba(0, 0, 0, 0.1)"
388
+ },
389
+ children: [
390
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
391
+ "div",
392
+ {
393
+ style: {
394
+ background: "linear-gradient(135deg, #28a745 0%, #20c997 100%)",
395
+ color: "white",
396
+ padding: "25px"
397
+ },
398
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "d-flex justify-content-between align-items-center", children: [
399
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
400
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("h4", { className: "mb-1", style: { fontWeight: "600", fontSize: "22px" }, children: [
401
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_fi.FiMail, { className: "me-2", size: 20 }),
402
+ "Enviar Relat\xF3rio por E-mail"
403
+ ] }),
404
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("small", { style: { opacity: "0.9", fontSize: "14px" }, children: [
405
+ "Selecione os destinat\xE1rios para envio do relat\xF3rio de ",
406
+ companyName
407
+ ] })
408
+ ] }),
409
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "d-flex gap-2", children: [
410
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
411
+ import_react_bootstrap6.Button,
412
+ {
413
+ variant: "light",
414
+ onClick: sendEmail,
415
+ disabled: selectedEmails.length === 0 || postLoading,
416
+ style: {
417
+ borderRadius: "8px",
418
+ fontWeight: "600",
419
+ minWidth: "130px",
420
+ height: "40px"
421
+ },
422
+ children: postLoading ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
423
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_bootstrap6.Spinner, { size: "sm", className: "me-2" }),
424
+ "Enviando..."
425
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
426
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_fi.FiSend, { className: "me-2", size: 14 }),
427
+ "Enviar E-mail"
428
+ ] })
429
+ }
430
+ ),
431
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
432
+ import_react_bootstrap6.Button,
433
+ {
434
+ variant: "outline-light",
435
+ onClick: () => setOpened(false),
436
+ disabled: postLoading,
437
+ style: { borderRadius: "8px", width: "40px", height: "40px" },
438
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_fi.FiX, { size: 16 })
439
+ }
440
+ )
441
+ ] })
442
+ ] })
443
+ }
444
+ ),
445
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { padding: "25px" }, children: [
446
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_bootstrap6.Card, { className: "mb-4", style: { border: "none", boxShadow: "0 2px 8px rgba(0,0,0,0.05)" }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_bootstrap6.Card.Body, { style: { padding: "20px" }, children: [
447
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_bootstrap6.Row, { className: "align-items-center", children: [
448
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_bootstrap6.Col, { md: 6, children: [
449
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h6", { className: "mb-2", style: { color: "#495057", fontWeight: "600" }, children: "\u{1F527} Filtros e A\xE7\xF5es" }),
450
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_bootstrap6.InputGroup, { style: { maxWidth: "300px" }, children: [
451
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_bootstrap6.InputGroup.Text, { style: { backgroundColor: "#f8f9fa", border: "1px solid #dee2e6" }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_fi.FiSearch, { size: 14, color: "#6c757d" }) }),
452
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
453
+ import_react_bootstrap6.Form.Control,
454
+ {
455
+ type: "text",
456
+ placeholder: "Buscar e-mails...",
457
+ value: searchFilter,
458
+ onChange: (e) => setSearchFilter(e.target.value),
459
+ style: { border: "1px solid #dee2e6" }
460
+ }
461
+ )
462
+ ] })
463
+ ] }),
464
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_bootstrap6.Col, { md: 6, className: "text-end", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
465
+ import_react_bootstrap6.Button,
466
+ {
467
+ variant: addingEmail ? "outline-secondary" : "outline-primary",
468
+ size: "sm",
469
+ onClick: () => setAddingEmail(!addingEmail),
470
+ disabled: postLoading,
471
+ style: { borderRadius: "8px" },
472
+ children: addingEmail ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
473
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_fi.FiX, { className: "me-1", size: 14 }),
474
+ "Cancelar"
475
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
476
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_fi.FiPlus, { className: "me-1", size: 14 }),
477
+ "E-mail Personalizado"
478
+ ] })
479
+ }
480
+ ) })
481
+ ] }),
482
+ addingEmail && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
483
+ "div",
484
+ {
485
+ style: {
486
+ marginTop: "20px",
487
+ padding: "20px",
488
+ backgroundColor: "#f8f9ff",
489
+ borderRadius: "8px",
490
+ border: "1px solid #e3f2fd"
491
+ },
492
+ children: [
493
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h6", { className: "mb-3", style: { color: "#1976d2", fontWeight: "600" }, children: "\u2709\uFE0F Adicionar E-mail Personalizado" }),
494
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_bootstrap6.Row, { className: "align-items-end", children: [
495
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_bootstrap6.Col, { md: 8, children: [
496
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_bootstrap6.Form.Label, { style: { fontSize: "13px", color: "#6c757d", fontWeight: "500" }, children: "Endere\xE7o de E-mail" }),
497
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
498
+ import_react_bootstrap6.Form.Control,
499
+ {
500
+ type: "email",
501
+ placeholder: "exemplo@empresa.com",
502
+ value: customEmail,
503
+ onChange: (e) => {
504
+ setCustomEmail(e.target.value);
505
+ if (emailError) setEmailError("");
506
+ },
507
+ isInvalid: !!emailError,
508
+ disabled: postLoading,
509
+ style: { borderRadius: "8px" },
510
+ onKeyPress: (e) => e.key === "Enter" && handleEmailAdd()
511
+ }
512
+ ),
513
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_bootstrap6.Form.Control.Feedback, { type: "invalid", children: emailError })
514
+ ] }),
515
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_bootstrap6.Col, { md: 4, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
516
+ import_react_bootstrap6.Button,
517
+ {
518
+ variant: "success",
519
+ onClick: handleEmailAdd,
520
+ disabled: postLoading,
521
+ style: { borderRadius: "8px", width: "100%" },
522
+ children: [
523
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_fi.FiPlus, { className: "me-1", size: 14 }),
524
+ "Adicionar"
525
+ ]
526
+ }
527
+ ) })
528
+ ] })
529
+ ]
530
+ }
531
+ )
532
+ ] }) }),
533
+ selectedEmails.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_bootstrap6.Card, { className: "mb-4", style: { border: "none", boxShadow: "0 2px 8px rgba(0,0,0,0.05)" }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_bootstrap6.Card.Body, { style: { padding: "20px" }, children: [
534
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "d-flex justify-content-between align-items-center mb-3", children: [
535
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h6", { className: "mb-0", style: { color: "#495057", fontWeight: "600" }, children: "\u{1F4CB} Destinat\xE1rios Selecionados" }),
536
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_bootstrap6.Badge, { bg: "primary", style: { fontSize: "12px", padding: "6px 12px" }, children: [
537
+ selectedEmails.length,
538
+ " selecionado",
539
+ selectedEmails.length > 1 ? "s" : ""
540
+ ] })
541
+ ] }),
542
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "d-flex flex-wrap gap-2", children: selectedEmails.map((email, index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
543
+ "div",
544
+ {
545
+ style: {
546
+ background: "linear-gradient(135deg, #e3f2fd 0%, #f3e5f5 100%)",
547
+ border: "1px solid #bbdefb",
548
+ borderRadius: "20px",
549
+ padding: "8px 15px",
550
+ display: "flex",
551
+ alignItems: "center",
552
+ fontSize: "14px",
553
+ fontWeight: "500"
554
+ },
555
+ children: [
556
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_fi.FiUser, { size: 12, className: "me-2", color: "#1976d2" }),
557
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: email.email || email }),
558
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
559
+ import_react_bootstrap6.Button,
560
+ {
561
+ variant: "link",
562
+ size: "sm",
563
+ onClick: () => handleEmailRemove(email),
564
+ disabled: postLoading,
565
+ style: {
566
+ padding: "0 0 0 8px",
567
+ color: "#dc3545",
568
+ textDecoration: "none",
569
+ fontSize: "16px"
570
+ },
571
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_fi.FiX, { size: 14 })
572
+ }
573
+ )
574
+ ]
575
+ },
576
+ index
577
+ )) })
578
+ ] }) }),
579
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_bootstrap6.Card, { style: { border: "none", boxShadow: "0 2px 8px rgba(0,0,0,0.05)" }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_bootstrap6.Card.Body, { style: { padding: "20px" }, children: [
580
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("h6", { className: "mb-3", style: { color: "#495057", fontWeight: "600" }, children: [
581
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_fi.FiUser, { className: "me-2", size: 16 }),
582
+ "E-mails de ",
583
+ companyName
584
+ ] }),
585
+ loading ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "text-center py-4", children: [
586
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_bootstrap6.Spinner, {}),
587
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mt-2 text-muted", children: "Carregando e-mails..." })
588
+ ] }) : filteredEmails.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "text-center py-4", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-muted mb-0", children: searchFilter ? "Nenhum e-mail encontrado com esse filtro" : "Nenhum e-mail dispon\xEDvel" }) }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_bootstrap6.Row, { children: filteredEmails.map((email) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_bootstrap6.Col, { xs: 12, sm: 6, lg: 4, className: "mb-3", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
589
+ import_react_bootstrap6.Card,
590
+ {
591
+ onClick: () => setSelectedEmails([...selectedEmails, email]),
592
+ style: {
593
+ cursor: "pointer",
594
+ border: "1px solid #e9ecef",
595
+ borderRadius: "10px",
596
+ transition: "all 0.2s ease",
597
+ backgroundColor: "#fff"
598
+ },
599
+ onMouseEnter: (e) => {
600
+ e.currentTarget.style.transform = "translateY(-2px)";
601
+ e.currentTarget.style.boxShadow = "0 4px 12px rgba(0,0,0,0.1)";
602
+ e.currentTarget.style.borderColor = "#007bff";
603
+ },
604
+ onMouseLeave: (e) => {
605
+ e.currentTarget.style.transform = "translateY(0)";
606
+ e.currentTarget.style.boxShadow = "none";
607
+ e.currentTarget.style.borderColor = "#e9ecef";
608
+ },
609
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_bootstrap6.Card.Body, { style: { padding: "15px", textAlign: "center" }, children: [
610
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_fi.FiMail, { size: 20, color: "#007bff", className: "mb-2" }),
611
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
612
+ "div",
613
+ {
614
+ style: {
615
+ fontSize: "14px",
616
+ fontWeight: "500",
617
+ color: "#2c3e50",
618
+ wordBreak: "break-word"
619
+ },
620
+ children: email.email
621
+ }
622
+ )
623
+ ] })
624
+ }
625
+ ) }, email.email)) })
626
+ ] }) })
627
+ ] })
628
+ ]
629
+ }
630
+ );
631
+ };
632
+
633
+ // src/forms/GenericForm.tsx
634
+ var import_react4 = require("react");
635
+ var import_react_bootstrap7 = require("react-bootstrap");
636
+ var import_jsx_runtime7 = require("react/jsx-runtime");
276
637
  var GenericForm = ({ fields, onSubmit, renderCustomSelect }) => {
277
- const [formValues, setFormValues] = (0, import_react3.useState)({});
278
- const [errors, setErrors] = (0, import_react3.useState)({});
638
+ const [formValues, setFormValues] = (0, import_react4.useState)({});
639
+ const [errors, setErrors] = (0, import_react4.useState)({});
279
640
  const handleChange = (key, value) => {
280
641
  setFormValues({
281
642
  ...formValues,
@@ -304,10 +665,10 @@ var GenericForm = ({ fields, onSubmit, renderCustomSelect }) => {
304
665
  switch (type) {
305
666
  case "text":
306
667
  case "number":
307
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_bootstrap6.Form.Group, { className: "mb-3", children: [
308
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_bootstrap6.Form.Label, { children: label }),
309
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
310
- import_react_bootstrap6.Form.Control,
668
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_bootstrap7.Form.Group, { className: "mb-3", children: [
669
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_bootstrap7.Form.Label, { children: label }),
670
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
671
+ import_react_bootstrap7.Form.Control,
311
672
  {
312
673
  type,
313
674
  placeholder,
@@ -316,30 +677,30 @@ var GenericForm = ({ fields, onSubmit, renderCustomSelect }) => {
316
677
  isInvalid: !!errors[key]
317
678
  }
318
679
  ),
319
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_bootstrap6.Form.Control.Feedback, { type: "invalid", children: errors[key] })
680
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_bootstrap7.Form.Control.Feedback, { type: "invalid", children: errors[key] })
320
681
  ] }, key);
321
682
  case "select": {
322
683
  const orderedOptions = (options || []).filter((opt) => opt && opt.value !== void 0 && opt.label !== void 0).sort((a, b) => a.label.localeCompare(b.label));
323
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_bootstrap6.Form.Group, { className: "mb-3", children: [
324
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_bootstrap6.Form.Label, { children: label }),
325
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
326
- import_react_bootstrap6.Form.Select,
684
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_bootstrap7.Form.Group, { className: "mb-3", children: [
685
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_bootstrap7.Form.Label, { children: label }),
686
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
687
+ import_react_bootstrap7.Form.Select,
327
688
  {
328
689
  value,
329
690
  onChange: (e) => handleChange(key, e.target.value),
330
691
  isInvalid: !!errors[key],
331
692
  children: [
332
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: "", children: "Selecione..." }),
333
- orderedOptions.map((option) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: option.value, children: option.label }, String(option.value)))
693
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: "", children: "Selecione..." }),
694
+ orderedOptions.map((option) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: option.value, children: option.label }, String(option.value)))
334
695
  ]
335
696
  }
336
697
  ),
337
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_bootstrap6.Form.Control.Feedback, { type: "invalid", children: errors[key] })
698
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_bootstrap7.Form.Control.Feedback, { type: "invalid", children: errors[key] })
338
699
  ] }, key);
339
700
  }
340
701
  case "custom-select":
341
702
  if (renderCustomSelect) {
342
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
703
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { children: [
343
704
  renderCustomSelect({
344
705
  label,
345
706
  value,
@@ -347,15 +708,15 @@ var GenericForm = ({ fields, onSubmit, renderCustomSelect }) => {
347
708
  onChange: (v) => handleChange(key, v),
348
709
  placeholder
349
710
  }),
350
- errors[key] && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "invalid-feedback d-block", children: errors[key] })
711
+ errors[key] && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "invalid-feedback d-block", children: errors[key] })
351
712
  ] }, key);
352
713
  }
353
714
  return null;
354
715
  case "date":
355
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_bootstrap6.Form.Group, { className: "mb-3", children: [
356
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_bootstrap6.Form.Label, { children: label }),
357
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
358
- import_react_bootstrap6.Form.Control,
716
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_bootstrap7.Form.Group, { className: "mb-3", children: [
717
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_bootstrap7.Form.Label, { children: label }),
718
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
719
+ import_react_bootstrap7.Form.Control,
359
720
  {
360
721
  type: "date",
361
722
  value,
@@ -363,23 +724,23 @@ var GenericForm = ({ fields, onSubmit, renderCustomSelect }) => {
363
724
  isInvalid: !!errors[key]
364
725
  }
365
726
  ),
366
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_bootstrap6.Form.Control.Feedback, { type: "invalid", children: errors[key] })
727
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_bootstrap7.Form.Control.Feedback, { type: "invalid", children: errors[key] })
367
728
  ] }, key);
368
729
  default:
369
730
  return null;
370
731
  }
371
732
  };
372
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_bootstrap6.Form, { onSubmit: handleSubmit, children: [
733
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_bootstrap7.Form, { onSubmit: handleSubmit, children: [
373
734
  fields.map((field) => renderField(field)),
374
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "d-grid", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_bootstrap6.Button, { variant: "primary", type: "submit", children: "Salvar" }) })
735
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "d-grid", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_bootstrap7.Button, { variant: "primary", type: "submit", children: "Salvar" }) })
375
736
  ] });
376
737
  };
377
738
  var GenericForm_default = GenericForm;
378
739
 
379
740
  // src/forms/GenericSelect.tsx
380
- var import_react4 = require("react");
381
- var import_react_bootstrap7 = require("react-bootstrap");
382
- var import_jsx_runtime7 = require("react/jsx-runtime");
741
+ var import_react5 = require("react");
742
+ var import_react_bootstrap8 = require("react-bootstrap");
743
+ var import_jsx_runtime8 = require("react/jsx-runtime");
383
744
  var GenericSelectOps = class {
384
745
  constructor(noLabel, title, onChange, ops, selection, returnType, displayType, filter, filterField, valueType, loadFunc, loadCondition, actionClick, locked) {
385
746
  this.noLabel = noLabel;
@@ -416,8 +777,8 @@ var GenericSelect = ({
416
777
  isBold,
417
778
  ...restProps
418
779
  }) => {
419
- const [options, setOptions] = (0, import_react4.useState)(ops || []);
420
- (0, import_react4.useEffect)(() => {
780
+ const [options, setOptions] = (0, import_react5.useState)(ops || []);
781
+ (0, import_react5.useEffect)(() => {
421
782
  const loadFunction = async () => {
422
783
  if (loadCondition && loadFunc) {
423
784
  loadFunc().then((res) => {
@@ -442,15 +803,15 @@ var GenericSelect = ({
442
803
  }
443
804
  };
444
805
  const defaultPlaceholder = (restProps == null ? void 0 : restProps.default) || "Seleciona uma Op\xE7\xE3o";
445
- const selectContent = /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
446
- import_react_bootstrap7.Form.Control,
806
+ const selectContent = /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
807
+ import_react_bootstrap8.Form.Control,
447
808
  {
448
809
  disabled: locked,
449
810
  as: "select",
450
811
  value: selection,
451
812
  onChange: (event) => getTrueValue(event.target.selectedIndex),
452
813
  children: [
453
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("option", { value: void 0, children: [
814
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("option", { value: void 0, children: [
454
815
  "-- ",
455
816
  defaultPlaceholder,
456
817
  " --"
@@ -459,22 +820,22 @@ var GenericSelect = ({
459
820
  const val = valueType && op[valueType] || op.id || op;
460
821
  let fill = displayType && op[displayType] || op;
461
822
  if (typeof fill == "object") fill = "";
462
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: val, children: fill }, op.id || index);
823
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: val, children: fill }, op.id || index);
463
824
  })
464
825
  ]
465
826
  }
466
827
  );
467
828
  if (actionClick) {
468
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
469
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_bootstrap7.Form.Label, { style: { fontWeight: isBold ? "bold" : void 0 }, hidden: noLabel, children: title }),
470
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_bootstrap7.InputGroup, { children: [
829
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
830
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_bootstrap8.Form.Label, { style: { fontWeight: isBold ? "bold" : void 0 }, hidden: noLabel, children: title }),
831
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_bootstrap8.InputGroup, { children: [
471
832
  selectContent,
472
833
  actionClick()
473
834
  ] })
474
835
  ] });
475
836
  }
476
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
477
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_bootstrap7.Form.Label, { style: { fontWeight: isBold ? "bold" : void 0 }, hidden: noLabel, children: title }),
837
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
838
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_bootstrap8.Form.Label, { style: { fontWeight: isBold ? "bold" : void 0 }, hidden: noLabel, children: title }),
478
839
  selectContent
479
840
  ] });
480
841
  };
@@ -488,6 +849,7 @@ var GenericSelect_default = GenericSelect;
488
849
  GenericForm,
489
850
  GenericSelect,
490
851
  GenericSelectOps,
852
+ MailSender,
491
853
  ResponsiveContainer,
492
854
  UuidPill
493
855
  });
package/dist/index.mjs CHANGED
@@ -225,13 +225,382 @@ var GenericDisplay = ({
225
225
  };
226
226
  var GenericDisplay_default = GenericDisplay;
227
227
 
228
- // src/forms/GenericForm.tsx
228
+ // src/forms/MailSender.tsx
229
229
  import { useState as useState3 } from "react";
230
- import { Button as Button3, Form } from "react-bootstrap";
231
- import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
230
+ import {
231
+ Button as Button3,
232
+ Card,
233
+ Col as Col2,
234
+ Form,
235
+ Row as Row2,
236
+ Spinner,
237
+ Badge as Badge2,
238
+ InputGroup
239
+ } from "react-bootstrap";
240
+ import { FiMail, FiSearch, FiUser, FiX, FiPlus, FiSend } from "react-icons/fi";
241
+ import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
242
+ var MailSender = ({
243
+ htmlContent,
244
+ companyName,
245
+ onFetchEmails,
246
+ onSendEmail,
247
+ hide = false,
248
+ renderTrigger
249
+ }) => {
250
+ const [opened, setOpened] = useState3(false);
251
+ const [addingEmail, setAddingEmail] = useState3(false);
252
+ const [selectedEmails, setSelectedEmails] = useState3([]);
253
+ const [emails, setEmails] = useState3([]);
254
+ const [loading, setLoading] = useState3(false);
255
+ const [postLoading, setPostLoading] = useState3(false);
256
+ const [customEmail, setCustomEmail] = useState3("");
257
+ const [emailError, setEmailError] = useState3("");
258
+ const [searchFilter, setSearchFilter] = useState3("");
259
+ const handleOpen = async () => {
260
+ setLoading(true);
261
+ try {
262
+ const data = await onFetchEmails();
263
+ setEmails(data || []);
264
+ setOpened(true);
265
+ } catch (err) {
266
+ console.error("Erro ao buscar e-mails:", err);
267
+ } finally {
268
+ setLoading(false);
269
+ }
270
+ };
271
+ const mailListLinter = () => {
272
+ const result = [];
273
+ const seen = /* @__PURE__ */ new Set();
274
+ if (emails) {
275
+ for (const item of emails) {
276
+ if (item.email && !seen.has(item.email)) {
277
+ seen.add(item.email);
278
+ result.push({ email: item.email });
279
+ }
280
+ }
281
+ }
282
+ return result;
283
+ };
284
+ const filteredEmails = emails ? mailListLinter().filter(
285
+ (email) => email.email.toLowerCase().includes(searchFilter.toLowerCase()) && !selectedEmails.some((selected) => (selected.email || selected) === email.email)
286
+ ) : [];
287
+ const sendEmail = async () => {
288
+ const emailString = selectedEmails.map((email) => email.email ? email.email : email).join(", ");
289
+ const emailData = {
290
+ to: emailString,
291
+ subject: `Relat\xF3rio - ${companyName}`,
292
+ text: `Relat\xF3rio de processo da empresa ${companyName}`,
293
+ html: htmlContent
294
+ };
295
+ setPostLoading(true);
296
+ try {
297
+ await onSendEmail(emailData);
298
+ setSelectedEmails([]);
299
+ setCustomEmail("");
300
+ setOpened(false);
301
+ } catch (err) {
302
+ console.error("Erro ao enviar e-mail:", err);
303
+ } finally {
304
+ setPostLoading(false);
305
+ }
306
+ };
307
+ const validateEmail = (email) => {
308
+ const re = /\S+@\S+\.\S+/;
309
+ return re.test(email);
310
+ };
311
+ const handleEmailAdd = () => {
312
+ if (!customEmail.trim()) {
313
+ setEmailError("Por favor, digite um e-mail");
314
+ return;
315
+ }
316
+ if (!validateEmail(customEmail)) {
317
+ setEmailError("Formato de e-mail inv\xE1lido");
318
+ return;
319
+ }
320
+ if (selectedEmails.some((email) => (email.email || email) === customEmail)) {
321
+ setEmailError("Este e-mail j\xE1 foi selecionado");
322
+ return;
323
+ }
324
+ setSelectedEmails([...selectedEmails, customEmail]);
325
+ setCustomEmail("");
326
+ setEmailError("");
327
+ setAddingEmail(false);
328
+ };
329
+ const handleEmailRemove = (emailToRemove) => {
330
+ setSelectedEmails(
331
+ selectedEmails.filter(
332
+ (email) => (email.email || email) !== (emailToRemove.email || emailToRemove)
333
+ )
334
+ );
335
+ };
336
+ if (hide) return null;
337
+ if (!opened) {
338
+ if (renderTrigger) {
339
+ return renderTrigger({ onClick: handleOpen, loading });
340
+ }
341
+ return /* @__PURE__ */ jsx6(Button3, { disabled: loading, className: "w-100", onClick: handleOpen, children: loading ? "Carregando..." : "Enviar por E-mail" });
342
+ }
343
+ return /* @__PURE__ */ jsxs4(
344
+ "div",
345
+ {
346
+ style: {
347
+ backgroundColor: "#f8f9fa",
348
+ borderRadius: "12px",
349
+ overflow: "hidden",
350
+ border: "1px solid #dee2e6",
351
+ boxShadow: "0 4px 6px rgba(0, 0, 0, 0.1)"
352
+ },
353
+ children: [
354
+ /* @__PURE__ */ jsx6(
355
+ "div",
356
+ {
357
+ style: {
358
+ background: "linear-gradient(135deg, #28a745 0%, #20c997 100%)",
359
+ color: "white",
360
+ padding: "25px"
361
+ },
362
+ children: /* @__PURE__ */ jsxs4("div", { className: "d-flex justify-content-between align-items-center", children: [
363
+ /* @__PURE__ */ jsxs4("div", { children: [
364
+ /* @__PURE__ */ jsxs4("h4", { className: "mb-1", style: { fontWeight: "600", fontSize: "22px" }, children: [
365
+ /* @__PURE__ */ jsx6(FiMail, { className: "me-2", size: 20 }),
366
+ "Enviar Relat\xF3rio por E-mail"
367
+ ] }),
368
+ /* @__PURE__ */ jsxs4("small", { style: { opacity: "0.9", fontSize: "14px" }, children: [
369
+ "Selecione os destinat\xE1rios para envio do relat\xF3rio de ",
370
+ companyName
371
+ ] })
372
+ ] }),
373
+ /* @__PURE__ */ jsxs4("div", { className: "d-flex gap-2", children: [
374
+ /* @__PURE__ */ jsx6(
375
+ Button3,
376
+ {
377
+ variant: "light",
378
+ onClick: sendEmail,
379
+ disabled: selectedEmails.length === 0 || postLoading,
380
+ style: {
381
+ borderRadius: "8px",
382
+ fontWeight: "600",
383
+ minWidth: "130px",
384
+ height: "40px"
385
+ },
386
+ children: postLoading ? /* @__PURE__ */ jsxs4(Fragment3, { children: [
387
+ /* @__PURE__ */ jsx6(Spinner, { size: "sm", className: "me-2" }),
388
+ "Enviando..."
389
+ ] }) : /* @__PURE__ */ jsxs4(Fragment3, { children: [
390
+ /* @__PURE__ */ jsx6(FiSend, { className: "me-2", size: 14 }),
391
+ "Enviar E-mail"
392
+ ] })
393
+ }
394
+ ),
395
+ /* @__PURE__ */ jsx6(
396
+ Button3,
397
+ {
398
+ variant: "outline-light",
399
+ onClick: () => setOpened(false),
400
+ disabled: postLoading,
401
+ style: { borderRadius: "8px", width: "40px", height: "40px" },
402
+ children: /* @__PURE__ */ jsx6(FiX, { size: 16 })
403
+ }
404
+ )
405
+ ] })
406
+ ] })
407
+ }
408
+ ),
409
+ /* @__PURE__ */ jsxs4("div", { style: { padding: "25px" }, children: [
410
+ /* @__PURE__ */ jsx6(Card, { className: "mb-4", style: { border: "none", boxShadow: "0 2px 8px rgba(0,0,0,0.05)" }, children: /* @__PURE__ */ jsxs4(Card.Body, { style: { padding: "20px" }, children: [
411
+ /* @__PURE__ */ jsxs4(Row2, { className: "align-items-center", children: [
412
+ /* @__PURE__ */ jsxs4(Col2, { md: 6, children: [
413
+ /* @__PURE__ */ jsx6("h6", { className: "mb-2", style: { color: "#495057", fontWeight: "600" }, children: "\u{1F527} Filtros e A\xE7\xF5es" }),
414
+ /* @__PURE__ */ jsxs4(InputGroup, { style: { maxWidth: "300px" }, children: [
415
+ /* @__PURE__ */ jsx6(InputGroup.Text, { style: { backgroundColor: "#f8f9fa", border: "1px solid #dee2e6" }, children: /* @__PURE__ */ jsx6(FiSearch, { size: 14, color: "#6c757d" }) }),
416
+ /* @__PURE__ */ jsx6(
417
+ Form.Control,
418
+ {
419
+ type: "text",
420
+ placeholder: "Buscar e-mails...",
421
+ value: searchFilter,
422
+ onChange: (e) => setSearchFilter(e.target.value),
423
+ style: { border: "1px solid #dee2e6" }
424
+ }
425
+ )
426
+ ] })
427
+ ] }),
428
+ /* @__PURE__ */ jsx6(Col2, { md: 6, className: "text-end", children: /* @__PURE__ */ jsx6(
429
+ Button3,
430
+ {
431
+ variant: addingEmail ? "outline-secondary" : "outline-primary",
432
+ size: "sm",
433
+ onClick: () => setAddingEmail(!addingEmail),
434
+ disabled: postLoading,
435
+ style: { borderRadius: "8px" },
436
+ children: addingEmail ? /* @__PURE__ */ jsxs4(Fragment3, { children: [
437
+ /* @__PURE__ */ jsx6(FiX, { className: "me-1", size: 14 }),
438
+ "Cancelar"
439
+ ] }) : /* @__PURE__ */ jsxs4(Fragment3, { children: [
440
+ /* @__PURE__ */ jsx6(FiPlus, { className: "me-1", size: 14 }),
441
+ "E-mail Personalizado"
442
+ ] })
443
+ }
444
+ ) })
445
+ ] }),
446
+ addingEmail && /* @__PURE__ */ jsxs4(
447
+ "div",
448
+ {
449
+ style: {
450
+ marginTop: "20px",
451
+ padding: "20px",
452
+ backgroundColor: "#f8f9ff",
453
+ borderRadius: "8px",
454
+ border: "1px solid #e3f2fd"
455
+ },
456
+ children: [
457
+ /* @__PURE__ */ jsx6("h6", { className: "mb-3", style: { color: "#1976d2", fontWeight: "600" }, children: "\u2709\uFE0F Adicionar E-mail Personalizado" }),
458
+ /* @__PURE__ */ jsxs4(Row2, { className: "align-items-end", children: [
459
+ /* @__PURE__ */ jsxs4(Col2, { md: 8, children: [
460
+ /* @__PURE__ */ jsx6(Form.Label, { style: { fontSize: "13px", color: "#6c757d", fontWeight: "500" }, children: "Endere\xE7o de E-mail" }),
461
+ /* @__PURE__ */ jsx6(
462
+ Form.Control,
463
+ {
464
+ type: "email",
465
+ placeholder: "exemplo@empresa.com",
466
+ value: customEmail,
467
+ onChange: (e) => {
468
+ setCustomEmail(e.target.value);
469
+ if (emailError) setEmailError("");
470
+ },
471
+ isInvalid: !!emailError,
472
+ disabled: postLoading,
473
+ style: { borderRadius: "8px" },
474
+ onKeyPress: (e) => e.key === "Enter" && handleEmailAdd()
475
+ }
476
+ ),
477
+ /* @__PURE__ */ jsx6(Form.Control.Feedback, { type: "invalid", children: emailError })
478
+ ] }),
479
+ /* @__PURE__ */ jsx6(Col2, { md: 4, children: /* @__PURE__ */ jsxs4(
480
+ Button3,
481
+ {
482
+ variant: "success",
483
+ onClick: handleEmailAdd,
484
+ disabled: postLoading,
485
+ style: { borderRadius: "8px", width: "100%" },
486
+ children: [
487
+ /* @__PURE__ */ jsx6(FiPlus, { className: "me-1", size: 14 }),
488
+ "Adicionar"
489
+ ]
490
+ }
491
+ ) })
492
+ ] })
493
+ ]
494
+ }
495
+ )
496
+ ] }) }),
497
+ selectedEmails.length > 0 && /* @__PURE__ */ jsx6(Card, { className: "mb-4", style: { border: "none", boxShadow: "0 2px 8px rgba(0,0,0,0.05)" }, children: /* @__PURE__ */ jsxs4(Card.Body, { style: { padding: "20px" }, children: [
498
+ /* @__PURE__ */ jsxs4("div", { className: "d-flex justify-content-between align-items-center mb-3", children: [
499
+ /* @__PURE__ */ jsx6("h6", { className: "mb-0", style: { color: "#495057", fontWeight: "600" }, children: "\u{1F4CB} Destinat\xE1rios Selecionados" }),
500
+ /* @__PURE__ */ jsxs4(Badge2, { bg: "primary", style: { fontSize: "12px", padding: "6px 12px" }, children: [
501
+ selectedEmails.length,
502
+ " selecionado",
503
+ selectedEmails.length > 1 ? "s" : ""
504
+ ] })
505
+ ] }),
506
+ /* @__PURE__ */ jsx6("div", { className: "d-flex flex-wrap gap-2", children: selectedEmails.map((email, index) => /* @__PURE__ */ jsxs4(
507
+ "div",
508
+ {
509
+ style: {
510
+ background: "linear-gradient(135deg, #e3f2fd 0%, #f3e5f5 100%)",
511
+ border: "1px solid #bbdefb",
512
+ borderRadius: "20px",
513
+ padding: "8px 15px",
514
+ display: "flex",
515
+ alignItems: "center",
516
+ fontSize: "14px",
517
+ fontWeight: "500"
518
+ },
519
+ children: [
520
+ /* @__PURE__ */ jsx6(FiUser, { size: 12, className: "me-2", color: "#1976d2" }),
521
+ /* @__PURE__ */ jsx6("span", { children: email.email || email }),
522
+ /* @__PURE__ */ jsx6(
523
+ Button3,
524
+ {
525
+ variant: "link",
526
+ size: "sm",
527
+ onClick: () => handleEmailRemove(email),
528
+ disabled: postLoading,
529
+ style: {
530
+ padding: "0 0 0 8px",
531
+ color: "#dc3545",
532
+ textDecoration: "none",
533
+ fontSize: "16px"
534
+ },
535
+ children: /* @__PURE__ */ jsx6(FiX, { size: 14 })
536
+ }
537
+ )
538
+ ]
539
+ },
540
+ index
541
+ )) })
542
+ ] }) }),
543
+ /* @__PURE__ */ jsx6(Card, { style: { border: "none", boxShadow: "0 2px 8px rgba(0,0,0,0.05)" }, children: /* @__PURE__ */ jsxs4(Card.Body, { style: { padding: "20px" }, children: [
544
+ /* @__PURE__ */ jsxs4("h6", { className: "mb-3", style: { color: "#495057", fontWeight: "600" }, children: [
545
+ /* @__PURE__ */ jsx6(FiUser, { className: "me-2", size: 16 }),
546
+ "E-mails de ",
547
+ companyName
548
+ ] }),
549
+ loading ? /* @__PURE__ */ jsxs4("div", { className: "text-center py-4", children: [
550
+ /* @__PURE__ */ jsx6(Spinner, {}),
551
+ /* @__PURE__ */ jsx6("p", { className: "mt-2 text-muted", children: "Carregando e-mails..." })
552
+ ] }) : filteredEmails.length === 0 ? /* @__PURE__ */ jsx6("div", { className: "text-center py-4", children: /* @__PURE__ */ jsx6("p", { className: "text-muted mb-0", children: searchFilter ? "Nenhum e-mail encontrado com esse filtro" : "Nenhum e-mail dispon\xEDvel" }) }) : /* @__PURE__ */ jsx6(Row2, { children: filteredEmails.map((email) => /* @__PURE__ */ jsx6(Col2, { xs: 12, sm: 6, lg: 4, className: "mb-3", children: /* @__PURE__ */ jsx6(
553
+ Card,
554
+ {
555
+ onClick: () => setSelectedEmails([...selectedEmails, email]),
556
+ style: {
557
+ cursor: "pointer",
558
+ border: "1px solid #e9ecef",
559
+ borderRadius: "10px",
560
+ transition: "all 0.2s ease",
561
+ backgroundColor: "#fff"
562
+ },
563
+ onMouseEnter: (e) => {
564
+ e.currentTarget.style.transform = "translateY(-2px)";
565
+ e.currentTarget.style.boxShadow = "0 4px 12px rgba(0,0,0,0.1)";
566
+ e.currentTarget.style.borderColor = "#007bff";
567
+ },
568
+ onMouseLeave: (e) => {
569
+ e.currentTarget.style.transform = "translateY(0)";
570
+ e.currentTarget.style.boxShadow = "none";
571
+ e.currentTarget.style.borderColor = "#e9ecef";
572
+ },
573
+ children: /* @__PURE__ */ jsxs4(Card.Body, { style: { padding: "15px", textAlign: "center" }, children: [
574
+ /* @__PURE__ */ jsx6(FiMail, { size: 20, color: "#007bff", className: "mb-2" }),
575
+ /* @__PURE__ */ jsx6(
576
+ "div",
577
+ {
578
+ style: {
579
+ fontSize: "14px",
580
+ fontWeight: "500",
581
+ color: "#2c3e50",
582
+ wordBreak: "break-word"
583
+ },
584
+ children: email.email
585
+ }
586
+ )
587
+ ] })
588
+ }
589
+ ) }, email.email)) })
590
+ ] }) })
591
+ ] })
592
+ ]
593
+ }
594
+ );
595
+ };
596
+
597
+ // src/forms/GenericForm.tsx
598
+ import { useState as useState4 } from "react";
599
+ import { Button as Button4, Form as Form2 } from "react-bootstrap";
600
+ import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
232
601
  var GenericForm = ({ fields, onSubmit, renderCustomSelect }) => {
233
- const [formValues, setFormValues] = useState3({});
234
- const [errors, setErrors] = useState3({});
602
+ const [formValues, setFormValues] = useState4({});
603
+ const [errors, setErrors] = useState4({});
235
604
  const handleChange = (key, value) => {
236
605
  setFormValues({
237
606
  ...formValues,
@@ -260,10 +629,10 @@ var GenericForm = ({ fields, onSubmit, renderCustomSelect }) => {
260
629
  switch (type) {
261
630
  case "text":
262
631
  case "number":
263
- return /* @__PURE__ */ jsxs4(Form.Group, { className: "mb-3", children: [
264
- /* @__PURE__ */ jsx6(Form.Label, { children: label }),
265
- /* @__PURE__ */ jsx6(
266
- Form.Control,
632
+ return /* @__PURE__ */ jsxs5(Form2.Group, { className: "mb-3", children: [
633
+ /* @__PURE__ */ jsx7(Form2.Label, { children: label }),
634
+ /* @__PURE__ */ jsx7(
635
+ Form2.Control,
267
636
  {
268
637
  type,
269
638
  placeholder,
@@ -272,30 +641,30 @@ var GenericForm = ({ fields, onSubmit, renderCustomSelect }) => {
272
641
  isInvalid: !!errors[key]
273
642
  }
274
643
  ),
275
- /* @__PURE__ */ jsx6(Form.Control.Feedback, { type: "invalid", children: errors[key] })
644
+ /* @__PURE__ */ jsx7(Form2.Control.Feedback, { type: "invalid", children: errors[key] })
276
645
  ] }, key);
277
646
  case "select": {
278
647
  const orderedOptions = (options || []).filter((opt) => opt && opt.value !== void 0 && opt.label !== void 0).sort((a, b) => a.label.localeCompare(b.label));
279
- return /* @__PURE__ */ jsxs4(Form.Group, { className: "mb-3", children: [
280
- /* @__PURE__ */ jsx6(Form.Label, { children: label }),
281
- /* @__PURE__ */ jsxs4(
282
- Form.Select,
648
+ return /* @__PURE__ */ jsxs5(Form2.Group, { className: "mb-3", children: [
649
+ /* @__PURE__ */ jsx7(Form2.Label, { children: label }),
650
+ /* @__PURE__ */ jsxs5(
651
+ Form2.Select,
283
652
  {
284
653
  value,
285
654
  onChange: (e) => handleChange(key, e.target.value),
286
655
  isInvalid: !!errors[key],
287
656
  children: [
288
- /* @__PURE__ */ jsx6("option", { value: "", children: "Selecione..." }),
289
- orderedOptions.map((option) => /* @__PURE__ */ jsx6("option", { value: option.value, children: option.label }, String(option.value)))
657
+ /* @__PURE__ */ jsx7("option", { value: "", children: "Selecione..." }),
658
+ orderedOptions.map((option) => /* @__PURE__ */ jsx7("option", { value: option.value, children: option.label }, String(option.value)))
290
659
  ]
291
660
  }
292
661
  ),
293
- /* @__PURE__ */ jsx6(Form.Control.Feedback, { type: "invalid", children: errors[key] })
662
+ /* @__PURE__ */ jsx7(Form2.Control.Feedback, { type: "invalid", children: errors[key] })
294
663
  ] }, key);
295
664
  }
296
665
  case "custom-select":
297
666
  if (renderCustomSelect) {
298
- return /* @__PURE__ */ jsxs4("div", { children: [
667
+ return /* @__PURE__ */ jsxs5("div", { children: [
299
668
  renderCustomSelect({
300
669
  label,
301
670
  value,
@@ -303,15 +672,15 @@ var GenericForm = ({ fields, onSubmit, renderCustomSelect }) => {
303
672
  onChange: (v) => handleChange(key, v),
304
673
  placeholder
305
674
  }),
306
- errors[key] && /* @__PURE__ */ jsx6("div", { className: "invalid-feedback d-block", children: errors[key] })
675
+ errors[key] && /* @__PURE__ */ jsx7("div", { className: "invalid-feedback d-block", children: errors[key] })
307
676
  ] }, key);
308
677
  }
309
678
  return null;
310
679
  case "date":
311
- return /* @__PURE__ */ jsxs4(Form.Group, { className: "mb-3", children: [
312
- /* @__PURE__ */ jsx6(Form.Label, { children: label }),
313
- /* @__PURE__ */ jsx6(
314
- Form.Control,
680
+ return /* @__PURE__ */ jsxs5(Form2.Group, { className: "mb-3", children: [
681
+ /* @__PURE__ */ jsx7(Form2.Label, { children: label }),
682
+ /* @__PURE__ */ jsx7(
683
+ Form2.Control,
315
684
  {
316
685
  type: "date",
317
686
  value,
@@ -319,23 +688,23 @@ var GenericForm = ({ fields, onSubmit, renderCustomSelect }) => {
319
688
  isInvalid: !!errors[key]
320
689
  }
321
690
  ),
322
- /* @__PURE__ */ jsx6(Form.Control.Feedback, { type: "invalid", children: errors[key] })
691
+ /* @__PURE__ */ jsx7(Form2.Control.Feedback, { type: "invalid", children: errors[key] })
323
692
  ] }, key);
324
693
  default:
325
694
  return null;
326
695
  }
327
696
  };
328
- return /* @__PURE__ */ jsxs4(Form, { onSubmit: handleSubmit, children: [
697
+ return /* @__PURE__ */ jsxs5(Form2, { onSubmit: handleSubmit, children: [
329
698
  fields.map((field) => renderField(field)),
330
- /* @__PURE__ */ jsx6("div", { className: "d-grid", children: /* @__PURE__ */ jsx6(Button3, { variant: "primary", type: "submit", children: "Salvar" }) })
699
+ /* @__PURE__ */ jsx7("div", { className: "d-grid", children: /* @__PURE__ */ jsx7(Button4, { variant: "primary", type: "submit", children: "Salvar" }) })
331
700
  ] });
332
701
  };
333
702
  var GenericForm_default = GenericForm;
334
703
 
335
704
  // src/forms/GenericSelect.tsx
336
- import { useEffect as useEffect2, useState as useState4 } from "react";
337
- import { Form as Form2, InputGroup } from "react-bootstrap";
338
- import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
705
+ import { useEffect as useEffect2, useState as useState5 } from "react";
706
+ import { Form as Form3, InputGroup as InputGroup2 } from "react-bootstrap";
707
+ import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
339
708
  var GenericSelectOps = class {
340
709
  constructor(noLabel, title, onChange, ops, selection, returnType, displayType, filter, filterField, valueType, loadFunc, loadCondition, actionClick, locked) {
341
710
  this.noLabel = noLabel;
@@ -372,7 +741,7 @@ var GenericSelect = ({
372
741
  isBold,
373
742
  ...restProps
374
743
  }) => {
375
- const [options, setOptions] = useState4(ops || []);
744
+ const [options, setOptions] = useState5(ops || []);
376
745
  useEffect2(() => {
377
746
  const loadFunction = async () => {
378
747
  if (loadCondition && loadFunc) {
@@ -398,15 +767,15 @@ var GenericSelect = ({
398
767
  }
399
768
  };
400
769
  const defaultPlaceholder = (restProps == null ? void 0 : restProps.default) || "Seleciona uma Op\xE7\xE3o";
401
- const selectContent = /* @__PURE__ */ jsxs5(
402
- Form2.Control,
770
+ const selectContent = /* @__PURE__ */ jsxs6(
771
+ Form3.Control,
403
772
  {
404
773
  disabled: locked,
405
774
  as: "select",
406
775
  value: selection,
407
776
  onChange: (event) => getTrueValue(event.target.selectedIndex),
408
777
  children: [
409
- /* @__PURE__ */ jsxs5("option", { value: void 0, children: [
778
+ /* @__PURE__ */ jsxs6("option", { value: void 0, children: [
410
779
  "-- ",
411
780
  defaultPlaceholder,
412
781
  " --"
@@ -415,22 +784,22 @@ var GenericSelect = ({
415
784
  const val = valueType && op[valueType] || op.id || op;
416
785
  let fill = displayType && op[displayType] || op;
417
786
  if (typeof fill == "object") fill = "";
418
- return /* @__PURE__ */ jsx7("option", { value: val, children: fill }, op.id || index);
787
+ return /* @__PURE__ */ jsx8("option", { value: val, children: fill }, op.id || index);
419
788
  })
420
789
  ]
421
790
  }
422
791
  );
423
792
  if (actionClick) {
424
- return /* @__PURE__ */ jsxs5(Fragment3, { children: [
425
- /* @__PURE__ */ jsx7(Form2.Label, { style: { fontWeight: isBold ? "bold" : void 0 }, hidden: noLabel, children: title }),
426
- /* @__PURE__ */ jsxs5(InputGroup, { children: [
793
+ return /* @__PURE__ */ jsxs6(Fragment4, { children: [
794
+ /* @__PURE__ */ jsx8(Form3.Label, { style: { fontWeight: isBold ? "bold" : void 0 }, hidden: noLabel, children: title }),
795
+ /* @__PURE__ */ jsxs6(InputGroup2, { children: [
427
796
  selectContent,
428
797
  actionClick()
429
798
  ] })
430
799
  ] });
431
800
  }
432
- return /* @__PURE__ */ jsxs5(Fragment3, { children: [
433
- /* @__PURE__ */ jsx7(Form2.Label, { style: { fontWeight: isBold ? "bold" : void 0 }, hidden: noLabel, children: title }),
801
+ return /* @__PURE__ */ jsxs6(Fragment4, { children: [
802
+ /* @__PURE__ */ jsx8(Form3.Label, { style: { fontWeight: isBold ? "bold" : void 0 }, hidden: noLabel, children: title }),
434
803
  selectContent
435
804
  ] });
436
805
  };
@@ -443,6 +812,7 @@ export {
443
812
  GenericForm_default as GenericForm,
444
813
  GenericSelect_default as GenericSelect,
445
814
  GenericSelectOps,
815
+ MailSender,
446
816
  ResponsiveContainer_default as ResponsiveContainer,
447
817
  UuidPill_default as UuidPill
448
818
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "teraprox-ui-kit",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Componentes visuais compartilhados entre módulos federados TeraproX",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",