@greatapps/greatchat-ui 0.1.5 → 0.2.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/dist/index.d.ts +106 -5
- package/dist/index.js +1787 -1116
- package/dist/index.js.map +1 -1
- package/package.json +17 -13
- package/src/components/channel-card.tsx +1 -1
- package/src/components/channel-create-dialog.tsx +126 -0
- package/src/components/channel-edit-dialog.tsx +132 -0
- package/src/components/channels-page.tsx +242 -0
- package/src/components/chat-dashboard.tsx +433 -0
- package/src/components/chat-input.tsx +1 -2
- package/src/components/chat-view.tsx +1 -8
- package/src/components/contact-avatar.tsx +1 -2
- package/src/components/contact-form-dialog.tsx +139 -0
- package/src/components/contact-info-panel.tsx +1 -4
- package/src/components/contacts-page.tsx +41 -0
- package/src/components/contacts-table.tsx +216 -0
- package/src/components/data-table.tsx +185 -0
- package/src/components/inbox-item.tsx +6 -4
- package/src/components/inbox-page.tsx +167 -0
- package/src/components/inbox-sidebar.tsx +1 -5
- package/src/components/message-bubble.tsx +4 -6
- package/src/components/new-conversation-dialog.tsx +2 -6
- package/src/components/whatsapp-icon.tsx +21 -0
- package/src/components/whatsapp-qr-dialog.tsx +147 -0
- package/src/components/whatsapp-status-badge.tsx +1 -1
- package/src/index.ts +37 -2
- package/src/components/ui/alert-dialog.tsx +0 -167
- package/src/components/ui/avatar.tsx +0 -51
- package/src/components/ui/badge.tsx +0 -44
- package/src/components/ui/button.tsx +0 -62
- package/src/components/ui/command.tsx +0 -106
- package/src/components/ui/dialog.tsx +0 -133
- package/src/components/ui/dropdown-menu.tsx +0 -173
- package/src/components/ui/input.tsx +0 -19
- package/src/components/ui/scroll-area.tsx +0 -50
- package/src/components/ui/select.tsx +0 -156
- package/src/components/ui/separator.tsx +0 -26
- package/src/components/ui/skeleton.tsx +0 -16
- package/src/components/ui/tabs.tsx +0 -64
- package/src/components/ui/textarea.tsx +0 -18
- package/src/components/ui/tooltip.tsx +0 -58
- package/src/lib/utils.ts +0 -6
package/dist/index.js
CHANGED
|
@@ -95,12 +95,8 @@ function createGchatClient(config) {
|
|
|
95
95
|
};
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
// src/
|
|
99
|
-
import {
|
|
100
|
-
import { twMerge } from "tailwind-merge";
|
|
101
|
-
function cn(...inputs) {
|
|
102
|
-
return twMerge(clsx(inputs));
|
|
103
|
-
}
|
|
98
|
+
// src/index.ts
|
|
99
|
+
import { cn as cn7 } from "@greatapps/greatauth-ui/ui";
|
|
104
100
|
|
|
105
101
|
// src/utils/group-messages.ts
|
|
106
102
|
function groupMessagesByDate(messages) {
|
|
@@ -698,7 +694,7 @@ import { useRef as useRef2, useEffect } from "react";
|
|
|
698
694
|
// src/components/message-bubble.tsx
|
|
699
695
|
import { useState } from "react";
|
|
700
696
|
import {
|
|
701
|
-
Check
|
|
697
|
+
Check,
|
|
702
698
|
CheckCheck,
|
|
703
699
|
AlertCircle,
|
|
704
700
|
Clock,
|
|
@@ -712,279 +708,30 @@ import {
|
|
|
712
708
|
Pencil,
|
|
713
709
|
Ban
|
|
714
710
|
} from "lucide-react";
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
711
|
+
import {
|
|
712
|
+
cn,
|
|
713
|
+
DropdownMenu,
|
|
714
|
+
DropdownMenuContent,
|
|
715
|
+
DropdownMenuItem,
|
|
716
|
+
DropdownMenuTrigger,
|
|
717
|
+
AlertDialog,
|
|
718
|
+
AlertDialogAction,
|
|
719
|
+
AlertDialogCancel,
|
|
720
|
+
AlertDialogContent,
|
|
721
|
+
AlertDialogDescription,
|
|
722
|
+
AlertDialogFooter,
|
|
723
|
+
AlertDialogHeader,
|
|
724
|
+
AlertDialogTitle,
|
|
725
|
+
Button,
|
|
726
|
+
Textarea
|
|
727
|
+
} from "@greatapps/greatauth-ui/ui";
|
|
719
728
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
720
|
-
function DropdownMenu({
|
|
721
|
-
...props
|
|
722
|
-
}) {
|
|
723
|
-
return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
|
|
724
|
-
}
|
|
725
|
-
function DropdownMenuTrigger({
|
|
726
|
-
...props
|
|
727
|
-
}) {
|
|
728
|
-
return /* @__PURE__ */ jsx(
|
|
729
|
-
DropdownMenuPrimitive.Trigger,
|
|
730
|
-
{
|
|
731
|
-
"data-slot": "dropdown-menu-trigger",
|
|
732
|
-
...props
|
|
733
|
-
}
|
|
734
|
-
);
|
|
735
|
-
}
|
|
736
|
-
function DropdownMenuContent({
|
|
737
|
-
className,
|
|
738
|
-
align = "start",
|
|
739
|
-
sideOffset = 4,
|
|
740
|
-
...props
|
|
741
|
-
}) {
|
|
742
|
-
return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
|
|
743
|
-
DropdownMenuPrimitive.Content,
|
|
744
|
-
{
|
|
745
|
-
"data-slot": "dropdown-menu-content",
|
|
746
|
-
sideOffset,
|
|
747
|
-
align,
|
|
748
|
-
className: cn(
|
|
749
|
-
"data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 bg-popover text-popover-foreground min-w-32 rounded-md p-1 shadow-md ring-1 duration-100 z-50 overflow-x-hidden overflow-y-auto",
|
|
750
|
-
className
|
|
751
|
-
),
|
|
752
|
-
...props
|
|
753
|
-
}
|
|
754
|
-
) });
|
|
755
|
-
}
|
|
756
|
-
function DropdownMenuItem({
|
|
757
|
-
className,
|
|
758
|
-
inset,
|
|
759
|
-
variant = "default",
|
|
760
|
-
...props
|
|
761
|
-
}) {
|
|
762
|
-
return /* @__PURE__ */ jsx(
|
|
763
|
-
DropdownMenuPrimitive.Item,
|
|
764
|
-
{
|
|
765
|
-
"data-slot": "dropdown-menu-item",
|
|
766
|
-
"data-inset": inset,
|
|
767
|
-
"data-variant": variant,
|
|
768
|
-
className: cn(
|
|
769
|
-
"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive gap-2 rounded-sm px-2 py-1.5 text-sm data-inset:pl-8 [&_svg:not([class*='size-'])]:size-4 relative flex cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
770
|
-
className
|
|
771
|
-
),
|
|
772
|
-
...props
|
|
773
|
-
}
|
|
774
|
-
);
|
|
775
|
-
}
|
|
776
|
-
|
|
777
|
-
// src/components/ui/alert-dialog.tsx
|
|
778
|
-
import { AlertDialog as AlertDialogPrimitive } from "radix-ui";
|
|
779
|
-
|
|
780
|
-
// src/components/ui/button.tsx
|
|
781
|
-
import { cva } from "class-variance-authority";
|
|
782
|
-
import { Slot } from "radix-ui";
|
|
783
|
-
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
784
|
-
var buttonVariants = cva(
|
|
785
|
-
"focus-visible:border-ring focus-visible:ring-ring/50 rounded-md border border-transparent text-sm font-medium focus-visible:ring-3 [&_svg:not([class*='size-'])]:size-4 inline-flex items-center justify-center whitespace-nowrap transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none shrink-0 [&_svg]:shrink-0 outline-none select-none",
|
|
786
|
-
{
|
|
787
|
-
variants: {
|
|
788
|
-
variant: {
|
|
789
|
-
default: "bg-primary text-primary-foreground hover:bg-primary/80",
|
|
790
|
-
outline: "border-border bg-background hover:bg-muted hover:text-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 shadow-xs",
|
|
791
|
-
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
792
|
-
ghost: "hover:bg-muted hover:text-foreground dark:hover:bg-muted/50",
|
|
793
|
-
destructive: "bg-destructive/10 hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:bg-destructive/20 text-destructive",
|
|
794
|
-
link: "text-primary underline-offset-4 hover:underline"
|
|
795
|
-
},
|
|
796
|
-
size: {
|
|
797
|
-
default: "h-9 gap-1.5 px-2.5",
|
|
798
|
-
xs: "h-6 gap-1 px-2 text-xs [&_svg:not([class*='size-'])]:size-3",
|
|
799
|
-
sm: "h-8 gap-1 px-2.5",
|
|
800
|
-
lg: "h-10 gap-1.5 px-2.5",
|
|
801
|
-
icon: "size-9",
|
|
802
|
-
"icon-xs": "size-6 [&_svg:not([class*='size-'])]:size-3",
|
|
803
|
-
"icon-sm": "size-8",
|
|
804
|
-
"icon-lg": "size-10"
|
|
805
|
-
}
|
|
806
|
-
},
|
|
807
|
-
defaultVariants: {
|
|
808
|
-
variant: "default",
|
|
809
|
-
size: "default"
|
|
810
|
-
}
|
|
811
|
-
}
|
|
812
|
-
);
|
|
813
|
-
function Button({
|
|
814
|
-
className,
|
|
815
|
-
variant = "default",
|
|
816
|
-
size = "default",
|
|
817
|
-
asChild = false,
|
|
818
|
-
...props
|
|
819
|
-
}) {
|
|
820
|
-
const Comp = asChild ? Slot.Root : "button";
|
|
821
|
-
return /* @__PURE__ */ jsx2(
|
|
822
|
-
Comp,
|
|
823
|
-
{
|
|
824
|
-
"data-slot": "button",
|
|
825
|
-
className: cn(buttonVariants({ variant, size, className })),
|
|
826
|
-
...props
|
|
827
|
-
}
|
|
828
|
-
);
|
|
829
|
-
}
|
|
830
|
-
|
|
831
|
-
// src/components/ui/alert-dialog.tsx
|
|
832
|
-
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
833
|
-
function AlertDialog({
|
|
834
|
-
...props
|
|
835
|
-
}) {
|
|
836
|
-
return /* @__PURE__ */ jsx3(AlertDialogPrimitive.Root, { "data-slot": "alert-dialog", ...props });
|
|
837
|
-
}
|
|
838
|
-
function AlertDialogPortal({
|
|
839
|
-
...props
|
|
840
|
-
}) {
|
|
841
|
-
return /* @__PURE__ */ jsx3(AlertDialogPrimitive.Portal, { "data-slot": "alert-dialog-portal", ...props });
|
|
842
|
-
}
|
|
843
|
-
function AlertDialogOverlay({
|
|
844
|
-
className,
|
|
845
|
-
...props
|
|
846
|
-
}) {
|
|
847
|
-
return /* @__PURE__ */ jsx3(
|
|
848
|
-
AlertDialogPrimitive.Overlay,
|
|
849
|
-
{
|
|
850
|
-
"data-slot": "alert-dialog-overlay",
|
|
851
|
-
className: cn(
|
|
852
|
-
"data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs fixed inset-0 z-50",
|
|
853
|
-
className
|
|
854
|
-
),
|
|
855
|
-
...props
|
|
856
|
-
}
|
|
857
|
-
);
|
|
858
|
-
}
|
|
859
|
-
function AlertDialogContent({
|
|
860
|
-
className,
|
|
861
|
-
...props
|
|
862
|
-
}) {
|
|
863
|
-
return /* @__PURE__ */ jsxs2(AlertDialogPortal, { children: [
|
|
864
|
-
/* @__PURE__ */ jsx3(AlertDialogOverlay, {}),
|
|
865
|
-
/* @__PURE__ */ jsx3(
|
|
866
|
-
AlertDialogPrimitive.Content,
|
|
867
|
-
{
|
|
868
|
-
"data-slot": "alert-dialog-content",
|
|
869
|
-
className: cn(
|
|
870
|
-
"data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 bg-background ring-foreground/10 gap-6 rounded-xl p-6 ring-1 duration-100 sm:max-w-lg fixed top-1/2 left-1/2 z-50 grid w-full max-w-xs -translate-x-1/2 -translate-y-1/2 outline-none",
|
|
871
|
-
className
|
|
872
|
-
),
|
|
873
|
-
...props
|
|
874
|
-
}
|
|
875
|
-
)
|
|
876
|
-
] });
|
|
877
|
-
}
|
|
878
|
-
function AlertDialogHeader({
|
|
879
|
-
className,
|
|
880
|
-
...props
|
|
881
|
-
}) {
|
|
882
|
-
return /* @__PURE__ */ jsx3(
|
|
883
|
-
"div",
|
|
884
|
-
{
|
|
885
|
-
"data-slot": "alert-dialog-header",
|
|
886
|
-
className: cn("grid gap-1.5 text-center sm:text-left", className),
|
|
887
|
-
...props
|
|
888
|
-
}
|
|
889
|
-
);
|
|
890
|
-
}
|
|
891
|
-
function AlertDialogFooter({
|
|
892
|
-
className,
|
|
893
|
-
...props
|
|
894
|
-
}) {
|
|
895
|
-
return /* @__PURE__ */ jsx3(
|
|
896
|
-
"div",
|
|
897
|
-
{
|
|
898
|
-
"data-slot": "alert-dialog-footer",
|
|
899
|
-
className: cn(
|
|
900
|
-
"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
|
|
901
|
-
className
|
|
902
|
-
),
|
|
903
|
-
...props
|
|
904
|
-
}
|
|
905
|
-
);
|
|
906
|
-
}
|
|
907
|
-
function AlertDialogTitle({
|
|
908
|
-
className,
|
|
909
|
-
...props
|
|
910
|
-
}) {
|
|
911
|
-
return /* @__PURE__ */ jsx3(
|
|
912
|
-
AlertDialogPrimitive.Title,
|
|
913
|
-
{
|
|
914
|
-
"data-slot": "alert-dialog-title",
|
|
915
|
-
className: cn("text-lg font-medium", className),
|
|
916
|
-
...props
|
|
917
|
-
}
|
|
918
|
-
);
|
|
919
|
-
}
|
|
920
|
-
function AlertDialogDescription({
|
|
921
|
-
className,
|
|
922
|
-
...props
|
|
923
|
-
}) {
|
|
924
|
-
return /* @__PURE__ */ jsx3(
|
|
925
|
-
AlertDialogPrimitive.Description,
|
|
926
|
-
{
|
|
927
|
-
"data-slot": "alert-dialog-description",
|
|
928
|
-
className: cn("text-muted-foreground text-sm", className),
|
|
929
|
-
...props
|
|
930
|
-
}
|
|
931
|
-
);
|
|
932
|
-
}
|
|
933
|
-
function AlertDialogAction({
|
|
934
|
-
className,
|
|
935
|
-
variant = "default",
|
|
936
|
-
size = "default",
|
|
937
|
-
...props
|
|
938
|
-
}) {
|
|
939
|
-
return /* @__PURE__ */ jsx3(Button, { variant, size, asChild: true, children: /* @__PURE__ */ jsx3(
|
|
940
|
-
AlertDialogPrimitive.Action,
|
|
941
|
-
{
|
|
942
|
-
"data-slot": "alert-dialog-action",
|
|
943
|
-
className: cn(className),
|
|
944
|
-
...props
|
|
945
|
-
}
|
|
946
|
-
) });
|
|
947
|
-
}
|
|
948
|
-
function AlertDialogCancel({
|
|
949
|
-
className,
|
|
950
|
-
variant = "outline",
|
|
951
|
-
size = "default",
|
|
952
|
-
...props
|
|
953
|
-
}) {
|
|
954
|
-
return /* @__PURE__ */ jsx3(Button, { variant, size, asChild: true, children: /* @__PURE__ */ jsx3(
|
|
955
|
-
AlertDialogPrimitive.Cancel,
|
|
956
|
-
{
|
|
957
|
-
"data-slot": "alert-dialog-cancel",
|
|
958
|
-
className: cn(className),
|
|
959
|
-
...props
|
|
960
|
-
}
|
|
961
|
-
) });
|
|
962
|
-
}
|
|
963
|
-
|
|
964
|
-
// src/components/ui/textarea.tsx
|
|
965
|
-
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
966
|
-
function Textarea({ className, ...props }) {
|
|
967
|
-
return /* @__PURE__ */ jsx4(
|
|
968
|
-
"textarea",
|
|
969
|
-
{
|
|
970
|
-
"data-slot": "textarea",
|
|
971
|
-
className: cn(
|
|
972
|
-
"border-input dark:bg-input/30 focus-visible:border-ring focus-visible:ring-ring/50 rounded-md border bg-transparent px-2.5 py-2 text-base shadow-xs transition-[color,box-shadow] focus-visible:ring-3 md:text-sm placeholder:text-muted-foreground flex field-sizing-content min-h-16 w-full outline-none disabled:cursor-not-allowed disabled:opacity-50",
|
|
973
|
-
className
|
|
974
|
-
),
|
|
975
|
-
...props
|
|
976
|
-
}
|
|
977
|
-
);
|
|
978
|
-
}
|
|
979
|
-
|
|
980
|
-
// src/components/message-bubble.tsx
|
|
981
|
-
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
982
729
|
var statusIcons = {
|
|
983
|
-
pending: /* @__PURE__ */
|
|
984
|
-
sent: /* @__PURE__ */
|
|
985
|
-
delivered: /* @__PURE__ */
|
|
986
|
-
read: /* @__PURE__ */
|
|
987
|
-
failed: /* @__PURE__ */
|
|
730
|
+
pending: /* @__PURE__ */ jsx(Clock, { className: "h-3 w-3 animate-pulse" }),
|
|
731
|
+
sent: /* @__PURE__ */ jsx(Check, { className: "h-3 w-3" }),
|
|
732
|
+
delivered: /* @__PURE__ */ jsx(CheckCheck, { className: "h-3 w-3" }),
|
|
733
|
+
read: /* @__PURE__ */ jsx(CheckCheck, { className: "h-3 w-3 text-blue-500" }),
|
|
734
|
+
failed: /* @__PURE__ */ jsx(AlertCircle, { className: "h-3 w-3 text-destructive" })
|
|
988
735
|
};
|
|
989
736
|
function parseMetadata(metadata) {
|
|
990
737
|
if (!metadata) return {};
|
|
@@ -997,8 +744,8 @@ function parseMetadata(metadata) {
|
|
|
997
744
|
function MediaContent({ message }) {
|
|
998
745
|
switch (message.content_type) {
|
|
999
746
|
case "image":
|
|
1000
|
-
return /* @__PURE__ */
|
|
1001
|
-
message.content_url && /* @__PURE__ */
|
|
747
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
748
|
+
message.content_url && /* @__PURE__ */ jsx(
|
|
1002
749
|
"img",
|
|
1003
750
|
{
|
|
1004
751
|
src: message.content_url,
|
|
@@ -1006,30 +753,30 @@ function MediaContent({ message }) {
|
|
|
1006
753
|
className: "max-w-[240px] rounded-md"
|
|
1007
754
|
}
|
|
1008
755
|
),
|
|
1009
|
-
message.content && /* @__PURE__ */
|
|
756
|
+
message.content && /* @__PURE__ */ jsx("p", { className: "text-sm", children: message.content })
|
|
1010
757
|
] });
|
|
1011
758
|
case "audio":
|
|
1012
|
-
return /* @__PURE__ */
|
|
1013
|
-
/* @__PURE__ */
|
|
1014
|
-
/* @__PURE__ */
|
|
759
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
760
|
+
/* @__PURE__ */ jsx(Headphones, { className: "h-4 w-4" }),
|
|
761
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm", children: "Mensagem de \xE1udio" })
|
|
1015
762
|
] });
|
|
1016
763
|
case "video":
|
|
1017
|
-
return /* @__PURE__ */
|
|
1018
|
-
/* @__PURE__ */
|
|
1019
|
-
/* @__PURE__ */
|
|
1020
|
-
message.content && /* @__PURE__ */
|
|
764
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
765
|
+
/* @__PURE__ */ jsx(Video, { className: "h-4 w-4" }),
|
|
766
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm", children: "V\xEDdeo" }),
|
|
767
|
+
message.content && /* @__PURE__ */ jsx("p", { className: "text-sm", children: message.content })
|
|
1021
768
|
] });
|
|
1022
769
|
case "document": {
|
|
1023
770
|
const meta = parseMetadata(message.metadata);
|
|
1024
|
-
return /* @__PURE__ */
|
|
1025
|
-
/* @__PURE__ */
|
|
1026
|
-
/* @__PURE__ */
|
|
771
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
772
|
+
/* @__PURE__ */ jsx(File, { className: "h-4 w-4" }),
|
|
773
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm", children: meta.filename || "Documento" })
|
|
1027
774
|
] });
|
|
1028
775
|
}
|
|
1029
776
|
case "location":
|
|
1030
|
-
return /* @__PURE__ */
|
|
1031
|
-
/* @__PURE__ */
|
|
1032
|
-
/* @__PURE__ */
|
|
777
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
778
|
+
/* @__PURE__ */ jsx(MapPin, { className: "h-4 w-4" }),
|
|
779
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm", children: "Localiza\xE7\xE3o" })
|
|
1033
780
|
] });
|
|
1034
781
|
default:
|
|
1035
782
|
return null;
|
|
@@ -1065,11 +812,11 @@ function MessageBubble({
|
|
|
1065
812
|
setEditing(false);
|
|
1066
813
|
}
|
|
1067
814
|
if (isRevoked) {
|
|
1068
|
-
return /* @__PURE__ */
|
|
815
|
+
return /* @__PURE__ */ jsx(
|
|
1069
816
|
"div",
|
|
1070
817
|
{
|
|
1071
818
|
className: cn("flex", isOutbound ? "justify-end" : "justify-start"),
|
|
1072
|
-
children: /* @__PURE__ */
|
|
819
|
+
children: /* @__PURE__ */ jsx("div", { className: "max-w-[75%]", children: /* @__PURE__ */ jsxs(
|
|
1073
820
|
"div",
|
|
1074
821
|
{
|
|
1075
822
|
className: cn(
|
|
@@ -1077,8 +824,8 @@ function MessageBubble({
|
|
|
1077
824
|
isOutbound ? "bg-primary/40" : "bg-muted/60"
|
|
1078
825
|
),
|
|
1079
826
|
children: [
|
|
1080
|
-
/* @__PURE__ */
|
|
1081
|
-
/* @__PURE__ */
|
|
827
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
828
|
+
/* @__PURE__ */ jsx(
|
|
1082
829
|
Ban,
|
|
1083
830
|
{
|
|
1084
831
|
className: cn(
|
|
@@ -1087,7 +834,7 @@ function MessageBubble({
|
|
|
1087
834
|
)
|
|
1088
835
|
}
|
|
1089
836
|
),
|
|
1090
|
-
/* @__PURE__ */
|
|
837
|
+
/* @__PURE__ */ jsx(
|
|
1091
838
|
"p",
|
|
1092
839
|
{
|
|
1093
840
|
className: cn(
|
|
@@ -1098,14 +845,14 @@ function MessageBubble({
|
|
|
1098
845
|
}
|
|
1099
846
|
)
|
|
1100
847
|
] }),
|
|
1101
|
-
/* @__PURE__ */
|
|
848
|
+
/* @__PURE__ */ jsx(
|
|
1102
849
|
"div",
|
|
1103
850
|
{
|
|
1104
851
|
className: cn(
|
|
1105
852
|
"mt-1 flex items-center justify-end gap-1",
|
|
1106
853
|
isOutbound ? "text-primary-foreground/40" : "text-muted-foreground/60"
|
|
1107
854
|
),
|
|
1108
|
-
children: /* @__PURE__ */
|
|
855
|
+
children: /* @__PURE__ */ jsx("span", { className: "text-[10px]", children: time })
|
|
1109
856
|
}
|
|
1110
857
|
)
|
|
1111
858
|
]
|
|
@@ -1114,7 +861,7 @@ function MessageBubble({
|
|
|
1114
861
|
}
|
|
1115
862
|
);
|
|
1116
863
|
}
|
|
1117
|
-
return /* @__PURE__ */
|
|
864
|
+
return /* @__PURE__ */ jsxs(
|
|
1118
865
|
"div",
|
|
1119
866
|
{
|
|
1120
867
|
className: cn(
|
|
@@ -1122,11 +869,11 @@ function MessageBubble({
|
|
|
1122
869
|
isOutbound ? "justify-end" : "justify-start"
|
|
1123
870
|
),
|
|
1124
871
|
children: [
|
|
1125
|
-
/* @__PURE__ */
|
|
1126
|
-
canAct && /* @__PURE__ */
|
|
1127
|
-
/* @__PURE__ */
|
|
1128
|
-
/* @__PURE__ */
|
|
1129
|
-
canEdit && /* @__PURE__ */
|
|
872
|
+
/* @__PURE__ */ jsxs("div", { className: "max-w-[75%] relative", children: [
|
|
873
|
+
canAct && /* @__PURE__ */ jsx("div", { className: "absolute -top-1 right-1 opacity-0 group-hover:opacity-100 transition-opacity z-10", children: /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
874
|
+
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx("button", { className: "h-6 w-6 rounded-full bg-background/80 shadow-sm flex items-center justify-center hover:bg-background", children: /* @__PURE__ */ jsx(MoreHorizontal, { className: "h-3.5 w-3.5 text-muted-foreground" }) }) }),
|
|
875
|
+
/* @__PURE__ */ jsxs(DropdownMenuContent, { align: "end", className: "w-40", children: [
|
|
876
|
+
canEdit && /* @__PURE__ */ jsxs(
|
|
1130
877
|
DropdownMenuItem,
|
|
1131
878
|
{
|
|
1132
879
|
onSelect: (e) => {
|
|
@@ -1135,12 +882,12 @@ function MessageBubble({
|
|
|
1135
882
|
setEditContent(message.content || "");
|
|
1136
883
|
},
|
|
1137
884
|
children: [
|
|
1138
|
-
/* @__PURE__ */
|
|
885
|
+
/* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4 mr-2" }),
|
|
1139
886
|
"Editar"
|
|
1140
887
|
]
|
|
1141
888
|
}
|
|
1142
889
|
),
|
|
1143
|
-
/* @__PURE__ */
|
|
890
|
+
/* @__PURE__ */ jsxs(
|
|
1144
891
|
DropdownMenuItem,
|
|
1145
892
|
{
|
|
1146
893
|
onSelect: (e) => {
|
|
@@ -1149,7 +896,7 @@ function MessageBubble({
|
|
|
1149
896
|
},
|
|
1150
897
|
className: "text-destructive focus:text-destructive",
|
|
1151
898
|
children: [
|
|
1152
|
-
/* @__PURE__ */
|
|
899
|
+
/* @__PURE__ */ jsx(Trash2, { className: "h-4 w-4 mr-2" }),
|
|
1153
900
|
"Apagar para todos"
|
|
1154
901
|
]
|
|
1155
902
|
}
|
|
@@ -1157,7 +904,7 @@ function MessageBubble({
|
|
|
1157
904
|
] })
|
|
1158
905
|
] }) }),
|
|
1159
906
|
renderActions?.(message),
|
|
1160
|
-
/* @__PURE__ */
|
|
907
|
+
/* @__PURE__ */ jsxs(
|
|
1161
908
|
"div",
|
|
1162
909
|
{
|
|
1163
910
|
className: cn(
|
|
@@ -1167,7 +914,7 @@ function MessageBubble({
|
|
|
1167
914
|
isFailed && "bg-destructive/10 border border-destructive/30"
|
|
1168
915
|
),
|
|
1169
916
|
children: [
|
|
1170
|
-
agentLabel && /* @__PURE__ */
|
|
917
|
+
agentLabel && /* @__PURE__ */ jsx(
|
|
1171
918
|
"p",
|
|
1172
919
|
{
|
|
1173
920
|
className: cn(
|
|
@@ -1177,8 +924,8 @@ function MessageBubble({
|
|
|
1177
924
|
children: agentLabel
|
|
1178
925
|
}
|
|
1179
926
|
),
|
|
1180
|
-
editing ? /* @__PURE__ */
|
|
1181
|
-
/* @__PURE__ */
|
|
927
|
+
editing ? /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
928
|
+
/* @__PURE__ */ jsx(
|
|
1182
929
|
Textarea,
|
|
1183
930
|
{
|
|
1184
931
|
value: editContent,
|
|
@@ -1197,8 +944,8 @@ function MessageBubble({
|
|
|
1197
944
|
}
|
|
1198
945
|
}
|
|
1199
946
|
),
|
|
1200
|
-
/* @__PURE__ */
|
|
1201
|
-
/* @__PURE__ */
|
|
947
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-1.5", children: [
|
|
948
|
+
/* @__PURE__ */ jsx(
|
|
1202
949
|
Button,
|
|
1203
950
|
{
|
|
1204
951
|
size: "sm",
|
|
@@ -1208,7 +955,7 @@ function MessageBubble({
|
|
|
1208
955
|
children: "Cancelar"
|
|
1209
956
|
}
|
|
1210
957
|
),
|
|
1211
|
-
/* @__PURE__ */
|
|
958
|
+
/* @__PURE__ */ jsx(
|
|
1212
959
|
Button,
|
|
1213
960
|
{
|
|
1214
961
|
size: "sm",
|
|
@@ -1219,7 +966,7 @@ function MessageBubble({
|
|
|
1219
966
|
}
|
|
1220
967
|
)
|
|
1221
968
|
] })
|
|
1222
|
-
] }) : message.content_type === "text" ? /* @__PURE__ */
|
|
969
|
+
] }) : message.content_type === "text" ? /* @__PURE__ */ jsx(
|
|
1223
970
|
"p",
|
|
1224
971
|
{
|
|
1225
972
|
className: cn(
|
|
@@ -1228,8 +975,8 @@ function MessageBubble({
|
|
|
1228
975
|
),
|
|
1229
976
|
children: message.content
|
|
1230
977
|
}
|
|
1231
|
-
) : /* @__PURE__ */
|
|
1232
|
-
!editing && /* @__PURE__ */
|
|
978
|
+
) : /* @__PURE__ */ jsx(MediaContent, { message }),
|
|
979
|
+
!editing && /* @__PURE__ */ jsxs(
|
|
1233
980
|
"div",
|
|
1234
981
|
{
|
|
1235
982
|
className: cn(
|
|
@@ -1237,8 +984,8 @@ function MessageBubble({
|
|
|
1237
984
|
isFailed ? "text-destructive" : isOutbound ? "text-primary-foreground/60" : "text-muted-foreground"
|
|
1238
985
|
),
|
|
1239
986
|
children: [
|
|
1240
|
-
isEdited && /* @__PURE__ */
|
|
1241
|
-
/* @__PURE__ */
|
|
987
|
+
isEdited && /* @__PURE__ */ jsx("span", { className: "text-[10px] italic", children: "editada" }),
|
|
988
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px]", children: time }),
|
|
1242
989
|
isOutbound && statusIcons[message.status]
|
|
1243
990
|
]
|
|
1244
991
|
}
|
|
@@ -1246,30 +993,30 @@ function MessageBubble({
|
|
|
1246
993
|
]
|
|
1247
994
|
}
|
|
1248
995
|
),
|
|
1249
|
-
isFailed && /* @__PURE__ */
|
|
1250
|
-
/* @__PURE__ */
|
|
1251
|
-
/* @__PURE__ */
|
|
1252
|
-
onRetry && /* @__PURE__ */
|
|
996
|
+
isFailed && /* @__PURE__ */ jsxs("div", { className: "mt-1 flex items-center gap-1.5 justify-end px-1", children: [
|
|
997
|
+
/* @__PURE__ */ jsx(AlertCircle, { className: "h-3 w-3 shrink-0 text-destructive" }),
|
|
998
|
+
/* @__PURE__ */ jsx("span", { className: "text-[11px] text-destructive", children: message._error || "Erro ao enviar" }),
|
|
999
|
+
onRetry && /* @__PURE__ */ jsxs(
|
|
1253
1000
|
"button",
|
|
1254
1001
|
{
|
|
1255
1002
|
onClick: () => onRetry(message),
|
|
1256
1003
|
className: "inline-flex items-center gap-0.5 text-[11px] text-destructive font-medium hover:text-destructive/80 hover:underline cursor-pointer ml-1",
|
|
1257
1004
|
children: [
|
|
1258
|
-
/* @__PURE__ */
|
|
1005
|
+
/* @__PURE__ */ jsx(RotateCcw, { className: "h-3 w-3" }),
|
|
1259
1006
|
"Reenviar"
|
|
1260
1007
|
]
|
|
1261
1008
|
}
|
|
1262
1009
|
)
|
|
1263
1010
|
] })
|
|
1264
1011
|
] }),
|
|
1265
|
-
/* @__PURE__ */
|
|
1266
|
-
/* @__PURE__ */
|
|
1267
|
-
/* @__PURE__ */
|
|
1268
|
-
/* @__PURE__ */
|
|
1012
|
+
/* @__PURE__ */ jsx(AlertDialog, { open: showRevokeDialog, onOpenChange: setShowRevokeDialog, children: /* @__PURE__ */ jsxs(AlertDialogContent, { children: [
|
|
1013
|
+
/* @__PURE__ */ jsxs(AlertDialogHeader, { children: [
|
|
1014
|
+
/* @__PURE__ */ jsx(AlertDialogTitle, { children: "Apagar mensagem?" }),
|
|
1015
|
+
/* @__PURE__ */ jsx(AlertDialogDescription, { children: 'A mensagem ser\xE1 apagada para todos no WhatsApp. Ela continuar\xE1 vis\xEDvel aqui como "mensagem apagada".' })
|
|
1269
1016
|
] }),
|
|
1270
|
-
/* @__PURE__ */
|
|
1271
|
-
/* @__PURE__ */
|
|
1272
|
-
/* @__PURE__ */
|
|
1017
|
+
/* @__PURE__ */ jsxs(AlertDialogFooter, { children: [
|
|
1018
|
+
/* @__PURE__ */ jsx(AlertDialogCancel, { children: "Cancelar" }),
|
|
1019
|
+
/* @__PURE__ */ jsx(
|
|
1273
1020
|
AlertDialogAction,
|
|
1274
1021
|
{
|
|
1275
1022
|
className: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
@@ -1287,7 +1034,8 @@ function MessageBubble({
|
|
|
1287
1034
|
// src/components/chat-input.tsx
|
|
1288
1035
|
import { useState as useState2, useRef } from "react";
|
|
1289
1036
|
import { Send } from "lucide-react";
|
|
1290
|
-
import {
|
|
1037
|
+
import { Button as Button2, Textarea as Textarea2 } from "@greatapps/greatauth-ui/ui";
|
|
1038
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1291
1039
|
function ChatInput({ onSend, disabled }) {
|
|
1292
1040
|
const [content, setContent] = useState2("");
|
|
1293
1041
|
const textareaRef = useRef(null);
|
|
@@ -1304,9 +1052,9 @@ function ChatInput({ onSend, disabled }) {
|
|
|
1304
1052
|
handleSend();
|
|
1305
1053
|
}
|
|
1306
1054
|
}
|
|
1307
|
-
return /* @__PURE__ */
|
|
1308
|
-
/* @__PURE__ */
|
|
1309
|
-
|
|
1055
|
+
return /* @__PURE__ */ jsx2("div", { className: "border-t p-3", children: /* @__PURE__ */ jsxs2("div", { className: "flex items-end gap-2", children: [
|
|
1056
|
+
/* @__PURE__ */ jsx2(
|
|
1057
|
+
Textarea2,
|
|
1310
1058
|
{
|
|
1311
1059
|
ref: textareaRef,
|
|
1312
1060
|
placeholder: "Digite uma mensagem...",
|
|
@@ -1317,157 +1065,22 @@ function ChatInput({ onSend, disabled }) {
|
|
|
1317
1065
|
className: "min-h-[40px] max-h-[120px] resize-none"
|
|
1318
1066
|
}
|
|
1319
1067
|
),
|
|
1320
|
-
/* @__PURE__ */
|
|
1321
|
-
|
|
1068
|
+
/* @__PURE__ */ jsx2(
|
|
1069
|
+
Button2,
|
|
1322
1070
|
{
|
|
1323
1071
|
size: "icon",
|
|
1324
1072
|
onClick: handleSend,
|
|
1325
1073
|
disabled: !content.trim() || disabled,
|
|
1326
1074
|
className: "shrink-0",
|
|
1327
|
-
children: /* @__PURE__ */
|
|
1075
|
+
children: /* @__PURE__ */ jsx2(Send, { className: "h-4 w-4" })
|
|
1328
1076
|
}
|
|
1329
1077
|
)
|
|
1330
1078
|
] }) });
|
|
1331
1079
|
}
|
|
1332
1080
|
|
|
1333
|
-
// src/components/ui/skeleton.tsx
|
|
1334
|
-
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
1335
|
-
function Skeleton({
|
|
1336
|
-
className,
|
|
1337
|
-
...props
|
|
1338
|
-
}) {
|
|
1339
|
-
return /* @__PURE__ */ jsx7(
|
|
1340
|
-
"div",
|
|
1341
|
-
{
|
|
1342
|
-
"data-slot": "skeleton",
|
|
1343
|
-
className: cn("bg-muted rounded-md animate-pulse", className),
|
|
1344
|
-
...props
|
|
1345
|
-
}
|
|
1346
|
-
);
|
|
1347
|
-
}
|
|
1348
|
-
|
|
1349
|
-
// src/components/ui/select.tsx
|
|
1350
|
-
import { Select as SelectPrimitive } from "radix-ui";
|
|
1351
|
-
import { Check as Check3, ChevronDown, ChevronUp, ChevronsUpDown } from "lucide-react";
|
|
1352
|
-
import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1353
|
-
function Select({
|
|
1354
|
-
...props
|
|
1355
|
-
}) {
|
|
1356
|
-
return /* @__PURE__ */ jsx8(SelectPrimitive.Root, { "data-slot": "select", ...props });
|
|
1357
|
-
}
|
|
1358
|
-
function SelectValue({
|
|
1359
|
-
...props
|
|
1360
|
-
}) {
|
|
1361
|
-
return /* @__PURE__ */ jsx8(SelectPrimitive.Value, { "data-slot": "select-value", ...props });
|
|
1362
|
-
}
|
|
1363
|
-
function SelectTrigger({
|
|
1364
|
-
className,
|
|
1365
|
-
size = "default",
|
|
1366
|
-
children,
|
|
1367
|
-
...props
|
|
1368
|
-
}) {
|
|
1369
|
-
return /* @__PURE__ */ jsxs5(
|
|
1370
|
-
SelectPrimitive.Trigger,
|
|
1371
|
-
{
|
|
1372
|
-
"data-slot": "select-trigger",
|
|
1373
|
-
"data-size": size,
|
|
1374
|
-
className: cn(
|
|
1375
|
-
"border-input data-placeholder:text-muted-foreground dark:bg-input/30 dark:hover:bg-input/50 focus-visible:border-ring focus-visible:ring-ring/50 gap-1.5 rounded-md border bg-transparent py-2 pr-2 pl-2.5 text-sm shadow-xs transition-[color,box-shadow] focus-visible:ring-3 data-[size=default]:h-9 data-[size=sm]:h-8 [&_svg:not([class*='size-'])]:size-4 flex w-fit items-center justify-between whitespace-nowrap outline-none disabled:cursor-not-allowed disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
1376
|
-
className
|
|
1377
|
-
),
|
|
1378
|
-
...props,
|
|
1379
|
-
children: [
|
|
1380
|
-
children,
|
|
1381
|
-
/* @__PURE__ */ jsx8(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx8(ChevronsUpDown, { className: "text-muted-foreground size-4 pointer-events-none" }) })
|
|
1382
|
-
]
|
|
1383
|
-
}
|
|
1384
|
-
);
|
|
1385
|
-
}
|
|
1386
|
-
function SelectContent({
|
|
1387
|
-
className,
|
|
1388
|
-
children,
|
|
1389
|
-
position = "item-aligned",
|
|
1390
|
-
align = "center",
|
|
1391
|
-
...props
|
|
1392
|
-
}) {
|
|
1393
|
-
return /* @__PURE__ */ jsx8(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs5(
|
|
1394
|
-
SelectPrimitive.Content,
|
|
1395
|
-
{
|
|
1396
|
-
"data-slot": "select-content",
|
|
1397
|
-
className: cn(
|
|
1398
|
-
"bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 min-w-36 rounded-md shadow-md ring-1 duration-100 relative z-50 max-h-(--radix-select-content-available-height) overflow-x-hidden overflow-y-auto",
|
|
1399
|
-
position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
|
1400
|
-
className
|
|
1401
|
-
),
|
|
1402
|
-
position,
|
|
1403
|
-
align,
|
|
1404
|
-
...props,
|
|
1405
|
-
children: [
|
|
1406
|
-
/* @__PURE__ */ jsx8(SelectScrollUpButton, {}),
|
|
1407
|
-
/* @__PURE__ */ jsx8(SelectPrimitive.Viewport, { children }),
|
|
1408
|
-
/* @__PURE__ */ jsx8(SelectScrollDownButton, {})
|
|
1409
|
-
]
|
|
1410
|
-
}
|
|
1411
|
-
) });
|
|
1412
|
-
}
|
|
1413
|
-
function SelectItem({
|
|
1414
|
-
className,
|
|
1415
|
-
children,
|
|
1416
|
-
...props
|
|
1417
|
-
}) {
|
|
1418
|
-
return /* @__PURE__ */ jsxs5(
|
|
1419
|
-
SelectPrimitive.Item,
|
|
1420
|
-
{
|
|
1421
|
-
"data-slot": "select-item",
|
|
1422
|
-
className: cn(
|
|
1423
|
-
"focus:bg-accent focus:text-accent-foreground gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm [&_svg:not([class*='size-'])]:size-4 relative flex w-full cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
1424
|
-
className
|
|
1425
|
-
),
|
|
1426
|
-
...props,
|
|
1427
|
-
children: [
|
|
1428
|
-
/* @__PURE__ */ jsx8("span", { className: "pointer-events-none absolute right-2 flex size-4 items-center justify-center", children: /* @__PURE__ */ jsx8(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx8(Check3, { className: "pointer-events-none" }) }) }),
|
|
1429
|
-
/* @__PURE__ */ jsx8(SelectPrimitive.ItemText, { children })
|
|
1430
|
-
]
|
|
1431
|
-
}
|
|
1432
|
-
);
|
|
1433
|
-
}
|
|
1434
|
-
function SelectScrollUpButton({
|
|
1435
|
-
className,
|
|
1436
|
-
...props
|
|
1437
|
-
}) {
|
|
1438
|
-
return /* @__PURE__ */ jsx8(
|
|
1439
|
-
SelectPrimitive.ScrollUpButton,
|
|
1440
|
-
{
|
|
1441
|
-
"data-slot": "select-scroll-up-button",
|
|
1442
|
-
className: cn(
|
|
1443
|
-
"bg-popover z-10 flex cursor-default items-center justify-center py-1 [&_svg:not([class*='size-'])]:size-4",
|
|
1444
|
-
className
|
|
1445
|
-
),
|
|
1446
|
-
...props,
|
|
1447
|
-
children: /* @__PURE__ */ jsx8(ChevronUp, {})
|
|
1448
|
-
}
|
|
1449
|
-
);
|
|
1450
|
-
}
|
|
1451
|
-
function SelectScrollDownButton({
|
|
1452
|
-
className,
|
|
1453
|
-
...props
|
|
1454
|
-
}) {
|
|
1455
|
-
return /* @__PURE__ */ jsx8(
|
|
1456
|
-
SelectPrimitive.ScrollDownButton,
|
|
1457
|
-
{
|
|
1458
|
-
"data-slot": "select-scroll-down-button",
|
|
1459
|
-
className: cn(
|
|
1460
|
-
"bg-popover z-10 flex cursor-default items-center justify-center py-1 [&_svg:not([class*='size-'])]:size-4",
|
|
1461
|
-
className
|
|
1462
|
-
),
|
|
1463
|
-
...props,
|
|
1464
|
-
children: /* @__PURE__ */ jsx8(ChevronDown, {})
|
|
1465
|
-
}
|
|
1466
|
-
);
|
|
1467
|
-
}
|
|
1468
|
-
|
|
1469
1081
|
// src/components/chat-view.tsx
|
|
1470
|
-
import {
|
|
1082
|
+
import { Skeleton, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@greatapps/greatauth-ui/ui";
|
|
1083
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1471
1084
|
function ChatView({
|
|
1472
1085
|
messages,
|
|
1473
1086
|
isLoading,
|
|
@@ -1495,35 +1108,35 @@ function ChatView({
|
|
|
1495
1108
|
prevMessageCount.current = messages?.length || 0;
|
|
1496
1109
|
}, [messages]);
|
|
1497
1110
|
const groups = messages ? groupMessagesByDate(messages) : [];
|
|
1498
|
-
return /* @__PURE__ */
|
|
1499
|
-
renderHeader !== void 0 ? renderHeader : /* @__PURE__ */
|
|
1500
|
-
/* @__PURE__ */
|
|
1501
|
-
renderStatusDropdown !== void 0 ? renderStatusDropdown : onStatusChange ? /* @__PURE__ */
|
|
1111
|
+
return /* @__PURE__ */ jsxs3("div", { className: "flex h-full flex-col", children: [
|
|
1112
|
+
renderHeader !== void 0 ? renderHeader : /* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-between border-b px-4 py-3", children: [
|
|
1113
|
+
/* @__PURE__ */ jsx3("div", { className: "flex-1" }),
|
|
1114
|
+
renderStatusDropdown !== void 0 ? renderStatusDropdown : onStatusChange ? /* @__PURE__ */ jsxs3(
|
|
1502
1115
|
Select,
|
|
1503
1116
|
{
|
|
1504
1117
|
value: inboxStatus,
|
|
1505
1118
|
onValueChange: onStatusChange,
|
|
1506
1119
|
children: [
|
|
1507
|
-
/* @__PURE__ */
|
|
1508
|
-
/* @__PURE__ */
|
|
1509
|
-
/* @__PURE__ */
|
|
1510
|
-
/* @__PURE__ */
|
|
1511
|
-
/* @__PURE__ */
|
|
1120
|
+
/* @__PURE__ */ jsx3(SelectTrigger, { className: "w-[130px] h-8 text-xs", children: /* @__PURE__ */ jsx3(SelectValue, { placeholder: "Status" }) }),
|
|
1121
|
+
/* @__PURE__ */ jsxs3(SelectContent, { children: [
|
|
1122
|
+
/* @__PURE__ */ jsx3(SelectItem, { value: "open", children: "Aberta" }),
|
|
1123
|
+
/* @__PURE__ */ jsx3(SelectItem, { value: "pending", children: "Pendente" }),
|
|
1124
|
+
/* @__PURE__ */ jsx3(SelectItem, { value: "resolved", children: "Resolvida" })
|
|
1512
1125
|
] })
|
|
1513
1126
|
]
|
|
1514
1127
|
}
|
|
1515
1128
|
) : null
|
|
1516
1129
|
] }),
|
|
1517
|
-
/* @__PURE__ */
|
|
1130
|
+
/* @__PURE__ */ jsx3("div", { ref: scrollRef, className: "flex-1 overflow-y-auto p-4", children: isLoading ? /* @__PURE__ */ jsx3("div", { className: "space-y-4", children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ jsx3(
|
|
1518
1131
|
"div",
|
|
1519
1132
|
{
|
|
1520
1133
|
className: `flex ${i % 2 === 0 ? "justify-start" : "justify-end"}`,
|
|
1521
|
-
children: /* @__PURE__ */
|
|
1134
|
+
children: /* @__PURE__ */ jsx3(Skeleton, { className: "h-12 w-64 rounded-lg" })
|
|
1522
1135
|
},
|
|
1523
1136
|
i
|
|
1524
|
-
)) }) : groups.length === 0 ? /* @__PURE__ */
|
|
1525
|
-
/* @__PURE__ */
|
|
1526
|
-
/* @__PURE__ */
|
|
1137
|
+
)) }) : groups.length === 0 ? /* @__PURE__ */ jsx3("div", { className: "flex h-full items-center justify-center text-sm text-muted-foreground", children: "Nenhuma mensagem ainda" }) : /* @__PURE__ */ jsx3("div", { className: "space-y-4", children: groups.map((group, gi) => /* @__PURE__ */ jsxs3("div", { children: [
|
|
1138
|
+
/* @__PURE__ */ jsx3("div", { className: "mb-3 flex justify-center", children: /* @__PURE__ */ jsx3("span", { className: "rounded-full bg-muted px-3 py-1 text-[11px] text-muted-foreground", children: formatDateGroup(group.date) }) }),
|
|
1139
|
+
/* @__PURE__ */ jsx3("div", { className: "space-y-1", children: group.messages.map((msg) => /* @__PURE__ */ jsx3(
|
|
1527
1140
|
MessageBubble,
|
|
1528
1141
|
{
|
|
1529
1142
|
message: msg,
|
|
@@ -1534,48 +1147,13 @@ function ChatView({
|
|
|
1534
1147
|
msg.id
|
|
1535
1148
|
)) })
|
|
1536
1149
|
] }, gi)) }) }),
|
|
1537
|
-
/* @__PURE__ */
|
|
1150
|
+
/* @__PURE__ */ jsx3(ChatInput, { onSend, disabled: sendDisabled })
|
|
1538
1151
|
] });
|
|
1539
1152
|
}
|
|
1540
1153
|
|
|
1541
|
-
// src/components/ui/avatar.tsx
|
|
1542
|
-
import { Avatar as AvatarPrimitive } from "radix-ui";
|
|
1543
|
-
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
1544
|
-
function Avatar({
|
|
1545
|
-
className,
|
|
1546
|
-
...props
|
|
1547
|
-
}) {
|
|
1548
|
-
return /* @__PURE__ */ jsx10(
|
|
1549
|
-
AvatarPrimitive.Root,
|
|
1550
|
-
{
|
|
1551
|
-
"data-slot": "avatar",
|
|
1552
|
-
className: cn(
|
|
1553
|
-
"relative flex size-8 shrink-0 overflow-hidden rounded-full",
|
|
1554
|
-
className
|
|
1555
|
-
),
|
|
1556
|
-
...props
|
|
1557
|
-
}
|
|
1558
|
-
);
|
|
1559
|
-
}
|
|
1560
|
-
function AvatarFallback({
|
|
1561
|
-
className,
|
|
1562
|
-
...props
|
|
1563
|
-
}) {
|
|
1564
|
-
return /* @__PURE__ */ jsx10(
|
|
1565
|
-
AvatarPrimitive.Fallback,
|
|
1566
|
-
{
|
|
1567
|
-
"data-slot": "avatar-fallback",
|
|
1568
|
-
className: cn(
|
|
1569
|
-
"flex size-full items-center justify-center rounded-full bg-muted",
|
|
1570
|
-
className
|
|
1571
|
-
),
|
|
1572
|
-
...props
|
|
1573
|
-
}
|
|
1574
|
-
);
|
|
1575
|
-
}
|
|
1576
|
-
|
|
1577
1154
|
// src/components/contact-avatar.tsx
|
|
1578
|
-
import {
|
|
1155
|
+
import { Avatar, AvatarFallback, cn as cn2 } from "@greatapps/greatauth-ui/ui";
|
|
1156
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
1579
1157
|
var COLORS = [
|
|
1580
1158
|
"bg-red-100 text-red-700 dark:bg-red-900 dark:text-red-300",
|
|
1581
1159
|
"bg-orange-100 text-orange-700 dark:bg-orange-900 dark:text-orange-300",
|
|
@@ -1613,102 +1191,30 @@ function ContactAvatar({
|
|
|
1613
1191
|
const displayName = name || "?";
|
|
1614
1192
|
const color = COLORS[hashCode(displayName) % COLORS.length];
|
|
1615
1193
|
const initials = getInitials(displayName);
|
|
1616
|
-
return /* @__PURE__ */
|
|
1194
|
+
return /* @__PURE__ */ jsx4(Avatar, { className: cn2(SIZE_MAP[size], className), children: /* @__PURE__ */ jsx4(AvatarFallback, { className: cn2("font-medium", color), children: initials }) });
|
|
1617
1195
|
}
|
|
1618
1196
|
|
|
1619
1197
|
// src/components/inbox-item.tsx
|
|
1620
1198
|
import { useState as useState3 } from "react";
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
}
|
|
1637
|
-
},
|
|
1638
|
-
defaultVariants: {
|
|
1639
|
-
variant: "default"
|
|
1640
|
-
}
|
|
1641
|
-
}
|
|
1642
|
-
);
|
|
1643
|
-
function Badge({
|
|
1644
|
-
className,
|
|
1645
|
-
variant = "default",
|
|
1646
|
-
asChild = false,
|
|
1647
|
-
...props
|
|
1648
|
-
}) {
|
|
1649
|
-
const Comp = asChild ? Slot2.Root : "span";
|
|
1650
|
-
return /* @__PURE__ */ jsx12(
|
|
1651
|
-
Comp,
|
|
1652
|
-
{
|
|
1653
|
-
"data-slot": "badge",
|
|
1654
|
-
className: cn(badgeVariants({ variant }), className),
|
|
1655
|
-
...props
|
|
1656
|
-
}
|
|
1657
|
-
);
|
|
1658
|
-
}
|
|
1659
|
-
|
|
1660
|
-
// src/components/ui/tooltip.tsx
|
|
1661
|
-
import { Tooltip as TooltipPrimitive } from "radix-ui";
|
|
1662
|
-
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
1663
|
-
function TooltipProvider({
|
|
1664
|
-
delayDuration = 0,
|
|
1665
|
-
...props
|
|
1666
|
-
}) {
|
|
1667
|
-
return /* @__PURE__ */ jsx13(
|
|
1668
|
-
TooltipPrimitive.Provider,
|
|
1669
|
-
{
|
|
1670
|
-
"data-slot": "tooltip-provider",
|
|
1671
|
-
delayDuration,
|
|
1672
|
-
...props
|
|
1673
|
-
}
|
|
1674
|
-
);
|
|
1675
|
-
}
|
|
1676
|
-
function Tooltip({
|
|
1677
|
-
...props
|
|
1678
|
-
}) {
|
|
1679
|
-
return /* @__PURE__ */ jsx13(TooltipProvider, { children: /* @__PURE__ */ jsx13(TooltipPrimitive.Root, { "data-slot": "tooltip", ...props }) });
|
|
1680
|
-
}
|
|
1681
|
-
function TooltipTrigger({
|
|
1682
|
-
...props
|
|
1683
|
-
}) {
|
|
1684
|
-
return /* @__PURE__ */ jsx13(TooltipPrimitive.Trigger, { "data-slot": "tooltip-trigger", ...props });
|
|
1685
|
-
}
|
|
1686
|
-
function TooltipContent({
|
|
1687
|
-
className,
|
|
1688
|
-
sideOffset = 4,
|
|
1689
|
-
children,
|
|
1690
|
-
...props
|
|
1691
|
-
}) {
|
|
1692
|
-
return /* @__PURE__ */ jsx13(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsx13(
|
|
1693
|
-
TooltipPrimitive.Content,
|
|
1694
|
-
{
|
|
1695
|
-
"data-slot": "tooltip-content",
|
|
1696
|
-
sideOffset,
|
|
1697
|
-
className: cn(
|
|
1698
|
-
"z-50 overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
1699
|
-
className
|
|
1700
|
-
),
|
|
1701
|
-
...props,
|
|
1702
|
-
children
|
|
1703
|
-
}
|
|
1704
|
-
) });
|
|
1705
|
-
}
|
|
1706
|
-
|
|
1707
|
-
// src/components/inbox-item.tsx
|
|
1199
|
+
import {
|
|
1200
|
+
Badge,
|
|
1201
|
+
Tooltip,
|
|
1202
|
+
TooltipTrigger,
|
|
1203
|
+
TooltipContent,
|
|
1204
|
+
AlertDialog as AlertDialog2,
|
|
1205
|
+
AlertDialogAction as AlertDialogAction2,
|
|
1206
|
+
AlertDialogCancel as AlertDialogCancel2,
|
|
1207
|
+
AlertDialogContent as AlertDialogContent2,
|
|
1208
|
+
AlertDialogDescription as AlertDialogDescription2,
|
|
1209
|
+
AlertDialogFooter as AlertDialogFooter2,
|
|
1210
|
+
AlertDialogHeader as AlertDialogHeader2,
|
|
1211
|
+
AlertDialogTitle as AlertDialogTitle2,
|
|
1212
|
+
cn as cn3
|
|
1213
|
+
} from "@greatapps/greatauth-ui/ui";
|
|
1708
1214
|
import { formatDistanceToNow } from "date-fns";
|
|
1709
1215
|
import { ptBR as ptBR2 } from "date-fns/locale";
|
|
1710
1216
|
import { Trash2 as Trash22 } from "lucide-react";
|
|
1711
|
-
import { Fragment, jsx as
|
|
1217
|
+
import { Fragment, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1712
1218
|
var statusColors = {
|
|
1713
1219
|
open: "bg-green-500/10 text-green-600 border-green-200",
|
|
1714
1220
|
pending: "bg-yellow-500/10 text-yellow-600 border-yellow-200",
|
|
@@ -1734,17 +1240,17 @@ function InboxItem({
|
|
|
1734
1240
|
});
|
|
1735
1241
|
const lastMessage = inbox.last_message_content_type === "text" ? inbox.last_message_content : inbox.last_message_content_type ? `[${inbox.last_message_content_type}]` : null;
|
|
1736
1242
|
const directionPrefix = inbox.last_message_direction === "outbound" ? "Voc\xEA: " : "";
|
|
1737
|
-
return /* @__PURE__ */
|
|
1738
|
-
/* @__PURE__ */
|
|
1243
|
+
return /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
1244
|
+
/* @__PURE__ */ jsxs4(
|
|
1739
1245
|
"div",
|
|
1740
1246
|
{
|
|
1741
|
-
className:
|
|
1247
|
+
className: cn3(
|
|
1742
1248
|
"flex w-full items-start gap-3 rounded-md p-3 text-left transition-colors hover:bg-accent group relative cursor-pointer",
|
|
1743
1249
|
isSelected && "bg-accent"
|
|
1744
1250
|
),
|
|
1745
1251
|
onClick,
|
|
1746
1252
|
children: [
|
|
1747
|
-
/* @__PURE__ */
|
|
1253
|
+
/* @__PURE__ */ jsx5(
|
|
1748
1254
|
ContactAvatar,
|
|
1749
1255
|
{
|
|
1750
1256
|
name: inbox.contact_name,
|
|
@@ -1752,14 +1258,14 @@ function InboxItem({
|
|
|
1752
1258
|
size: "md"
|
|
1753
1259
|
}
|
|
1754
1260
|
),
|
|
1755
|
-
/* @__PURE__ */
|
|
1756
|
-
/* @__PURE__ */
|
|
1757
|
-
/* @__PURE__ */
|
|
1758
|
-
/* @__PURE__ */
|
|
1759
|
-
/* @__PURE__ */
|
|
1261
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex-1 overflow-hidden", children: [
|
|
1262
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-between gap-2", children: [
|
|
1263
|
+
/* @__PURE__ */ jsx5("span", { className: "truncate font-medium text-sm", children: inbox.contact_name || "Desconhecido" }),
|
|
1264
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-1 shrink-0", children: [
|
|
1265
|
+
/* @__PURE__ */ jsx5("span", { className: "text-xs text-muted-foreground", children: timeAgo }),
|
|
1760
1266
|
renderActions?.(inbox),
|
|
1761
|
-
onDelete && /* @__PURE__ */
|
|
1762
|
-
/* @__PURE__ */
|
|
1267
|
+
onDelete && /* @__PURE__ */ jsxs4(Tooltip, { children: [
|
|
1268
|
+
/* @__PURE__ */ jsx5(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx5(
|
|
1763
1269
|
"button",
|
|
1764
1270
|
{
|
|
1765
1271
|
className: "h-5 w-5 rounded flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity hover:bg-muted text-destructive",
|
|
@@ -1767,20 +1273,20 @@ function InboxItem({
|
|
|
1767
1273
|
e.stopPropagation();
|
|
1768
1274
|
setShowDeleteDialog(true);
|
|
1769
1275
|
},
|
|
1770
|
-
children: /* @__PURE__ */
|
|
1276
|
+
children: /* @__PURE__ */ jsx5(Trash22, { className: "h-3.5 w-3.5" })
|
|
1771
1277
|
}
|
|
1772
1278
|
) }),
|
|
1773
|
-
/* @__PURE__ */
|
|
1279
|
+
/* @__PURE__ */ jsx5(TooltipContent, { children: "Excluir conversa" })
|
|
1774
1280
|
] })
|
|
1775
1281
|
] })
|
|
1776
1282
|
] }),
|
|
1777
|
-
/* @__PURE__ */
|
|
1778
|
-
/* @__PURE__ */
|
|
1779
|
-
/* @__PURE__ */
|
|
1283
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-between gap-2 mt-0.5", children: [
|
|
1284
|
+
/* @__PURE__ */ jsx5("p", { className: "truncate text-xs text-muted-foreground", children: lastMessage ? `${directionPrefix}${lastMessage}` : "Sem mensagens" }),
|
|
1285
|
+
/* @__PURE__ */ jsx5(
|
|
1780
1286
|
Badge,
|
|
1781
1287
|
{
|
|
1782
1288
|
variant: "outline",
|
|
1783
|
-
className:
|
|
1289
|
+
className: cn3(
|
|
1784
1290
|
"shrink-0 text-[10px] px-1.5 py-0",
|
|
1785
1291
|
statusColors[inbox.status]
|
|
1786
1292
|
),
|
|
@@ -1792,19 +1298,19 @@ function InboxItem({
|
|
|
1792
1298
|
]
|
|
1793
1299
|
}
|
|
1794
1300
|
),
|
|
1795
|
-
/* @__PURE__ */
|
|
1796
|
-
/* @__PURE__ */
|
|
1797
|
-
/* @__PURE__ */
|
|
1798
|
-
/* @__PURE__ */
|
|
1301
|
+
/* @__PURE__ */ jsx5(AlertDialog2, { open: showDeleteDialog, onOpenChange: setShowDeleteDialog, children: /* @__PURE__ */ jsxs4(AlertDialogContent2, { children: [
|
|
1302
|
+
/* @__PURE__ */ jsxs4(AlertDialogHeader2, { children: [
|
|
1303
|
+
/* @__PURE__ */ jsx5(AlertDialogTitle2, { children: "Excluir conversa?" }),
|
|
1304
|
+
/* @__PURE__ */ jsxs4(AlertDialogDescription2, { children: [
|
|
1799
1305
|
"A conversa com ",
|
|
1800
1306
|
inbox.contact_name || "este contato",
|
|
1801
1307
|
" ser\xE1 removida da lista. As mensagens n\xE3o ser\xE3o apagadas do WhatsApp."
|
|
1802
1308
|
] })
|
|
1803
1309
|
] }),
|
|
1804
|
-
/* @__PURE__ */
|
|
1805
|
-
/* @__PURE__ */
|
|
1806
|
-
/* @__PURE__ */
|
|
1807
|
-
|
|
1310
|
+
/* @__PURE__ */ jsxs4(AlertDialogFooter2, { children: [
|
|
1311
|
+
/* @__PURE__ */ jsx5(AlertDialogCancel2, { children: "Cancelar" }),
|
|
1312
|
+
/* @__PURE__ */ jsx5(
|
|
1313
|
+
AlertDialogAction2,
|
|
1808
1314
|
{
|
|
1809
1315
|
className: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
1810
1316
|
onClick: () => onDelete?.(inbox.id),
|
|
@@ -1818,120 +1324,9 @@ function InboxItem({
|
|
|
1818
1324
|
|
|
1819
1325
|
// src/components/inbox-sidebar.tsx
|
|
1820
1326
|
import { useState as useState4, useMemo as useMemo3 } from "react";
|
|
1821
|
-
|
|
1822
|
-
// src/components/ui/input.tsx
|
|
1823
|
-
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
1824
|
-
function Input({ className, type, ...props }) {
|
|
1825
|
-
return /* @__PURE__ */ jsx15(
|
|
1826
|
-
"input",
|
|
1827
|
-
{
|
|
1828
|
-
type,
|
|
1829
|
-
"data-slot": "input",
|
|
1830
|
-
className: cn(
|
|
1831
|
-
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
1832
|
-
className
|
|
1833
|
-
),
|
|
1834
|
-
...props
|
|
1835
|
-
}
|
|
1836
|
-
);
|
|
1837
|
-
}
|
|
1838
|
-
|
|
1839
|
-
// src/components/ui/tabs.tsx
|
|
1840
|
-
import { Tabs as TabsPrimitive } from "radix-ui";
|
|
1841
|
-
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
1842
|
-
function Tabs({
|
|
1843
|
-
className,
|
|
1844
|
-
...props
|
|
1845
|
-
}) {
|
|
1846
|
-
return /* @__PURE__ */ jsx16(
|
|
1847
|
-
TabsPrimitive.Root,
|
|
1848
|
-
{
|
|
1849
|
-
"data-slot": "tabs",
|
|
1850
|
-
className: cn("flex flex-col gap-2", className),
|
|
1851
|
-
...props
|
|
1852
|
-
}
|
|
1853
|
-
);
|
|
1854
|
-
}
|
|
1855
|
-
function TabsList({
|
|
1856
|
-
className,
|
|
1857
|
-
...props
|
|
1858
|
-
}) {
|
|
1859
|
-
return /* @__PURE__ */ jsx16(
|
|
1860
|
-
TabsPrimitive.List,
|
|
1861
|
-
{
|
|
1862
|
-
"data-slot": "tabs-list",
|
|
1863
|
-
className: cn(
|
|
1864
|
-
"inline-flex h-9 w-fit items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",
|
|
1865
|
-
className
|
|
1866
|
-
),
|
|
1867
|
-
...props
|
|
1868
|
-
}
|
|
1869
|
-
);
|
|
1870
|
-
}
|
|
1871
|
-
function TabsTrigger({
|
|
1872
|
-
className,
|
|
1873
|
-
...props
|
|
1874
|
-
}) {
|
|
1875
|
-
return /* @__PURE__ */ jsx16(
|
|
1876
|
-
TabsPrimitive.Trigger,
|
|
1877
|
-
{
|
|
1878
|
-
"data-slot": "tabs-trigger",
|
|
1879
|
-
className: cn(
|
|
1880
|
-
"inline-flex items-center justify-center gap-1.5 rounded-md px-2.5 py-1 text-sm font-medium whitespace-nowrap transition-all disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:size-4",
|
|
1881
|
-
className
|
|
1882
|
-
),
|
|
1883
|
-
...props
|
|
1884
|
-
}
|
|
1885
|
-
);
|
|
1886
|
-
}
|
|
1887
|
-
|
|
1888
|
-
// src/components/ui/scroll-area.tsx
|
|
1889
|
-
import { ScrollArea as ScrollAreaPrimitive } from "radix-ui";
|
|
1890
|
-
import { jsx as jsx17, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1891
|
-
function ScrollArea({
|
|
1892
|
-
className,
|
|
1893
|
-
children,
|
|
1894
|
-
...props
|
|
1895
|
-
}) {
|
|
1896
|
-
return /* @__PURE__ */ jsxs8(
|
|
1897
|
-
ScrollAreaPrimitive.Root,
|
|
1898
|
-
{
|
|
1899
|
-
"data-slot": "scroll-area",
|
|
1900
|
-
className: cn("relative", className),
|
|
1901
|
-
...props,
|
|
1902
|
-
children: [
|
|
1903
|
-
/* @__PURE__ */ jsx17(ScrollAreaPrimitive.Viewport, { className: "h-full w-full rounded-[inherit] [&>div]:!block", children }),
|
|
1904
|
-
/* @__PURE__ */ jsx17(ScrollBar, {}),
|
|
1905
|
-
/* @__PURE__ */ jsx17(ScrollAreaPrimitive.Corner, {})
|
|
1906
|
-
]
|
|
1907
|
-
}
|
|
1908
|
-
);
|
|
1909
|
-
}
|
|
1910
|
-
function ScrollBar({
|
|
1911
|
-
className,
|
|
1912
|
-
orientation = "vertical",
|
|
1913
|
-
...props
|
|
1914
|
-
}) {
|
|
1915
|
-
return /* @__PURE__ */ jsx17(
|
|
1916
|
-
ScrollAreaPrimitive.Scrollbar,
|
|
1917
|
-
{
|
|
1918
|
-
"data-slot": "scroll-bar",
|
|
1919
|
-
orientation,
|
|
1920
|
-
className: cn(
|
|
1921
|
-
"flex touch-none p-px transition-colors select-none",
|
|
1922
|
-
orientation === "vertical" && "h-full w-2.5 border-l border-l-transparent",
|
|
1923
|
-
orientation === "horizontal" && "h-2.5 flex-col border-t border-t-transparent",
|
|
1924
|
-
className
|
|
1925
|
-
),
|
|
1926
|
-
...props,
|
|
1927
|
-
children: /* @__PURE__ */ jsx17(ScrollAreaPrimitive.Thumb, { className: "relative flex-1 rounded-full bg-border" })
|
|
1928
|
-
}
|
|
1929
|
-
);
|
|
1930
|
-
}
|
|
1931
|
-
|
|
1932
|
-
// src/components/inbox-sidebar.tsx
|
|
1327
|
+
import { Input, Tabs, TabsList, TabsTrigger, Button as Button3, Skeleton as Skeleton2, ScrollArea } from "@greatapps/greatauth-ui/ui";
|
|
1933
1328
|
import { Search, Plus, Inbox as InboxIcon } from "lucide-react";
|
|
1934
|
-
import { jsx as
|
|
1329
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1935
1330
|
var STATUS_TABS = [
|
|
1936
1331
|
{ value: "all", label: "Todas" },
|
|
1937
1332
|
{ value: "open", label: "Abertas" },
|
|
@@ -1972,13 +1367,13 @@ function InboxSidebar({
|
|
|
1972
1367
|
return new Date(dateB).getTime() - new Date(dateA).getTime();
|
|
1973
1368
|
});
|
|
1974
1369
|
}, [inboxes, statusFilter, search, filterChannelId]);
|
|
1975
|
-
return /* @__PURE__ */
|
|
1370
|
+
return /* @__PURE__ */ jsxs5("div", { className: "flex h-full flex-col", children: [
|
|
1976
1371
|
renderHeader,
|
|
1977
|
-
/* @__PURE__ */
|
|
1978
|
-
/* @__PURE__ */
|
|
1979
|
-
/* @__PURE__ */
|
|
1980
|
-
/* @__PURE__ */
|
|
1981
|
-
/* @__PURE__ */
|
|
1372
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex flex-col gap-3 p-3", children: [
|
|
1373
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between gap-2", children: [
|
|
1374
|
+
/* @__PURE__ */ jsxs5("div", { className: "relative flex-1", children: [
|
|
1375
|
+
/* @__PURE__ */ jsx6(Search, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
1376
|
+
/* @__PURE__ */ jsx6(
|
|
1982
1377
|
Input,
|
|
1983
1378
|
{
|
|
1984
1379
|
placeholder: "Buscar...",
|
|
@@ -1988,17 +1383,17 @@ function InboxSidebar({
|
|
|
1988
1383
|
}
|
|
1989
1384
|
)
|
|
1990
1385
|
] }),
|
|
1991
|
-
onCreateInbox && /* @__PURE__ */
|
|
1992
|
-
|
|
1386
|
+
onCreateInbox && /* @__PURE__ */ jsx6(
|
|
1387
|
+
Button3,
|
|
1993
1388
|
{
|
|
1994
1389
|
size: "icon",
|
|
1995
1390
|
className: "h-8 w-8 shrink-0",
|
|
1996
1391
|
onClick: onCreateInbox,
|
|
1997
|
-
children: /* @__PURE__ */
|
|
1392
|
+
children: /* @__PURE__ */ jsx6(Plus, { className: "h-4 w-4" })
|
|
1998
1393
|
}
|
|
1999
1394
|
)
|
|
2000
1395
|
] }),
|
|
2001
|
-
/* @__PURE__ */
|
|
1396
|
+
/* @__PURE__ */ jsx6(Tabs, { value: statusFilter, onValueChange: setStatusFilter, children: /* @__PURE__ */ jsx6(TabsList, { className: "w-full", children: STATUS_TABS.map((tab) => /* @__PURE__ */ jsx6(
|
|
2002
1397
|
TabsTrigger,
|
|
2003
1398
|
{
|
|
2004
1399
|
value: tab.value,
|
|
@@ -2008,16 +1403,16 @@ function InboxSidebar({
|
|
|
2008
1403
|
tab.value
|
|
2009
1404
|
)) }) })
|
|
2010
1405
|
] }),
|
|
2011
|
-
/* @__PURE__ */
|
|
2012
|
-
/* @__PURE__ */
|
|
2013
|
-
/* @__PURE__ */
|
|
2014
|
-
/* @__PURE__ */
|
|
2015
|
-
/* @__PURE__ */
|
|
1406
|
+
/* @__PURE__ */ jsx6(ScrollArea, { className: "flex-1 px-2", children: isLoading ? /* @__PURE__ */ jsx6("div", { className: "space-y-2 p-2", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-3 p-3", children: [
|
|
1407
|
+
/* @__PURE__ */ jsx6(Skeleton2, { className: "h-10 w-10 rounded-full shrink-0" }),
|
|
1408
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex-1 space-y-1.5", children: [
|
|
1409
|
+
/* @__PURE__ */ jsx6(Skeleton2, { className: "h-4 w-28" }),
|
|
1410
|
+
/* @__PURE__ */ jsx6(Skeleton2, { className: "h-3 w-40" })
|
|
2016
1411
|
] })
|
|
2017
|
-
] }, i)) }) : filtered.length === 0 ? /* @__PURE__ */
|
|
2018
|
-
/* @__PURE__ */
|
|
1412
|
+
] }, i)) }) : filtered.length === 0 ? /* @__PURE__ */ jsxs5("div", { className: "flex flex-col items-center justify-center gap-2 py-8 text-sm text-muted-foreground", children: [
|
|
1413
|
+
/* @__PURE__ */ jsx6(InboxIcon, { className: "h-8 w-8 opacity-50" }),
|
|
2019
1414
|
"Nenhuma conversa encontrada"
|
|
2020
|
-
] }) : filtered.map((inbox) => /* @__PURE__ */
|
|
1415
|
+
] }) : filtered.map((inbox) => /* @__PURE__ */ jsx6(
|
|
2021
1416
|
InboxItem,
|
|
2022
1417
|
{
|
|
2023
1418
|
inbox,
|
|
@@ -2031,31 +1426,8 @@ function InboxSidebar({
|
|
|
2031
1426
|
] });
|
|
2032
1427
|
}
|
|
2033
1428
|
|
|
2034
|
-
// src/components/ui/separator.tsx
|
|
2035
|
-
import { Separator as SeparatorPrimitive } from "radix-ui";
|
|
2036
|
-
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
2037
|
-
function Separator({
|
|
2038
|
-
className,
|
|
2039
|
-
orientation = "horizontal",
|
|
2040
|
-
decorative = true,
|
|
2041
|
-
...props
|
|
2042
|
-
}) {
|
|
2043
|
-
return /* @__PURE__ */ jsx19(
|
|
2044
|
-
SeparatorPrimitive.Root,
|
|
2045
|
-
{
|
|
2046
|
-
"data-slot": "separator",
|
|
2047
|
-
decorative,
|
|
2048
|
-
orientation,
|
|
2049
|
-
className: cn(
|
|
2050
|
-
"shrink-0 bg-border data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
|
|
2051
|
-
className
|
|
2052
|
-
),
|
|
2053
|
-
...props
|
|
2054
|
-
}
|
|
2055
|
-
);
|
|
2056
|
-
}
|
|
2057
|
-
|
|
2058
1429
|
// src/components/contact-info-panel.tsx
|
|
1430
|
+
import { Button as Button4, Skeleton as Skeleton3, Separator, cn as cn4 } from "@greatapps/greatauth-ui/ui";
|
|
2059
1431
|
import {
|
|
2060
1432
|
X,
|
|
2061
1433
|
Phone,
|
|
@@ -2066,18 +1438,18 @@ import {
|
|
|
2066
1438
|
} from "lucide-react";
|
|
2067
1439
|
import { format as format2 } from "date-fns";
|
|
2068
1440
|
import { ptBR as ptBR3 } from "date-fns/locale";
|
|
2069
|
-
import { Fragment as Fragment2, jsx as
|
|
1441
|
+
import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2070
1442
|
function InfoRow({
|
|
2071
1443
|
icon: Icon,
|
|
2072
1444
|
label,
|
|
2073
1445
|
value
|
|
2074
1446
|
}) {
|
|
2075
1447
|
if (!value) return null;
|
|
2076
|
-
return /* @__PURE__ */
|
|
2077
|
-
/* @__PURE__ */
|
|
2078
|
-
/* @__PURE__ */
|
|
2079
|
-
/* @__PURE__ */
|
|
2080
|
-
/* @__PURE__ */
|
|
1448
|
+
return /* @__PURE__ */ jsxs6("div", { className: "flex items-start gap-3 py-2", children: [
|
|
1449
|
+
/* @__PURE__ */ jsx7(Icon, { className: "h-4 w-4 text-muted-foreground mt-0.5 shrink-0" }),
|
|
1450
|
+
/* @__PURE__ */ jsxs6("div", { className: "min-w-0", children: [
|
|
1451
|
+
/* @__PURE__ */ jsx7("p", { className: "text-xs text-muted-foreground", children: label }),
|
|
1452
|
+
/* @__PURE__ */ jsx7("p", { className: "text-sm break-all", children: value })
|
|
2081
1453
|
] })
|
|
2082
1454
|
] });
|
|
2083
1455
|
}
|
|
@@ -2087,40 +1459,40 @@ function ContactInfoPanel({
|
|
|
2087
1459
|
onClose,
|
|
2088
1460
|
className
|
|
2089
1461
|
}) {
|
|
2090
|
-
return /* @__PURE__ */
|
|
1462
|
+
return /* @__PURE__ */ jsxs6(
|
|
2091
1463
|
"div",
|
|
2092
1464
|
{
|
|
2093
|
-
className:
|
|
1465
|
+
className: cn4(
|
|
2094
1466
|
"flex h-full w-[320px] shrink-0 flex-col border-l",
|
|
2095
1467
|
className
|
|
2096
1468
|
),
|
|
2097
1469
|
children: [
|
|
2098
|
-
/* @__PURE__ */
|
|
2099
|
-
/* @__PURE__ */
|
|
2100
|
-
onClose && /* @__PURE__ */
|
|
2101
|
-
|
|
1470
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between border-b px-4 py-3", children: [
|
|
1471
|
+
/* @__PURE__ */ jsx7("span", { className: "text-sm font-medium", children: "Informa\xE7\xF5es do contato" }),
|
|
1472
|
+
onClose && /* @__PURE__ */ jsx7(
|
|
1473
|
+
Button4,
|
|
2102
1474
|
{
|
|
2103
1475
|
variant: "ghost",
|
|
2104
1476
|
size: "icon",
|
|
2105
1477
|
className: "h-7 w-7",
|
|
2106
1478
|
onClick: onClose,
|
|
2107
|
-
children: /* @__PURE__ */
|
|
1479
|
+
children: /* @__PURE__ */ jsx7(X, { className: "h-4 w-4" })
|
|
2108
1480
|
}
|
|
2109
1481
|
)
|
|
2110
1482
|
] }),
|
|
2111
|
-
/* @__PURE__ */
|
|
2112
|
-
/* @__PURE__ */
|
|
2113
|
-
/* @__PURE__ */
|
|
2114
|
-
/* @__PURE__ */
|
|
2115
|
-
] }) : contact ? /* @__PURE__ */
|
|
2116
|
-
/* @__PURE__ */
|
|
2117
|
-
/* @__PURE__ */
|
|
2118
|
-
/* @__PURE__ */
|
|
1483
|
+
/* @__PURE__ */ jsx7("div", { className: "flex-1 overflow-y-auto p-4", children: isLoading ? /* @__PURE__ */ jsxs6("div", { className: "flex flex-col items-center gap-3 pt-4", children: [
|
|
1484
|
+
/* @__PURE__ */ jsx7(Skeleton3, { className: "h-16 w-16 rounded-full" }),
|
|
1485
|
+
/* @__PURE__ */ jsx7(Skeleton3, { className: "h-5 w-32" }),
|
|
1486
|
+
/* @__PURE__ */ jsx7(Skeleton3, { className: "h-4 w-24" })
|
|
1487
|
+
] }) : contact ? /* @__PURE__ */ jsxs6(Fragment2, { children: [
|
|
1488
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex flex-col items-center gap-2 pb-4", children: [
|
|
1489
|
+
/* @__PURE__ */ jsx7(ContactAvatar, { name: contact.name, size: "lg" }),
|
|
1490
|
+
/* @__PURE__ */ jsx7("h3", { className: "text-base font-medium text-center", children: contact.name || "Desconhecido" })
|
|
2119
1491
|
] }),
|
|
2120
|
-
/* @__PURE__ */
|
|
2121
|
-
/* @__PURE__ */
|
|
2122
|
-
/* @__PURE__ */
|
|
2123
|
-
/* @__PURE__ */
|
|
1492
|
+
/* @__PURE__ */ jsx7(Separator, {}),
|
|
1493
|
+
/* @__PURE__ */ jsxs6("div", { className: "mt-3 space-y-1", children: [
|
|
1494
|
+
/* @__PURE__ */ jsx7(InfoRow, { icon: Hash, label: "ID", value: contact.id?.toString() }),
|
|
1495
|
+
/* @__PURE__ */ jsx7(
|
|
2124
1496
|
InfoRow,
|
|
2125
1497
|
{
|
|
2126
1498
|
icon: Phone,
|
|
@@ -2128,7 +1500,7 @@ function ContactInfoPanel({
|
|
|
2128
1500
|
value: contact.phone_number
|
|
2129
1501
|
}
|
|
2130
1502
|
),
|
|
2131
|
-
/* @__PURE__ */
|
|
1503
|
+
/* @__PURE__ */ jsx7(
|
|
2132
1504
|
InfoRow,
|
|
2133
1505
|
{
|
|
2134
1506
|
icon: Fingerprint,
|
|
@@ -2136,7 +1508,7 @@ function ContactInfoPanel({
|
|
|
2136
1508
|
value: contact.identifier
|
|
2137
1509
|
}
|
|
2138
1510
|
),
|
|
2139
|
-
/* @__PURE__ */
|
|
1511
|
+
/* @__PURE__ */ jsx7(
|
|
2140
1512
|
InfoRow,
|
|
2141
1513
|
{
|
|
2142
1514
|
icon: Calendar,
|
|
@@ -2148,7 +1520,7 @@ function ContactInfoPanel({
|
|
|
2148
1520
|
) : null
|
|
2149
1521
|
}
|
|
2150
1522
|
),
|
|
2151
|
-
/* @__PURE__ */
|
|
1523
|
+
/* @__PURE__ */ jsx7(
|
|
2152
1524
|
InfoRow,
|
|
2153
1525
|
{
|
|
2154
1526
|
icon: CalendarClock,
|
|
@@ -2169,214 +1541,28 @@ function ContactInfoPanel({
|
|
|
2169
1541
|
|
|
2170
1542
|
// src/components/new-conversation-dialog.tsx
|
|
2171
1543
|
import { useState as useState5, useCallback, useEffect as useEffect2 } from "react";
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
DialogPrimitive.Overlay,
|
|
2193
|
-
{
|
|
2194
|
-
"data-slot": "dialog-overlay",
|
|
2195
|
-
className: cn(
|
|
2196
|
-
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
2197
|
-
className
|
|
2198
|
-
),
|
|
2199
|
-
...props
|
|
2200
|
-
}
|
|
2201
|
-
);
|
|
2202
|
-
}
|
|
2203
|
-
function DialogContent({
|
|
2204
|
-
className,
|
|
2205
|
-
children,
|
|
2206
|
-
...props
|
|
2207
|
-
}) {
|
|
2208
|
-
return /* @__PURE__ */ jsxs11(DialogPortal, { children: [
|
|
2209
|
-
/* @__PURE__ */ jsx21(DialogOverlay, {}),
|
|
2210
|
-
/* @__PURE__ */ jsxs11(
|
|
2211
|
-
DialogPrimitive.Content,
|
|
2212
|
-
{
|
|
2213
|
-
"data-slot": "dialog-content",
|
|
2214
|
-
className: cn(
|
|
2215
|
-
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
|
|
2216
|
-
className
|
|
2217
|
-
),
|
|
2218
|
-
...props,
|
|
2219
|
-
children: [
|
|
2220
|
-
children,
|
|
2221
|
-
/* @__PURE__ */ jsxs11(DialogPrimitive.Close, { className: "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground", children: [
|
|
2222
|
-
/* @__PURE__ */ jsx21(X2, { className: "h-4 w-4" }),
|
|
2223
|
-
/* @__PURE__ */ jsx21("span", { className: "sr-only", children: "Close" })
|
|
2224
|
-
] })
|
|
2225
|
-
]
|
|
2226
|
-
}
|
|
2227
|
-
)
|
|
2228
|
-
] });
|
|
2229
|
-
}
|
|
2230
|
-
function DialogHeader({ className, ...props }) {
|
|
2231
|
-
return /* @__PURE__ */ jsx21(
|
|
2232
|
-
"div",
|
|
2233
|
-
{
|
|
2234
|
-
"data-slot": "dialog-header",
|
|
2235
|
-
className: cn("flex flex-col gap-2 text-center sm:text-left", className),
|
|
2236
|
-
...props
|
|
2237
|
-
}
|
|
2238
|
-
);
|
|
2239
|
-
}
|
|
2240
|
-
function DialogFooter({ className, ...props }) {
|
|
2241
|
-
return /* @__PURE__ */ jsx21(
|
|
2242
|
-
"div",
|
|
2243
|
-
{
|
|
2244
|
-
"data-slot": "dialog-footer",
|
|
2245
|
-
className: cn(
|
|
2246
|
-
"flex flex-col-reverse sm:flex-row sm:justify-end sm:gap-2",
|
|
2247
|
-
className
|
|
2248
|
-
),
|
|
2249
|
-
...props
|
|
2250
|
-
}
|
|
2251
|
-
);
|
|
2252
|
-
}
|
|
2253
|
-
function DialogTitle({
|
|
2254
|
-
className,
|
|
2255
|
-
...props
|
|
2256
|
-
}) {
|
|
2257
|
-
return /* @__PURE__ */ jsx21(
|
|
2258
|
-
DialogPrimitive.Title,
|
|
2259
|
-
{
|
|
2260
|
-
"data-slot": "dialog-title",
|
|
2261
|
-
className: cn("text-lg font-semibold leading-none tracking-tight", className),
|
|
2262
|
-
...props
|
|
2263
|
-
}
|
|
2264
|
-
);
|
|
2265
|
-
}
|
|
2266
|
-
function DialogDescription({
|
|
2267
|
-
className,
|
|
2268
|
-
...props
|
|
2269
|
-
}) {
|
|
2270
|
-
return /* @__PURE__ */ jsx21(
|
|
2271
|
-
DialogPrimitive.Description,
|
|
2272
|
-
{
|
|
2273
|
-
"data-slot": "dialog-description",
|
|
2274
|
-
className: cn("text-sm text-muted-foreground", className),
|
|
2275
|
-
...props
|
|
2276
|
-
}
|
|
2277
|
-
);
|
|
2278
|
-
}
|
|
2279
|
-
|
|
2280
|
-
// src/components/ui/command.tsx
|
|
2281
|
-
import { Command as CommandPrimitive } from "cmdk";
|
|
2282
|
-
import { Search as Search2 } from "lucide-react";
|
|
2283
|
-
import { jsx as jsx22, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2284
|
-
function Command({
|
|
2285
|
-
className,
|
|
2286
|
-
...props
|
|
2287
|
-
}) {
|
|
2288
|
-
return /* @__PURE__ */ jsx22(
|
|
2289
|
-
CommandPrimitive,
|
|
2290
|
-
{
|
|
2291
|
-
"data-slot": "command",
|
|
2292
|
-
className: cn(
|
|
2293
|
-
"flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
|
|
2294
|
-
className
|
|
2295
|
-
),
|
|
2296
|
-
...props
|
|
2297
|
-
}
|
|
2298
|
-
);
|
|
2299
|
-
}
|
|
2300
|
-
function CommandInput({
|
|
2301
|
-
className,
|
|
2302
|
-
...props
|
|
2303
|
-
}) {
|
|
2304
|
-
return /* @__PURE__ */ jsxs12("div", { className: "flex h-9 items-center gap-2 border-b px-3", "data-slot": "command-input-wrapper", children: [
|
|
2305
|
-
/* @__PURE__ */ jsx22(Search2, { className: "size-4 shrink-0 opacity-50" }),
|
|
2306
|
-
/* @__PURE__ */ jsx22(
|
|
2307
|
-
CommandPrimitive.Input,
|
|
2308
|
-
{
|
|
2309
|
-
"data-slot": "command-input",
|
|
2310
|
-
className: cn(
|
|
2311
|
-
"flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
|
2312
|
-
className
|
|
2313
|
-
),
|
|
2314
|
-
...props
|
|
2315
|
-
}
|
|
2316
|
-
)
|
|
2317
|
-
] });
|
|
2318
|
-
}
|
|
2319
|
-
function CommandList({
|
|
2320
|
-
className,
|
|
2321
|
-
...props
|
|
2322
|
-
}) {
|
|
2323
|
-
return /* @__PURE__ */ jsx22(
|
|
2324
|
-
CommandPrimitive.List,
|
|
2325
|
-
{
|
|
2326
|
-
"data-slot": "command-list",
|
|
2327
|
-
className: cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className),
|
|
2328
|
-
...props
|
|
2329
|
-
}
|
|
2330
|
-
);
|
|
2331
|
-
}
|
|
2332
|
-
function CommandEmpty({
|
|
2333
|
-
...props
|
|
2334
|
-
}) {
|
|
2335
|
-
return /* @__PURE__ */ jsx22(
|
|
2336
|
-
CommandPrimitive.Empty,
|
|
2337
|
-
{
|
|
2338
|
-
"data-slot": "command-empty",
|
|
2339
|
-
className: "py-6 text-center text-sm",
|
|
2340
|
-
...props
|
|
2341
|
-
}
|
|
2342
|
-
);
|
|
2343
|
-
}
|
|
2344
|
-
function CommandGroup({
|
|
2345
|
-
className,
|
|
2346
|
-
...props
|
|
2347
|
-
}) {
|
|
2348
|
-
return /* @__PURE__ */ jsx22(
|
|
2349
|
-
CommandPrimitive.Group,
|
|
2350
|
-
{
|
|
2351
|
-
"data-slot": "command-group",
|
|
2352
|
-
className: cn(
|
|
2353
|
-
"overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",
|
|
2354
|
-
className
|
|
2355
|
-
),
|
|
2356
|
-
...props
|
|
2357
|
-
}
|
|
2358
|
-
);
|
|
2359
|
-
}
|
|
2360
|
-
function CommandItem({
|
|
2361
|
-
className,
|
|
2362
|
-
...props
|
|
2363
|
-
}) {
|
|
2364
|
-
return /* @__PURE__ */ jsx22(
|
|
2365
|
-
CommandPrimitive.Item,
|
|
2366
|
-
{
|
|
2367
|
-
"data-slot": "command-item",
|
|
2368
|
-
className: cn(
|
|
2369
|
-
"relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none select-none data-[disabled=true]:pointer-events-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
2370
|
-
className
|
|
2371
|
-
),
|
|
2372
|
-
...props
|
|
2373
|
-
}
|
|
2374
|
-
);
|
|
2375
|
-
}
|
|
2376
|
-
|
|
2377
|
-
// src/components/new-conversation-dialog.tsx
|
|
1544
|
+
import {
|
|
1545
|
+
Dialog,
|
|
1546
|
+
DialogContent,
|
|
1547
|
+
DialogHeader,
|
|
1548
|
+
DialogTitle,
|
|
1549
|
+
DialogDescription,
|
|
1550
|
+
DialogFooter,
|
|
1551
|
+
Command,
|
|
1552
|
+
CommandInput,
|
|
1553
|
+
CommandList,
|
|
1554
|
+
CommandEmpty,
|
|
1555
|
+
CommandGroup,
|
|
1556
|
+
CommandItem,
|
|
1557
|
+
Select as Select2,
|
|
1558
|
+
SelectContent as SelectContent2,
|
|
1559
|
+
SelectItem as SelectItem2,
|
|
1560
|
+
SelectTrigger as SelectTrigger2,
|
|
1561
|
+
SelectValue as SelectValue2,
|
|
1562
|
+
Button as Button5
|
|
1563
|
+
} from "@greatapps/greatauth-ui/ui";
|
|
2378
1564
|
import { Loader2 } from "lucide-react";
|
|
2379
|
-
import { jsx as
|
|
1565
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2380
1566
|
function NewConversationDialog({
|
|
2381
1567
|
open,
|
|
2382
1568
|
onOpenChange,
|
|
@@ -2419,27 +1605,27 @@ function NewConversationDialog({
|
|
|
2419
1605
|
onCreated,
|
|
2420
1606
|
onOpenChange
|
|
2421
1607
|
]);
|
|
2422
|
-
return /* @__PURE__ */
|
|
2423
|
-
/* @__PURE__ */
|
|
2424
|
-
/* @__PURE__ */
|
|
2425
|
-
/* @__PURE__ */
|
|
1608
|
+
return /* @__PURE__ */ jsx8(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs7(DialogContent, { className: "sm:max-w-md p-0 gap-0", children: [
|
|
1609
|
+
/* @__PURE__ */ jsxs7(DialogHeader, { className: "px-4 pt-4 pb-2", children: [
|
|
1610
|
+
/* @__PURE__ */ jsx8(DialogTitle, { children: "Nova conversa" }),
|
|
1611
|
+
/* @__PURE__ */ jsx8(DialogDescription, { children: "Selecione um contato para iniciar uma conversa" })
|
|
2426
1612
|
] }),
|
|
2427
|
-
channels.length > 1 && /* @__PURE__ */
|
|
2428
|
-
|
|
1613
|
+
channels.length > 1 && /* @__PURE__ */ jsx8("div", { className: "px-4 pb-2", children: /* @__PURE__ */ jsxs7(
|
|
1614
|
+
Select2,
|
|
2429
1615
|
{
|
|
2430
1616
|
value: selectedChannelId?.toString() ?? "",
|
|
2431
1617
|
onValueChange: (v) => setSelectedChannelId(Number(v)),
|
|
2432
1618
|
children: [
|
|
2433
|
-
/* @__PURE__ */
|
|
2434
|
-
/* @__PURE__ */
|
|
1619
|
+
/* @__PURE__ */ jsx8(SelectTrigger2, { className: "h-9", children: /* @__PURE__ */ jsx8(SelectValue2, { placeholder: "Selecione um canal" }) }),
|
|
1620
|
+
/* @__PURE__ */ jsx8(SelectContent2, { children: channels.map((ch) => /* @__PURE__ */ jsx8(SelectItem2, { value: ch.id.toString(), children: ch.name }, ch.id)) })
|
|
2435
1621
|
]
|
|
2436
1622
|
}
|
|
2437
1623
|
) }),
|
|
2438
|
-
/* @__PURE__ */
|
|
2439
|
-
/* @__PURE__ */
|
|
2440
|
-
/* @__PURE__ */
|
|
2441
|
-
/* @__PURE__ */
|
|
2442
|
-
/* @__PURE__ */
|
|
1624
|
+
/* @__PURE__ */ jsxs7(Command, { className: "rounded-none border-none shadow-none", children: [
|
|
1625
|
+
/* @__PURE__ */ jsx8("div", { className: "px-2", children: /* @__PURE__ */ jsx8(CommandInput, { placeholder: "Buscar contato..." }) }),
|
|
1626
|
+
/* @__PURE__ */ jsxs7(CommandList, { className: "max-h-64 px-2", children: [
|
|
1627
|
+
/* @__PURE__ */ jsx8(CommandEmpty, { children: "Nenhum contato encontrado" }),
|
|
1628
|
+
/* @__PURE__ */ jsx8(CommandGroup, { children: contacts.map((contact) => /* @__PURE__ */ jsxs7(
|
|
2443
1629
|
CommandItem,
|
|
2444
1630
|
{
|
|
2445
1631
|
value: `${contact.name} ${contact.phone_number || ""}`,
|
|
@@ -2447,10 +1633,10 @@ function NewConversationDialog({
|
|
|
2447
1633
|
"data-checked": selectedContact?.id === contact.id,
|
|
2448
1634
|
className: "gap-3",
|
|
2449
1635
|
children: [
|
|
2450
|
-
/* @__PURE__ */
|
|
2451
|
-
/* @__PURE__ */
|
|
2452
|
-
/* @__PURE__ */
|
|
2453
|
-
/* @__PURE__ */
|
|
1636
|
+
/* @__PURE__ */ jsx8(ContactAvatar, { name: contact.name, size: "sm" }),
|
|
1637
|
+
/* @__PURE__ */ jsxs7("div", { className: "min-w-0 flex-1", children: [
|
|
1638
|
+
/* @__PURE__ */ jsx8("p", { className: "truncate text-sm font-medium", children: contact.name }),
|
|
1639
|
+
/* @__PURE__ */ jsx8("p", { className: "truncate text-xs text-muted-foreground", children: contact.phone_number || contact.identifier || "Sem telefone" })
|
|
2454
1640
|
] })
|
|
2455
1641
|
]
|
|
2456
1642
|
},
|
|
@@ -2458,15 +1644,15 @@ function NewConversationDialog({
|
|
|
2458
1644
|
)) })
|
|
2459
1645
|
] })
|
|
2460
1646
|
] }),
|
|
2461
|
-
/* @__PURE__ */
|
|
2462
|
-
/* @__PURE__ */
|
|
2463
|
-
/* @__PURE__ */
|
|
2464
|
-
|
|
1647
|
+
/* @__PURE__ */ jsxs7(DialogFooter, { className: "px-4 py-3 border-t", children: [
|
|
1648
|
+
/* @__PURE__ */ jsx8(Button5, { variant: "outline", onClick: () => onOpenChange(false), children: "Cancelar" }),
|
|
1649
|
+
/* @__PURE__ */ jsxs7(
|
|
1650
|
+
Button5,
|
|
2465
1651
|
{
|
|
2466
1652
|
disabled: !selectedContact || !effectiveChannelId || isCreating,
|
|
2467
1653
|
onClick: handleCreate,
|
|
2468
1654
|
children: [
|
|
2469
|
-
isCreating && /* @__PURE__ */
|
|
1655
|
+
isCreating && /* @__PURE__ */ jsx8(Loader2, { className: "h-4 w-4 animate-spin" }),
|
|
2470
1656
|
"Iniciar conversa"
|
|
2471
1657
|
]
|
|
2472
1658
|
}
|
|
@@ -2476,20 +1662,21 @@ function NewConversationDialog({
|
|
|
2476
1662
|
}
|
|
2477
1663
|
|
|
2478
1664
|
// src/components/whatsapp-status-badge.tsx
|
|
2479
|
-
import {
|
|
1665
|
+
import { Badge as Badge2 } from "@greatapps/greatauth-ui/ui";
|
|
1666
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
2480
1667
|
function WhatsappStatusBadge({
|
|
2481
1668
|
status,
|
|
2482
1669
|
hasSession
|
|
2483
1670
|
}) {
|
|
2484
1671
|
if (!hasSession) {
|
|
2485
|
-
return /* @__PURE__ */
|
|
1672
|
+
return /* @__PURE__ */ jsx9(Badge2, { variant: "outline", className: "text-xs text-zinc-500 border-zinc-300", children: "Sem sess\xE3o" });
|
|
2486
1673
|
}
|
|
2487
1674
|
if (!status) {
|
|
2488
|
-
return /* @__PURE__ */
|
|
1675
|
+
return /* @__PURE__ */ jsx9(Badge2, { variant: "outline", className: "text-xs text-zinc-500 border-zinc-300", children: "Verificando..." });
|
|
2489
1676
|
}
|
|
2490
1677
|
if (status.connected && status.logged_in) {
|
|
2491
|
-
return /* @__PURE__ */
|
|
2492
|
-
|
|
1678
|
+
return /* @__PURE__ */ jsx9(
|
|
1679
|
+
Badge2,
|
|
2493
1680
|
{
|
|
2494
1681
|
variant: "outline",
|
|
2495
1682
|
className: "text-xs bg-green-500/10 text-green-600 border-green-200",
|
|
@@ -2498,8 +1685,8 @@ function WhatsappStatusBadge({
|
|
|
2498
1685
|
);
|
|
2499
1686
|
}
|
|
2500
1687
|
if (status.connected && !status.logged_in) {
|
|
2501
|
-
return /* @__PURE__ */
|
|
2502
|
-
|
|
1688
|
+
return /* @__PURE__ */ jsx9(
|
|
1689
|
+
Badge2,
|
|
2503
1690
|
{
|
|
2504
1691
|
variant: "outline",
|
|
2505
1692
|
className: "text-xs bg-yellow-500/10 text-yellow-600 border-yellow-200",
|
|
@@ -2508,8 +1695,8 @@ function WhatsappStatusBadge({
|
|
|
2508
1695
|
);
|
|
2509
1696
|
}
|
|
2510
1697
|
if (status.logged_in && !status.connected) {
|
|
2511
|
-
return /* @__PURE__ */
|
|
2512
|
-
|
|
1698
|
+
return /* @__PURE__ */ jsx9(
|
|
1699
|
+
Badge2,
|
|
2513
1700
|
{
|
|
2514
1701
|
variant: "outline",
|
|
2515
1702
|
className: "text-xs bg-yellow-500/10 text-yellow-600 border-yellow-200",
|
|
@@ -2517,8 +1704,8 @@ function WhatsappStatusBadge({
|
|
|
2517
1704
|
}
|
|
2518
1705
|
);
|
|
2519
1706
|
}
|
|
2520
|
-
return /* @__PURE__ */
|
|
2521
|
-
|
|
1707
|
+
return /* @__PURE__ */ jsx9(
|
|
1708
|
+
Badge2,
|
|
2522
1709
|
{
|
|
2523
1710
|
variant: "outline",
|
|
2524
1711
|
className: "text-xs bg-red-500/10 text-red-600 border-red-200",
|
|
@@ -2528,7 +1715,8 @@ function WhatsappStatusBadge({
|
|
|
2528
1715
|
}
|
|
2529
1716
|
|
|
2530
1717
|
// src/components/channel-card.tsx
|
|
2531
|
-
import {
|
|
1718
|
+
import { Button as Button6 } from "@greatapps/greatauth-ui/ui";
|
|
1719
|
+
import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2532
1720
|
function ChannelCard({
|
|
2533
1721
|
channel,
|
|
2534
1722
|
config,
|
|
@@ -2540,82 +1728,1565 @@ function ChannelCard({
|
|
|
2540
1728
|
}) {
|
|
2541
1729
|
const { data: status } = useChannelWhatsappStatus(config, channel.id);
|
|
2542
1730
|
const hasSession = !!channel.external_id;
|
|
2543
|
-
return /* @__PURE__ */
|
|
2544
|
-
/* @__PURE__ */
|
|
2545
|
-
/* @__PURE__ */
|
|
2546
|
-
/* @__PURE__ */
|
|
2547
|
-
/* @__PURE__ */
|
|
2548
|
-
/* @__PURE__ */
|
|
2549
|
-
/* @__PURE__ */
|
|
1731
|
+
return /* @__PURE__ */ jsxs8("div", { className: "rounded-lg border bg-card text-card-foreground shadow-sm", children: [
|
|
1732
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex flex-row items-start justify-between p-4 pb-2", children: [
|
|
1733
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
|
|
1734
|
+
/* @__PURE__ */ jsx10("div", { className: "flex h-9 w-9 items-center justify-center rounded-md bg-green-500/10", children: /* @__PURE__ */ jsx10("svg", { className: "h-5 w-5 text-green-600", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx10("path", { d: "M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z" }) }) }),
|
|
1735
|
+
/* @__PURE__ */ jsxs8("div", { children: [
|
|
1736
|
+
/* @__PURE__ */ jsx10("h3", { className: "text-sm font-medium", children: channel.name }),
|
|
1737
|
+
/* @__PURE__ */ jsx10("p", { className: "text-xs text-muted-foreground", children: channel.identifier || "Sem n\xFAmero" })
|
|
2550
1738
|
] })
|
|
2551
1739
|
] }),
|
|
2552
|
-
/* @__PURE__ */
|
|
2553
|
-
onEdit && /* @__PURE__ */
|
|
2554
|
-
|
|
1740
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-1", children: [
|
|
1741
|
+
onEdit && /* @__PURE__ */ jsx10(
|
|
1742
|
+
Button6,
|
|
2555
1743
|
{
|
|
2556
1744
|
variant: "ghost",
|
|
2557
1745
|
size: "icon",
|
|
2558
1746
|
className: "h-7 w-7",
|
|
2559
1747
|
onClick: onEdit,
|
|
2560
|
-
children: /* @__PURE__ */
|
|
2561
|
-
/* @__PURE__ */
|
|
2562
|
-
/* @__PURE__ */
|
|
1748
|
+
children: /* @__PURE__ */ jsxs8("svg", { className: "h-3.5 w-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1749
|
+
/* @__PURE__ */ jsx10("path", { d: "M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z" }),
|
|
1750
|
+
/* @__PURE__ */ jsx10("path", { d: "m15 5 4 4" })
|
|
2563
1751
|
] })
|
|
2564
1752
|
}
|
|
2565
1753
|
),
|
|
2566
|
-
onDelete && /* @__PURE__ */
|
|
2567
|
-
|
|
1754
|
+
onDelete && /* @__PURE__ */ jsx10(
|
|
1755
|
+
Button6,
|
|
2568
1756
|
{
|
|
2569
1757
|
variant: "ghost",
|
|
2570
1758
|
size: "icon",
|
|
2571
1759
|
className: "h-7 w-7 text-destructive hover:text-destructive",
|
|
2572
1760
|
onClick: onDelete,
|
|
2573
|
-
children: /* @__PURE__ */
|
|
2574
|
-
/* @__PURE__ */
|
|
2575
|
-
/* @__PURE__ */
|
|
2576
|
-
/* @__PURE__ */
|
|
1761
|
+
children: /* @__PURE__ */ jsxs8("svg", { className: "h-3.5 w-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1762
|
+
/* @__PURE__ */ jsx10("path", { d: "M3 6h18" }),
|
|
1763
|
+
/* @__PURE__ */ jsx10("path", { d: "M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6" }),
|
|
1764
|
+
/* @__PURE__ */ jsx10("path", { d: "M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2" })
|
|
2577
1765
|
] })
|
|
2578
1766
|
}
|
|
2579
1767
|
),
|
|
2580
|
-
/* @__PURE__ */
|
|
1768
|
+
/* @__PURE__ */ jsx10(WhatsappStatusBadge, { status, hasSession })
|
|
2581
1769
|
] })
|
|
2582
1770
|
] }),
|
|
2583
|
-
/* @__PURE__ */
|
|
2584
|
-
linkedAgentName && /* @__PURE__ */
|
|
2585
|
-
/* @__PURE__ */
|
|
2586
|
-
/* @__PURE__ */
|
|
2587
|
-
/* @__PURE__ */
|
|
2588
|
-
/* @__PURE__ */
|
|
2589
|
-
/* @__PURE__ */
|
|
2590
|
-
/* @__PURE__ */
|
|
2591
|
-
/* @__PURE__ */
|
|
1771
|
+
/* @__PURE__ */ jsxs8("div", { className: "p-4 pt-0 space-y-3", children: [
|
|
1772
|
+
linkedAgentName && /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-1.5 text-xs text-muted-foreground", children: [
|
|
1773
|
+
/* @__PURE__ */ jsxs8("svg", { className: "h-3.5 w-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1774
|
+
/* @__PURE__ */ jsx10("path", { d: "M12 8V4H8" }),
|
|
1775
|
+
/* @__PURE__ */ jsx10("rect", { width: "16", height: "12", x: "4", y: "8", rx: "2" }),
|
|
1776
|
+
/* @__PURE__ */ jsx10("path", { d: "M2 14h2" }),
|
|
1777
|
+
/* @__PURE__ */ jsx10("path", { d: "M20 14h2" }),
|
|
1778
|
+
/* @__PURE__ */ jsx10("path", { d: "M15 13v2" }),
|
|
1779
|
+
/* @__PURE__ */ jsx10("path", { d: "M9 13v2" })
|
|
2592
1780
|
] }),
|
|
2593
|
-
/* @__PURE__ */
|
|
1781
|
+
/* @__PURE__ */ jsxs8("span", { children: [
|
|
2594
1782
|
"Agent: ",
|
|
2595
|
-
/* @__PURE__ */
|
|
1783
|
+
/* @__PURE__ */ jsx10("strong", { children: linkedAgentName })
|
|
2596
1784
|
] }),
|
|
2597
|
-
!linkedAgentActive && /* @__PURE__ */
|
|
1785
|
+
!linkedAgentActive && /* @__PURE__ */ jsx10("span", { className: "text-[10px] px-1 py-0 border rounded", children: "inativo" })
|
|
2598
1786
|
] }),
|
|
2599
1787
|
actions
|
|
2600
1788
|
] })
|
|
2601
1789
|
] });
|
|
2602
1790
|
}
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
1791
|
+
|
|
1792
|
+
// src/components/whatsapp-icon.tsx
|
|
1793
|
+
import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1794
|
+
function WhatsappIcon(props) {
|
|
1795
|
+
return /* @__PURE__ */ jsxs9(
|
|
1796
|
+
"svg",
|
|
1797
|
+
{
|
|
1798
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1799
|
+
width: "24",
|
|
1800
|
+
height: "24",
|
|
1801
|
+
viewBox: "0 0 24 24",
|
|
1802
|
+
fill: "none",
|
|
1803
|
+
stroke: "currentColor",
|
|
1804
|
+
strokeWidth: 2,
|
|
1805
|
+
strokeLinecap: "round",
|
|
1806
|
+
strokeLinejoin: "round",
|
|
1807
|
+
...props,
|
|
1808
|
+
children: [
|
|
1809
|
+
/* @__PURE__ */ jsx11("path", { d: "M3 21l1.65 -3.8a9 9 0 1 1 3.4 2.9l-5.05 .9" }),
|
|
1810
|
+
/* @__PURE__ */ jsx11("path", { d: "M9 10a.5 .5 0 0 0 1 0v-1a.5 .5 0 0 0 -1 0v1a5 5 0 0 0 5 5h1a.5 .5 0 0 0 0 -1h-1a.5 .5 0 0 0 0 1" })
|
|
1811
|
+
]
|
|
1812
|
+
}
|
|
1813
|
+
);
|
|
1814
|
+
}
|
|
1815
|
+
|
|
1816
|
+
// src/components/whatsapp-qr-dialog.tsx
|
|
1817
|
+
import { useEffect as useEffect3, useState as useState6, useCallback as useCallback2 } from "react";
|
|
1818
|
+
import {
|
|
1819
|
+
Dialog as Dialog2,
|
|
1820
|
+
DialogContent as DialogContent2,
|
|
1821
|
+
DialogHeader as DialogHeader2,
|
|
1822
|
+
DialogTitle as DialogTitle2,
|
|
1823
|
+
DialogDescription as DialogDescription2,
|
|
1824
|
+
Button as Button7
|
|
1825
|
+
} from "@greatapps/greatauth-ui/ui";
|
|
1826
|
+
import { Loader2 as Loader22, Check as Check2, AlertCircle as AlertCircle2, RefreshCw } from "lucide-react";
|
|
1827
|
+
import { toast } from "sonner";
|
|
1828
|
+
import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1829
|
+
function WhatsappQrDialog({
|
|
1830
|
+
open,
|
|
1831
|
+
onOpenChange,
|
|
1832
|
+
channelId,
|
|
1833
|
+
config
|
|
1834
|
+
}) {
|
|
1835
|
+
const connectChannel = useConnectChannel(config);
|
|
1836
|
+
const [state, setState] = useState6("connecting");
|
|
1837
|
+
const [errorMsg, setErrorMsg] = useState6("");
|
|
1838
|
+
const { data: qrUrl } = useChannelQR(
|
|
1839
|
+
config,
|
|
1840
|
+
channelId,
|
|
1841
|
+
open && (state === "waiting_qr" || state === "showing_qr")
|
|
1842
|
+
);
|
|
1843
|
+
const { data: status } = useChannelWhatsappStatus(
|
|
1844
|
+
config,
|
|
1845
|
+
channelId,
|
|
1846
|
+
open && state !== "connected"
|
|
1847
|
+
);
|
|
1848
|
+
const startConnect = useCallback2(() => {
|
|
1849
|
+
setState("connecting");
|
|
1850
|
+
setErrorMsg("");
|
|
1851
|
+
connectChannel.mutate(channelId, {
|
|
1852
|
+
onSuccess: () => setState("waiting_qr"),
|
|
1853
|
+
onError: (err) => {
|
|
1854
|
+
setState("error");
|
|
1855
|
+
setErrorMsg(err.message || "Erro ao conectar");
|
|
1856
|
+
}
|
|
1857
|
+
});
|
|
1858
|
+
}, [channelId, connectChannel]);
|
|
1859
|
+
useEffect3(() => {
|
|
1860
|
+
if (!open) {
|
|
1861
|
+
setState("connecting");
|
|
1862
|
+
setErrorMsg("");
|
|
1863
|
+
return;
|
|
1864
|
+
}
|
|
1865
|
+
startConnect();
|
|
1866
|
+
}, [open, channelId]);
|
|
1867
|
+
useEffect3(() => {
|
|
1868
|
+
if (qrUrl && (state === "waiting_qr" || state === "showing_qr")) {
|
|
1869
|
+
setState("showing_qr");
|
|
1870
|
+
}
|
|
1871
|
+
}, [qrUrl, state]);
|
|
1872
|
+
useEffect3(() => {
|
|
1873
|
+
if (status?.connected && status?.logged_in) {
|
|
1874
|
+
setState("connected");
|
|
1875
|
+
toast.success("WhatsApp conectado com sucesso!");
|
|
1876
|
+
setTimeout(() => onOpenChange(false), 1500);
|
|
1877
|
+
}
|
|
1878
|
+
}, [status, onOpenChange]);
|
|
1879
|
+
return /* @__PURE__ */ jsx12(Dialog2, { open, onOpenChange, children: /* @__PURE__ */ jsxs10(DialogContent2, { className: "sm:max-w-md", children: [
|
|
1880
|
+
/* @__PURE__ */ jsxs10(DialogHeader2, { children: [
|
|
1881
|
+
/* @__PURE__ */ jsx12(DialogTitle2, { children: "Conectar WhatsApp" }),
|
|
1882
|
+
/* @__PURE__ */ jsx12(DialogDescription2, { children: "Escaneie o QR code com seu WhatsApp para conectar" })
|
|
1883
|
+
] }),
|
|
1884
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex min-h-[300px] items-center justify-center", children: [
|
|
1885
|
+
state === "connecting" && /* @__PURE__ */ jsxs10("div", { className: "flex flex-col items-center gap-3 text-muted-foreground", children: [
|
|
1886
|
+
/* @__PURE__ */ jsx12(Loader22, { className: "h-8 w-8 animate-spin" }),
|
|
1887
|
+
/* @__PURE__ */ jsx12("p", { className: "text-sm", children: "Iniciando conex\xE3o..." })
|
|
1888
|
+
] }),
|
|
1889
|
+
state === "waiting_qr" && /* @__PURE__ */ jsxs10("div", { className: "flex flex-col items-center gap-3 text-muted-foreground", children: [
|
|
1890
|
+
/* @__PURE__ */ jsx12(Loader22, { className: "h-8 w-8 animate-spin" }),
|
|
1891
|
+
/* @__PURE__ */ jsx12("p", { className: "text-sm", children: "Gerando QR code..." })
|
|
1892
|
+
] }),
|
|
1893
|
+
state === "showing_qr" && qrUrl && /* @__PURE__ */ jsxs10("div", { className: "flex flex-col items-center gap-3", children: [
|
|
1894
|
+
/* @__PURE__ */ jsx12(
|
|
1895
|
+
"img",
|
|
1896
|
+
{
|
|
1897
|
+
src: qrUrl,
|
|
1898
|
+
alt: "QR Code WhatsApp",
|
|
1899
|
+
className: "h-64 w-64 rounded-lg border"
|
|
1900
|
+
}
|
|
1901
|
+
),
|
|
1902
|
+
/* @__PURE__ */ jsx12("p", { className: "text-sm text-muted-foreground", children: "Abra o WhatsApp > Aparelhos conectados > Conectar" })
|
|
1903
|
+
] }),
|
|
1904
|
+
state === "connected" && /* @__PURE__ */ jsxs10("div", { className: "flex flex-col items-center gap-3 text-green-600", children: [
|
|
1905
|
+
/* @__PURE__ */ jsx12(Check2, { className: "h-12 w-12" }),
|
|
1906
|
+
/* @__PURE__ */ jsx12("p", { className: "text-lg font-medium", children: "Conectado!" })
|
|
1907
|
+
] }),
|
|
1908
|
+
state === "error" && /* @__PURE__ */ jsxs10("div", { className: "flex flex-col items-center gap-3 text-destructive", children: [
|
|
1909
|
+
/* @__PURE__ */ jsx12(AlertCircle2, { className: "h-8 w-8" }),
|
|
1910
|
+
/* @__PURE__ */ jsx12("p", { className: "text-sm", children: errorMsg || "Erro ao gerar QR code" }),
|
|
1911
|
+
/* @__PURE__ */ jsxs10(
|
|
1912
|
+
Button7,
|
|
1913
|
+
{
|
|
1914
|
+
variant: "outline",
|
|
1915
|
+
size: "sm",
|
|
1916
|
+
onClick: startConnect,
|
|
1917
|
+
children: [
|
|
1918
|
+
/* @__PURE__ */ jsx12(RefreshCw, { className: "mr-2 h-4 w-4" }),
|
|
1919
|
+
"Tentar novamente"
|
|
1920
|
+
]
|
|
1921
|
+
}
|
|
1922
|
+
)
|
|
1923
|
+
] })
|
|
1924
|
+
] })
|
|
1925
|
+
] }) });
|
|
1926
|
+
}
|
|
1927
|
+
|
|
1928
|
+
// src/components/channel-create-dialog.tsx
|
|
1929
|
+
import { useState as useState7 } from "react";
|
|
1930
|
+
import {
|
|
1931
|
+
Dialog as Dialog3,
|
|
1932
|
+
DialogContent as DialogContent3,
|
|
1933
|
+
DialogHeader as DialogHeader3,
|
|
1934
|
+
DialogTitle as DialogTitle3,
|
|
1935
|
+
DialogFooter as DialogFooter2,
|
|
1936
|
+
Button as Button8,
|
|
1937
|
+
Input as Input2,
|
|
1938
|
+
Label
|
|
1939
|
+
} from "@greatapps/greatauth-ui/ui";
|
|
1940
|
+
import { Loader2 as Loader23 } from "lucide-react";
|
|
1941
|
+
import { toast as toast2 } from "sonner";
|
|
1942
|
+
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1943
|
+
function ChannelCreateDialog({
|
|
1944
|
+
open,
|
|
1945
|
+
onOpenChange,
|
|
1946
|
+
config,
|
|
1947
|
+
renderAgentSelect
|
|
1948
|
+
}) {
|
|
1949
|
+
const createChannel = useCreateChannel(config);
|
|
1950
|
+
const [name, setName] = useState7("");
|
|
1951
|
+
const [identifier, setIdentifier] = useState7("");
|
|
1952
|
+
const [idAgent, setIdAgent] = useState7(null);
|
|
1953
|
+
async function handleSubmit(e) {
|
|
1954
|
+
e.preventDefault();
|
|
1955
|
+
if (!name.trim()) return;
|
|
1956
|
+
try {
|
|
1957
|
+
await createChannel.mutateAsync({
|
|
1958
|
+
name: name.trim(),
|
|
1959
|
+
type: "whatsapp_unofficial",
|
|
1960
|
+
provider: "gwhatsmeow",
|
|
1961
|
+
identifier: identifier.trim() || void 0,
|
|
1962
|
+
id_agent: idAgent
|
|
1963
|
+
});
|
|
1964
|
+
toast2.success("Canal criado! Agora conecte via QR code.");
|
|
1965
|
+
setName("");
|
|
1966
|
+
setIdentifier("");
|
|
1967
|
+
setIdAgent(null);
|
|
1968
|
+
onOpenChange(false);
|
|
1969
|
+
} catch {
|
|
1970
|
+
toast2.error("Erro ao criar canal");
|
|
1971
|
+
}
|
|
1972
|
+
}
|
|
1973
|
+
return /* @__PURE__ */ jsx13(Dialog3, { open, onOpenChange, children: /* @__PURE__ */ jsxs11(DialogContent3, { children: [
|
|
1974
|
+
/* @__PURE__ */ jsx13(DialogHeader3, { children: /* @__PURE__ */ jsxs11(DialogTitle3, { className: "flex items-center gap-2", children: [
|
|
1975
|
+
/* @__PURE__ */ jsx13(WhatsappIcon, { className: "h-5 w-5 text-green-600" }),
|
|
1976
|
+
"Novo Canal WhatsApp"
|
|
1977
|
+
] }) }),
|
|
1978
|
+
/* @__PURE__ */ jsxs11("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
|
|
1979
|
+
/* @__PURE__ */ jsxs11("div", { className: "space-y-2", children: [
|
|
1980
|
+
/* @__PURE__ */ jsx13(Label, { htmlFor: "channel-name", children: "Nome do canal *" }),
|
|
1981
|
+
/* @__PURE__ */ jsx13(
|
|
1982
|
+
Input2,
|
|
1983
|
+
{
|
|
1984
|
+
id: "channel-name",
|
|
1985
|
+
value: name,
|
|
1986
|
+
onChange: (e) => setName(e.target.value),
|
|
1987
|
+
placeholder: "Ex: WhatsApp Principal",
|
|
1988
|
+
required: true,
|
|
1989
|
+
disabled: createChannel.isPending
|
|
1990
|
+
}
|
|
1991
|
+
)
|
|
1992
|
+
] }),
|
|
1993
|
+
/* @__PURE__ */ jsxs11("div", { className: "space-y-2", children: [
|
|
1994
|
+
/* @__PURE__ */ jsx13(Label, { htmlFor: "channel-identifier", children: "N\xFAmero do WhatsApp (opcional)" }),
|
|
1995
|
+
/* @__PURE__ */ jsx13(
|
|
1996
|
+
Input2,
|
|
1997
|
+
{
|
|
1998
|
+
id: "channel-identifier",
|
|
1999
|
+
value: identifier,
|
|
2000
|
+
onChange: (e) => setIdentifier(e.target.value),
|
|
2001
|
+
placeholder: "5511999999999",
|
|
2002
|
+
disabled: createChannel.isPending
|
|
2003
|
+
}
|
|
2004
|
+
),
|
|
2005
|
+
/* @__PURE__ */ jsx13("p", { className: "text-xs text-muted-foreground", children: "Ser\xE1 detectado automaticamente ao escanear o QR code" })
|
|
2006
|
+
] }),
|
|
2007
|
+
renderAgentSelect?.({
|
|
2008
|
+
value: idAgent,
|
|
2009
|
+
onChange: setIdAgent,
|
|
2010
|
+
disabled: createChannel.isPending
|
|
2011
|
+
}),
|
|
2012
|
+
/* @__PURE__ */ jsxs11(DialogFooter2, { children: [
|
|
2013
|
+
/* @__PURE__ */ jsx13(
|
|
2014
|
+
Button8,
|
|
2015
|
+
{
|
|
2016
|
+
type: "button",
|
|
2017
|
+
variant: "outline",
|
|
2018
|
+
onClick: () => onOpenChange(false),
|
|
2019
|
+
disabled: createChannel.isPending,
|
|
2020
|
+
children: "Cancelar"
|
|
2021
|
+
}
|
|
2022
|
+
),
|
|
2023
|
+
/* @__PURE__ */ jsxs11(Button8, { type: "submit", disabled: createChannel.isPending || !name.trim(), children: [
|
|
2024
|
+
createChannel.isPending && /* @__PURE__ */ jsx13(Loader23, { className: "mr-2 h-4 w-4 animate-spin" }),
|
|
2025
|
+
"Criar Canal"
|
|
2026
|
+
] })
|
|
2027
|
+
] })
|
|
2028
|
+
] })
|
|
2029
|
+
] }) });
|
|
2030
|
+
}
|
|
2031
|
+
|
|
2032
|
+
// src/components/channel-edit-dialog.tsx
|
|
2033
|
+
import { useState as useState8, useEffect as useEffect4 } from "react";
|
|
2034
|
+
import {
|
|
2035
|
+
Dialog as Dialog4,
|
|
2036
|
+
DialogContent as DialogContent4,
|
|
2037
|
+
DialogHeader as DialogHeader4,
|
|
2038
|
+
DialogTitle as DialogTitle4,
|
|
2039
|
+
DialogFooter as DialogFooter3,
|
|
2040
|
+
Button as Button9,
|
|
2041
|
+
Input as Input3,
|
|
2042
|
+
Label as Label2
|
|
2043
|
+
} from "@greatapps/greatauth-ui/ui";
|
|
2044
|
+
import { Loader2 as Loader24 } from "lucide-react";
|
|
2045
|
+
import { toast as toast3 } from "sonner";
|
|
2046
|
+
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2047
|
+
function ChannelEditDialog({
|
|
2048
|
+
open,
|
|
2049
|
+
onOpenChange,
|
|
2050
|
+
channel,
|
|
2051
|
+
config,
|
|
2052
|
+
renderAgentSelect
|
|
2053
|
+
}) {
|
|
2054
|
+
const updateChannel = useUpdateChannel(config);
|
|
2055
|
+
const [name, setName] = useState8(channel.name);
|
|
2056
|
+
const [identifier, setIdentifier] = useState8(channel.identifier || "");
|
|
2057
|
+
const [idAgent, setIdAgent] = useState8(channel.id_agent);
|
|
2058
|
+
useEffect4(() => {
|
|
2059
|
+
if (open) {
|
|
2060
|
+
setName(channel.name);
|
|
2061
|
+
setIdentifier(channel.identifier || "");
|
|
2062
|
+
setIdAgent(channel.id_agent);
|
|
2063
|
+
}
|
|
2064
|
+
}, [open, channel]);
|
|
2065
|
+
async function handleSubmit(e) {
|
|
2066
|
+
e.preventDefault();
|
|
2067
|
+
if (!name.trim()) return;
|
|
2068
|
+
try {
|
|
2069
|
+
await updateChannel.mutateAsync({
|
|
2070
|
+
id: channel.id,
|
|
2071
|
+
body: {
|
|
2072
|
+
name: name.trim(),
|
|
2073
|
+
identifier: identifier.trim() || void 0,
|
|
2074
|
+
id_agent: idAgent
|
|
2075
|
+
}
|
|
2076
|
+
});
|
|
2077
|
+
toast3.success("Canal atualizado");
|
|
2078
|
+
onOpenChange(false);
|
|
2079
|
+
} catch {
|
|
2080
|
+
toast3.error("Erro ao atualizar canal");
|
|
2081
|
+
}
|
|
2082
|
+
}
|
|
2083
|
+
return /* @__PURE__ */ jsx14(Dialog4, { open, onOpenChange, children: /* @__PURE__ */ jsxs12(DialogContent4, { children: [
|
|
2084
|
+
/* @__PURE__ */ jsx14(DialogHeader4, { children: /* @__PURE__ */ jsxs12(DialogTitle4, { className: "flex items-center gap-2", children: [
|
|
2085
|
+
/* @__PURE__ */ jsx14(WhatsappIcon, { className: "h-5 w-5 text-green-600" }),
|
|
2086
|
+
"Editar Canal"
|
|
2087
|
+
] }) }),
|
|
2088
|
+
/* @__PURE__ */ jsxs12("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
|
|
2089
|
+
/* @__PURE__ */ jsxs12("div", { className: "space-y-2", children: [
|
|
2090
|
+
/* @__PURE__ */ jsx14(Label2, { htmlFor: "edit-channel-name", children: "Nome do canal *" }),
|
|
2091
|
+
/* @__PURE__ */ jsx14(
|
|
2092
|
+
Input3,
|
|
2093
|
+
{
|
|
2094
|
+
id: "edit-channel-name",
|
|
2095
|
+
value: name,
|
|
2096
|
+
onChange: (e) => setName(e.target.value),
|
|
2097
|
+
placeholder: "Ex: WhatsApp Principal",
|
|
2098
|
+
required: true,
|
|
2099
|
+
disabled: updateChannel.isPending
|
|
2100
|
+
}
|
|
2101
|
+
)
|
|
2102
|
+
] }),
|
|
2103
|
+
/* @__PURE__ */ jsxs12("div", { className: "space-y-2", children: [
|
|
2104
|
+
/* @__PURE__ */ jsx14(Label2, { htmlFor: "edit-channel-identifier", children: "N\xFAmero do WhatsApp (opcional)" }),
|
|
2105
|
+
/* @__PURE__ */ jsx14(
|
|
2106
|
+
Input3,
|
|
2107
|
+
{
|
|
2108
|
+
id: "edit-channel-identifier",
|
|
2109
|
+
value: identifier,
|
|
2110
|
+
onChange: (e) => setIdentifier(e.target.value),
|
|
2111
|
+
placeholder: "5511999999999",
|
|
2112
|
+
disabled: updateChannel.isPending
|
|
2113
|
+
}
|
|
2114
|
+
)
|
|
2115
|
+
] }),
|
|
2116
|
+
renderAgentSelect?.({
|
|
2117
|
+
value: idAgent,
|
|
2118
|
+
onChange: setIdAgent,
|
|
2119
|
+
disabled: updateChannel.isPending
|
|
2120
|
+
}),
|
|
2121
|
+
/* @__PURE__ */ jsxs12(DialogFooter3, { children: [
|
|
2122
|
+
/* @__PURE__ */ jsx14(
|
|
2123
|
+
Button9,
|
|
2124
|
+
{
|
|
2125
|
+
type: "button",
|
|
2126
|
+
variant: "outline",
|
|
2127
|
+
onClick: () => onOpenChange(false),
|
|
2128
|
+
disabled: updateChannel.isPending,
|
|
2129
|
+
children: "Cancelar"
|
|
2130
|
+
}
|
|
2131
|
+
),
|
|
2132
|
+
/* @__PURE__ */ jsxs12(Button9, { type: "submit", disabled: updateChannel.isPending || !name.trim(), children: [
|
|
2133
|
+
updateChannel.isPending && /* @__PURE__ */ jsx14(Loader24, { className: "mr-2 h-4 w-4 animate-spin" }),
|
|
2134
|
+
"Salvar"
|
|
2135
|
+
] })
|
|
2136
|
+
] })
|
|
2137
|
+
] })
|
|
2138
|
+
] }) });
|
|
2139
|
+
}
|
|
2140
|
+
|
|
2141
|
+
// src/components/contact-form-dialog.tsx
|
|
2142
|
+
import { useEffect as useEffect5, useState as useState9 } from "react";
|
|
2143
|
+
import {
|
|
2144
|
+
Dialog as Dialog5,
|
|
2145
|
+
DialogContent as DialogContent5,
|
|
2146
|
+
DialogHeader as DialogHeader5,
|
|
2147
|
+
DialogTitle as DialogTitle5,
|
|
2148
|
+
DialogFooter as DialogFooter4,
|
|
2149
|
+
Button as Button10,
|
|
2150
|
+
Input as Input4,
|
|
2151
|
+
Label as Label3
|
|
2152
|
+
} from "@greatapps/greatauth-ui/ui";
|
|
2153
|
+
import { Loader2 as Loader25 } from "lucide-react";
|
|
2154
|
+
import { toast as toast4 } from "sonner";
|
|
2155
|
+
import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2156
|
+
function ContactFormDialog({
|
|
2157
|
+
open,
|
|
2158
|
+
onOpenChange,
|
|
2159
|
+
contact,
|
|
2160
|
+
config
|
|
2161
|
+
}) {
|
|
2162
|
+
const isEditing = !!contact;
|
|
2163
|
+
const createContact = useCreateContact(config);
|
|
2164
|
+
const updateContact = useUpdateContact(config);
|
|
2165
|
+
const [name, setName] = useState9("");
|
|
2166
|
+
const [phoneNumber, setPhoneNumber] = useState9("");
|
|
2167
|
+
const [identifier, setIdentifier] = useState9("");
|
|
2168
|
+
useEffect5(() => {
|
|
2169
|
+
if (contact) {
|
|
2170
|
+
setName(contact.name);
|
|
2171
|
+
setPhoneNumber(contact.phone_number || "");
|
|
2172
|
+
setIdentifier(contact.identifier || "");
|
|
2173
|
+
} else {
|
|
2174
|
+
setName("");
|
|
2175
|
+
setPhoneNumber("");
|
|
2176
|
+
setIdentifier("");
|
|
2177
|
+
}
|
|
2178
|
+
}, [contact, open]);
|
|
2179
|
+
const isPending = createContact.isPending || updateContact.isPending;
|
|
2180
|
+
async function handleSubmit(e) {
|
|
2181
|
+
e.preventDefault();
|
|
2182
|
+
if (!name.trim()) return;
|
|
2183
|
+
const body = {
|
|
2184
|
+
name: name.trim(),
|
|
2185
|
+
phone_number: phoneNumber.trim() || void 0,
|
|
2186
|
+
identifier: identifier.trim() || void 0
|
|
2187
|
+
};
|
|
2188
|
+
try {
|
|
2189
|
+
if (isEditing) {
|
|
2190
|
+
await updateContact.mutateAsync({ id: contact.id, body });
|
|
2191
|
+
toast4.success("Contato atualizado");
|
|
2192
|
+
} else {
|
|
2193
|
+
await createContact.mutateAsync(body);
|
|
2194
|
+
toast4.success("Contato criado");
|
|
2195
|
+
}
|
|
2196
|
+
onOpenChange(false);
|
|
2197
|
+
} catch {
|
|
2198
|
+
toast4.error(isEditing ? "Erro ao atualizar" : "Erro ao criar contato");
|
|
2199
|
+
}
|
|
2200
|
+
}
|
|
2201
|
+
return /* @__PURE__ */ jsx15(Dialog5, { open, onOpenChange, children: /* @__PURE__ */ jsxs13(DialogContent5, { children: [
|
|
2202
|
+
/* @__PURE__ */ jsx15(DialogHeader5, { children: /* @__PURE__ */ jsx15(DialogTitle5, { children: isEditing ? "Editar Contato" : "Novo Contato" }) }),
|
|
2203
|
+
/* @__PURE__ */ jsxs13("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
|
|
2204
|
+
/* @__PURE__ */ jsxs13("div", { className: "space-y-2", children: [
|
|
2205
|
+
/* @__PURE__ */ jsx15(Label3, { htmlFor: "contact-name", children: "Nome *" }),
|
|
2206
|
+
/* @__PURE__ */ jsx15(
|
|
2207
|
+
Input4,
|
|
2208
|
+
{
|
|
2209
|
+
id: "contact-name",
|
|
2210
|
+
value: name,
|
|
2211
|
+
onChange: (e) => setName(e.target.value),
|
|
2212
|
+
placeholder: "Nome do contato",
|
|
2213
|
+
required: true,
|
|
2214
|
+
disabled: isPending
|
|
2215
|
+
}
|
|
2216
|
+
)
|
|
2217
|
+
] }),
|
|
2218
|
+
/* @__PURE__ */ jsxs13("div", { className: "space-y-2", children: [
|
|
2219
|
+
/* @__PURE__ */ jsx15(Label3, { htmlFor: "contact-phone", children: "Telefone" }),
|
|
2220
|
+
/* @__PURE__ */ jsx15(
|
|
2221
|
+
Input4,
|
|
2222
|
+
{
|
|
2223
|
+
id: "contact-phone",
|
|
2224
|
+
value: phoneNumber,
|
|
2225
|
+
onChange: (e) => setPhoneNumber(e.target.value),
|
|
2226
|
+
placeholder: "5511999999999",
|
|
2227
|
+
disabled: isPending
|
|
2228
|
+
}
|
|
2229
|
+
)
|
|
2230
|
+
] }),
|
|
2231
|
+
/* @__PURE__ */ jsxs13("div", { className: "space-y-2", children: [
|
|
2232
|
+
/* @__PURE__ */ jsx15(Label3, { htmlFor: "contact-identifier", children: "Identificador (WhatsApp ID)" }),
|
|
2233
|
+
/* @__PURE__ */ jsx15(
|
|
2234
|
+
Input4,
|
|
2235
|
+
{
|
|
2236
|
+
id: "contact-identifier",
|
|
2237
|
+
value: identifier,
|
|
2238
|
+
onChange: (e) => setIdentifier(e.target.value),
|
|
2239
|
+
placeholder: "5511999999999@s.whatsapp.net",
|
|
2240
|
+
disabled: isPending
|
|
2241
|
+
}
|
|
2242
|
+
)
|
|
2243
|
+
] }),
|
|
2244
|
+
/* @__PURE__ */ jsxs13(DialogFooter4, { children: [
|
|
2245
|
+
/* @__PURE__ */ jsx15(
|
|
2246
|
+
Button10,
|
|
2247
|
+
{
|
|
2248
|
+
type: "button",
|
|
2249
|
+
variant: "outline",
|
|
2250
|
+
onClick: () => onOpenChange(false),
|
|
2251
|
+
disabled: isPending,
|
|
2252
|
+
children: "Cancelar"
|
|
2253
|
+
}
|
|
2254
|
+
),
|
|
2255
|
+
/* @__PURE__ */ jsxs13(Button10, { type: "submit", disabled: isPending || !name.trim(), children: [
|
|
2256
|
+
isPending ? /* @__PURE__ */ jsx15(Loader25, { className: "mr-2 h-4 w-4 animate-spin" }) : null,
|
|
2257
|
+
isEditing ? "Salvar" : "Criar"
|
|
2258
|
+
] })
|
|
2259
|
+
] })
|
|
2260
|
+
] })
|
|
2261
|
+
] }) });
|
|
2262
|
+
}
|
|
2263
|
+
|
|
2264
|
+
// src/components/contacts-table.tsx
|
|
2265
|
+
import { useMemo as useMemo4, useState as useState11 } from "react";
|
|
2266
|
+
|
|
2267
|
+
// src/components/data-table.tsx
|
|
2268
|
+
import {
|
|
2269
|
+
flexRender,
|
|
2270
|
+
getCoreRowModel,
|
|
2271
|
+
getSortedRowModel,
|
|
2272
|
+
useReactTable
|
|
2273
|
+
} from "@tanstack/react-table";
|
|
2274
|
+
import { useState as useState10 } from "react";
|
|
2275
|
+
import {
|
|
2276
|
+
Table,
|
|
2277
|
+
TableBody,
|
|
2278
|
+
TableCell,
|
|
2279
|
+
TableHead,
|
|
2280
|
+
TableHeader,
|
|
2281
|
+
TableRow,
|
|
2282
|
+
Button as Button11,
|
|
2283
|
+
Skeleton as Skeleton4,
|
|
2284
|
+
cn as cn5
|
|
2285
|
+
} from "@greatapps/greatauth-ui/ui";
|
|
2286
|
+
import { ChevronLeft, ChevronRight, ArrowUp, ArrowDown, ArrowUpDown } from "lucide-react";
|
|
2287
|
+
import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
2288
|
+
function DataTable({
|
|
2289
|
+
columns,
|
|
2290
|
+
data,
|
|
2291
|
+
isLoading,
|
|
2292
|
+
emptyMessage = "Nenhum registro encontrado",
|
|
2293
|
+
total,
|
|
2294
|
+
page = 1,
|
|
2295
|
+
onPageChange,
|
|
2296
|
+
pageSize = 15,
|
|
2297
|
+
onRowClick,
|
|
2298
|
+
selectedRowId,
|
|
2299
|
+
getRowId,
|
|
2300
|
+
compact
|
|
2301
|
+
}) {
|
|
2302
|
+
const [sorting, setSorting] = useState10([]);
|
|
2303
|
+
const table = useReactTable({
|
|
2304
|
+
data,
|
|
2305
|
+
columns,
|
|
2306
|
+
getCoreRowModel: getCoreRowModel(),
|
|
2307
|
+
getSortedRowModel: getSortedRowModel(),
|
|
2308
|
+
onSortingChange: setSorting,
|
|
2309
|
+
state: { sorting }
|
|
2310
|
+
});
|
|
2311
|
+
const totalPages = total ? Math.ceil(total / pageSize) : 1;
|
|
2312
|
+
const showPagination = onPageChange && total && total > pageSize;
|
|
2313
|
+
return /* @__PURE__ */ jsxs14("div", { className: "space-y-4", children: [
|
|
2314
|
+
/* @__PURE__ */ jsx16("div", { className: "rounded-md border", children: /* @__PURE__ */ jsxs14(Table, { children: [
|
|
2315
|
+
/* @__PURE__ */ jsx16(TableHeader, { children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx16(TableRow, { children: headerGroup.headers.map((header) => /* @__PURE__ */ jsx16(
|
|
2316
|
+
TableHead,
|
|
2317
|
+
{
|
|
2318
|
+
className: cn5(compact && "py-1.5 text-xs"),
|
|
2319
|
+
style: { width: header.getSize() !== 150 ? header.getSize() : void 0 },
|
|
2320
|
+
children: header.isPlaceholder ? null : header.column.getCanSort() ? /* @__PURE__ */ jsxs14(
|
|
2321
|
+
"button",
|
|
2322
|
+
{
|
|
2323
|
+
type: "button",
|
|
2324
|
+
className: "flex items-center gap-1 hover:text-foreground -ml-1 px-1 py-0.5 rounded cursor-pointer select-none",
|
|
2325
|
+
onClick: header.column.getToggleSortingHandler(),
|
|
2326
|
+
children: [
|
|
2327
|
+
flexRender(header.column.columnDef.header, header.getContext()),
|
|
2328
|
+
{
|
|
2329
|
+
asc: /* @__PURE__ */ jsx16(ArrowUp, { className: "h-3.5 w-3.5" }),
|
|
2330
|
+
desc: /* @__PURE__ */ jsx16(ArrowDown, { className: "h-3.5 w-3.5" })
|
|
2331
|
+
}[header.column.getIsSorted()] ?? /* @__PURE__ */ jsx16(ArrowUpDown, { className: "h-3.5 w-3.5 text-muted-foreground/50" })
|
|
2332
|
+
]
|
|
2333
|
+
}
|
|
2334
|
+
) : flexRender(header.column.columnDef.header, header.getContext())
|
|
2335
|
+
},
|
|
2336
|
+
header.id
|
|
2337
|
+
)) }, headerGroup.id)) }),
|
|
2338
|
+
/* @__PURE__ */ jsx16(TableBody, { children: isLoading ? Array.from({ length: compact ? 3 : 5 }).map((_, i) => /* @__PURE__ */ jsx16(TableRow, { children: columns.map((_2, j) => /* @__PURE__ */ jsx16(TableCell, { className: cn5(compact && "py-1.5"), children: /* @__PURE__ */ jsx16(Skeleton4, { className: "h-4 w-full max-w-[120px]" }) }, j)) }, i)) : table.getRowModel().rows.length === 0 ? /* @__PURE__ */ jsx16(TableRow, { children: /* @__PURE__ */ jsx16(
|
|
2339
|
+
TableCell,
|
|
2340
|
+
{
|
|
2341
|
+
colSpan: columns.length,
|
|
2342
|
+
className: cn5(
|
|
2343
|
+
"text-center text-muted-foreground",
|
|
2344
|
+
compact ? "py-4" : "py-8"
|
|
2345
|
+
),
|
|
2346
|
+
children: emptyMessage
|
|
2347
|
+
}
|
|
2348
|
+
) }) : table.getRowModel().rows.map((row) => {
|
|
2349
|
+
const rowId = getRowId ? getRowId(row.original) : void 0;
|
|
2350
|
+
const isSelected = selectedRowId != null && rowId != null && rowId === selectedRowId;
|
|
2351
|
+
return /* @__PURE__ */ jsx16(
|
|
2352
|
+
TableRow,
|
|
2353
|
+
{
|
|
2354
|
+
className: cn5(
|
|
2355
|
+
onRowClick && "cursor-pointer",
|
|
2356
|
+
isSelected && "bg-accent"
|
|
2357
|
+
),
|
|
2358
|
+
onClick: () => onRowClick?.(row.original),
|
|
2359
|
+
children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx16(TableCell, { className: cn5(compact && "py-1.5"), children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id))
|
|
2360
|
+
},
|
|
2361
|
+
row.id
|
|
2362
|
+
);
|
|
2363
|
+
}) })
|
|
2364
|
+
] }) }),
|
|
2365
|
+
showPagination && /* @__PURE__ */ jsxs14("div", { className: "flex items-center justify-between px-2", children: [
|
|
2366
|
+
/* @__PURE__ */ jsxs14("p", { className: "text-sm text-muted-foreground", children: [
|
|
2367
|
+
total,
|
|
2368
|
+
" registro",
|
|
2369
|
+
total !== 1 ? "s" : ""
|
|
2370
|
+
] }),
|
|
2371
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
|
|
2372
|
+
/* @__PURE__ */ jsxs14(
|
|
2373
|
+
Button11,
|
|
2374
|
+
{
|
|
2375
|
+
variant: "outline",
|
|
2376
|
+
size: "sm",
|
|
2377
|
+
onClick: () => onPageChange(page - 1),
|
|
2378
|
+
disabled: page <= 1,
|
|
2379
|
+
children: [
|
|
2380
|
+
/* @__PURE__ */ jsx16(ChevronLeft, { className: "h-4 w-4" }),
|
|
2381
|
+
"Anterior"
|
|
2382
|
+
]
|
|
2383
|
+
}
|
|
2384
|
+
),
|
|
2385
|
+
/* @__PURE__ */ jsxs14("span", { className: "text-sm text-muted-foreground", children: [
|
|
2386
|
+
page,
|
|
2387
|
+
" de ",
|
|
2388
|
+
totalPages
|
|
2389
|
+
] }),
|
|
2390
|
+
/* @__PURE__ */ jsxs14(
|
|
2391
|
+
Button11,
|
|
2392
|
+
{
|
|
2393
|
+
variant: "outline",
|
|
2394
|
+
size: "sm",
|
|
2395
|
+
onClick: () => onPageChange(page + 1),
|
|
2396
|
+
disabled: page >= totalPages,
|
|
2397
|
+
children: [
|
|
2398
|
+
"Pr\xF3ximo",
|
|
2399
|
+
/* @__PURE__ */ jsx16(ChevronRight, { className: "h-4 w-4" })
|
|
2400
|
+
]
|
|
2401
|
+
}
|
|
2402
|
+
)
|
|
2403
|
+
] })
|
|
2404
|
+
] })
|
|
2405
|
+
] });
|
|
2406
|
+
}
|
|
2407
|
+
|
|
2408
|
+
// src/components/contacts-table.tsx
|
|
2409
|
+
import {
|
|
2410
|
+
Input as Input5,
|
|
2411
|
+
Tooltip as Tooltip2,
|
|
2412
|
+
TooltipTrigger as TooltipTrigger2,
|
|
2413
|
+
TooltipContent as TooltipContent2,
|
|
2414
|
+
AlertDialog as AlertDialog3,
|
|
2415
|
+
AlertDialogAction as AlertDialogAction3,
|
|
2416
|
+
AlertDialogCancel as AlertDialogCancel3,
|
|
2417
|
+
AlertDialogContent as AlertDialogContent3,
|
|
2418
|
+
AlertDialogDescription as AlertDialogDescription3,
|
|
2419
|
+
AlertDialogFooter as AlertDialogFooter3,
|
|
2420
|
+
AlertDialogHeader as AlertDialogHeader3,
|
|
2421
|
+
AlertDialogTitle as AlertDialogTitle3,
|
|
2422
|
+
Button as Button12
|
|
2423
|
+
} from "@greatapps/greatauth-ui/ui";
|
|
2424
|
+
import { Pencil as Pencil2, Trash2 as Trash23, Search as Search2 } from "lucide-react";
|
|
2425
|
+
import { format as format3 } from "date-fns";
|
|
2426
|
+
import { ptBR as ptBR4 } from "date-fns/locale";
|
|
2427
|
+
import { toast as toast5 } from "sonner";
|
|
2428
|
+
import { Fragment as Fragment3, jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2429
|
+
function useColumns(onEdit, onDelete) {
|
|
2430
|
+
return [
|
|
2431
|
+
{
|
|
2432
|
+
accessorKey: "name",
|
|
2433
|
+
header: "Nome",
|
|
2434
|
+
cell: ({ row }) => /* @__PURE__ */ jsx17("span", { className: "font-medium", children: row.original.name }),
|
|
2435
|
+
sortingFn: (rowA, rowB) => rowA.original.name.toLowerCase().localeCompare(rowB.original.name.toLowerCase())
|
|
2436
|
+
},
|
|
2437
|
+
{
|
|
2438
|
+
accessorKey: "phone_number",
|
|
2439
|
+
header: "Telefone",
|
|
2440
|
+
cell: ({ row }) => row.original.phone_number || "\u2014",
|
|
2441
|
+
sortingFn: (rowA, rowB) => {
|
|
2442
|
+
const a = rowA.original.phone_number || "";
|
|
2443
|
+
const b = rowB.original.phone_number || "";
|
|
2444
|
+
return a.localeCompare(b);
|
|
2445
|
+
}
|
|
2446
|
+
},
|
|
2447
|
+
{
|
|
2448
|
+
accessorKey: "identifier",
|
|
2449
|
+
header: "Identificador",
|
|
2450
|
+
cell: ({ row }) => /* @__PURE__ */ jsx17("span", { className: "text-muted-foreground text-xs font-mono", children: row.original.identifier || "\u2014" }),
|
|
2451
|
+
sortingFn: (rowA, rowB) => {
|
|
2452
|
+
const a = rowA.original.identifier || "";
|
|
2453
|
+
const b = rowB.original.identifier || "";
|
|
2454
|
+
return a.localeCompare(b);
|
|
2455
|
+
}
|
|
2456
|
+
},
|
|
2457
|
+
{
|
|
2458
|
+
accessorKey: "datetime_add",
|
|
2459
|
+
header: "Criado em",
|
|
2460
|
+
cell: ({ row }) => /* @__PURE__ */ jsx17("span", { className: "text-muted-foreground text-sm", children: format3(new Date(row.original.datetime_add), "dd/MM/yyyy", { locale: ptBR4 }) })
|
|
2461
|
+
},
|
|
2462
|
+
{
|
|
2463
|
+
id: "actions",
|
|
2464
|
+
size: 80,
|
|
2465
|
+
enableSorting: false,
|
|
2466
|
+
cell: ({ row }) => /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-1", children: [
|
|
2467
|
+
/* @__PURE__ */ jsxs15(Tooltip2, { children: [
|
|
2468
|
+
/* @__PURE__ */ jsx17(TooltipTrigger2, { asChild: true, children: /* @__PURE__ */ jsx17(
|
|
2469
|
+
Button12,
|
|
2470
|
+
{
|
|
2471
|
+
variant: "ghost",
|
|
2472
|
+
size: "icon",
|
|
2473
|
+
className: "h-8 w-8",
|
|
2474
|
+
onClick: () => onEdit(row.original),
|
|
2475
|
+
children: /* @__PURE__ */ jsx17(Pencil2, { className: "h-4 w-4" })
|
|
2476
|
+
}
|
|
2477
|
+
) }),
|
|
2478
|
+
/* @__PURE__ */ jsx17(TooltipContent2, { children: "Editar" })
|
|
2479
|
+
] }),
|
|
2480
|
+
/* @__PURE__ */ jsxs15(Tooltip2, { children: [
|
|
2481
|
+
/* @__PURE__ */ jsx17(TooltipTrigger2, { asChild: true, children: /* @__PURE__ */ jsx17(
|
|
2482
|
+
Button12,
|
|
2483
|
+
{
|
|
2484
|
+
variant: "ghost",
|
|
2485
|
+
size: "icon",
|
|
2486
|
+
className: "h-8 w-8 text-destructive hover:text-destructive",
|
|
2487
|
+
onClick: () => onDelete(row.original.id),
|
|
2488
|
+
children: /* @__PURE__ */ jsx17(Trash23, { className: "h-4 w-4" })
|
|
2489
|
+
}
|
|
2490
|
+
) }),
|
|
2491
|
+
/* @__PURE__ */ jsx17(TooltipContent2, { children: "Excluir" })
|
|
2492
|
+
] })
|
|
2493
|
+
] })
|
|
2494
|
+
}
|
|
2495
|
+
];
|
|
2496
|
+
}
|
|
2497
|
+
function ContactsTable({ config }) {
|
|
2498
|
+
const [search, setSearch] = useState11("");
|
|
2499
|
+
const [page, setPage] = useState11(1);
|
|
2500
|
+
const queryParams = useMemo4(() => {
|
|
2501
|
+
const params = {
|
|
2502
|
+
limit: "15",
|
|
2503
|
+
page: String(page)
|
|
2504
|
+
};
|
|
2505
|
+
if (search) {
|
|
2506
|
+
params.search = search;
|
|
2507
|
+
}
|
|
2508
|
+
return params;
|
|
2509
|
+
}, [search, page]);
|
|
2510
|
+
const { data, isLoading } = useContacts(config, queryParams);
|
|
2511
|
+
const deleteContact = useDeleteContact(config);
|
|
2512
|
+
const [editContact, setEditContact] = useState11(null);
|
|
2513
|
+
const [deleteId, setDeleteId] = useState11(null);
|
|
2514
|
+
const contacts = data?.data || [];
|
|
2515
|
+
const total = data?.total || 0;
|
|
2516
|
+
const columns = useColumns(
|
|
2517
|
+
(contact) => setEditContact(contact),
|
|
2518
|
+
(id) => setDeleteId(id)
|
|
2519
|
+
);
|
|
2520
|
+
function handleDelete() {
|
|
2521
|
+
if (!deleteId) return;
|
|
2522
|
+
deleteContact.mutate(deleteId, {
|
|
2523
|
+
onSuccess: () => {
|
|
2524
|
+
toast5.success("Contato exclu\xEDdo");
|
|
2525
|
+
setDeleteId(null);
|
|
2526
|
+
},
|
|
2527
|
+
onError: () => toast5.error("Erro ao excluir contato")
|
|
2528
|
+
});
|
|
2529
|
+
}
|
|
2530
|
+
function handleSearchChange(value) {
|
|
2531
|
+
setSearch(value);
|
|
2532
|
+
setPage(1);
|
|
2533
|
+
}
|
|
2534
|
+
return /* @__PURE__ */ jsxs15(Fragment3, { children: [
|
|
2535
|
+
/* @__PURE__ */ jsx17("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsxs15("div", { className: "relative flex-1 max-w-md", children: [
|
|
2536
|
+
/* @__PURE__ */ jsx17(Search2, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
2537
|
+
/* @__PURE__ */ jsx17(
|
|
2538
|
+
Input5,
|
|
2539
|
+
{
|
|
2540
|
+
placeholder: "Buscar por nome, telefone ou identificador...",
|
|
2541
|
+
value: search,
|
|
2542
|
+
onChange: (e) => handleSearchChange(e.target.value),
|
|
2543
|
+
className: "pl-9"
|
|
2544
|
+
}
|
|
2545
|
+
)
|
|
2546
|
+
] }) }),
|
|
2547
|
+
/* @__PURE__ */ jsx17(
|
|
2548
|
+
DataTable,
|
|
2549
|
+
{
|
|
2550
|
+
columns,
|
|
2551
|
+
data: contacts,
|
|
2552
|
+
isLoading,
|
|
2553
|
+
emptyMessage: "Nenhum contato encontrado",
|
|
2554
|
+
total,
|
|
2555
|
+
page,
|
|
2556
|
+
onPageChange: setPage,
|
|
2557
|
+
pageSize: 15
|
|
2558
|
+
}
|
|
2559
|
+
),
|
|
2560
|
+
/* @__PURE__ */ jsx17(
|
|
2561
|
+
ContactFormDialog,
|
|
2562
|
+
{
|
|
2563
|
+
open: !!editContact,
|
|
2564
|
+
onOpenChange: (open) => !open && setEditContact(null),
|
|
2565
|
+
contact: editContact ?? void 0,
|
|
2566
|
+
config
|
|
2567
|
+
}
|
|
2568
|
+
),
|
|
2569
|
+
/* @__PURE__ */ jsx17(AlertDialog3, { open: !!deleteId, onOpenChange: (open) => !open && setDeleteId(null), children: /* @__PURE__ */ jsxs15(AlertDialogContent3, { children: [
|
|
2570
|
+
/* @__PURE__ */ jsxs15(AlertDialogHeader3, { children: [
|
|
2571
|
+
/* @__PURE__ */ jsx17(AlertDialogTitle3, { children: "Excluir contato?" }),
|
|
2572
|
+
/* @__PURE__ */ jsx17(AlertDialogDescription3, { children: "Esta a\xE7\xE3o n\xE3o pode ser desfeita. O contato ser\xE1 removido permanentemente." })
|
|
2573
|
+
] }),
|
|
2574
|
+
/* @__PURE__ */ jsxs15(AlertDialogFooter3, { children: [
|
|
2575
|
+
/* @__PURE__ */ jsx17(AlertDialogCancel3, { children: "Cancelar" }),
|
|
2576
|
+
/* @__PURE__ */ jsx17(
|
|
2577
|
+
AlertDialogAction3,
|
|
2578
|
+
{
|
|
2579
|
+
onClick: handleDelete,
|
|
2580
|
+
className: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
2581
|
+
children: "Excluir"
|
|
2582
|
+
}
|
|
2583
|
+
)
|
|
2584
|
+
] })
|
|
2585
|
+
] }) })
|
|
2586
|
+
] });
|
|
2587
|
+
}
|
|
2588
|
+
|
|
2589
|
+
// src/components/inbox-page.tsx
|
|
2590
|
+
import { useState as useState12, useCallback as useCallback3 } from "react";
|
|
2591
|
+
import { Button as Button13, Select as Select3, SelectContent as SelectContent3, SelectItem as SelectItem3, SelectTrigger as SelectTrigger3, SelectValue as SelectValue3 } from "@greatapps/greatauth-ui/ui";
|
|
2592
|
+
import { MessageCircle, User } from "lucide-react";
|
|
2593
|
+
import { Fragment as Fragment4, jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2594
|
+
function InboxPage({ config, filterChannelId }) {
|
|
2595
|
+
const [selectedInbox, setSelectedInbox] = useState12(null);
|
|
2596
|
+
const [showContactPanel, setShowContactPanel] = useState12(false);
|
|
2597
|
+
const { data: inboxes, isLoading: inboxesLoading } = useInboxes(config);
|
|
2598
|
+
const { data: messages = [], isLoading: messagesLoading } = useInboxMessages(config, selectedInbox?.id ?? null);
|
|
2599
|
+
const { data: contact, isLoading: contactLoading } = useGetContact(
|
|
2600
|
+
config,
|
|
2601
|
+
showContactPanel && selectedInbox?.id_contact ? selectedInbox.id_contact : null
|
|
2602
|
+
);
|
|
2603
|
+
const sendMessage = useSendMessage(config);
|
|
2604
|
+
const retryMessage = useRetryMessage(config);
|
|
2605
|
+
const revokeMessage = useRevokeMessage(config);
|
|
2606
|
+
const editMessage = useEditMessage(config);
|
|
2607
|
+
const updateInbox = useUpdateInbox(config);
|
|
2608
|
+
const deleteInbox = useDeleteInbox(config);
|
|
2609
|
+
const handleSend = useCallback3(
|
|
2610
|
+
(content) => {
|
|
2611
|
+
if (!selectedInbox) return;
|
|
2612
|
+
sendMessage.mutate({ idInbox: selectedInbox.id, content });
|
|
2613
|
+
},
|
|
2614
|
+
[selectedInbox, sendMessage]
|
|
2615
|
+
);
|
|
2616
|
+
const handleStatusChange = useCallback3(
|
|
2617
|
+
(status) => {
|
|
2618
|
+
if (!selectedInbox) return;
|
|
2619
|
+
updateInbox.mutate({ id: selectedInbox.id, body: { status } });
|
|
2620
|
+
},
|
|
2621
|
+
[selectedInbox, updateInbox]
|
|
2622
|
+
);
|
|
2623
|
+
const handleRevoke = useCallback3(
|
|
2624
|
+
(message) => {
|
|
2625
|
+
if (!selectedInbox) return;
|
|
2626
|
+
revokeMessage.mutate({ id: message.id, idInbox: selectedInbox.id });
|
|
2627
|
+
},
|
|
2628
|
+
[selectedInbox, revokeMessage]
|
|
2629
|
+
);
|
|
2630
|
+
const handleEdit = useCallback3(
|
|
2631
|
+
(message, newContent) => {
|
|
2632
|
+
if (!selectedInbox) return;
|
|
2633
|
+
editMessage.mutate({
|
|
2634
|
+
id: message.id,
|
|
2635
|
+
idInbox: selectedInbox.id,
|
|
2636
|
+
content: newContent
|
|
2637
|
+
});
|
|
2638
|
+
},
|
|
2639
|
+
[selectedInbox, editMessage]
|
|
2640
|
+
);
|
|
2641
|
+
return /* @__PURE__ */ jsxs16("div", { className: "flex h-full", children: [
|
|
2642
|
+
/* @__PURE__ */ jsx18("div", { className: "w-[360px] shrink-0 border-r flex flex-col", children: /* @__PURE__ */ jsx18(
|
|
2643
|
+
InboxSidebar,
|
|
2644
|
+
{
|
|
2645
|
+
inboxes,
|
|
2646
|
+
isLoading: inboxesLoading,
|
|
2647
|
+
selectedInboxId: selectedInbox?.id ?? null,
|
|
2648
|
+
onSelectInbox: (inbox) => {
|
|
2649
|
+
setSelectedInbox(inbox);
|
|
2650
|
+
setShowContactPanel(false);
|
|
2651
|
+
},
|
|
2652
|
+
onDeleteInbox: (id) => deleteInbox.mutate(id),
|
|
2653
|
+
filterChannelId
|
|
2654
|
+
}
|
|
2655
|
+
) }),
|
|
2656
|
+
/* @__PURE__ */ jsx18("div", { className: "flex-1 flex min-w-0", children: selectedInbox ? /* @__PURE__ */ jsxs16(Fragment4, { children: [
|
|
2657
|
+
/* @__PURE__ */ jsx18("div", { className: "flex-1 flex flex-col min-w-0", children: /* @__PURE__ */ jsx18(
|
|
2658
|
+
ChatView,
|
|
2659
|
+
{
|
|
2660
|
+
messages,
|
|
2661
|
+
isLoading: messagesLoading,
|
|
2662
|
+
onSend: handleSend,
|
|
2663
|
+
onRetry: retryMessage,
|
|
2664
|
+
onRevoke: handleRevoke,
|
|
2665
|
+
onEdit: handleEdit,
|
|
2666
|
+
renderHeader: /* @__PURE__ */ jsxs16("div", { className: "flex items-center justify-between border-b px-4 py-3", children: [
|
|
2667
|
+
/* @__PURE__ */ jsx18("span", { className: "text-sm font-medium", children: selectedInbox.contact_name || "Conversa" }),
|
|
2668
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2", children: [
|
|
2669
|
+
/* @__PURE__ */ jsxs16(
|
|
2670
|
+
Select3,
|
|
2671
|
+
{
|
|
2672
|
+
value: selectedInbox.status,
|
|
2673
|
+
onValueChange: handleStatusChange,
|
|
2674
|
+
children: [
|
|
2675
|
+
/* @__PURE__ */ jsx18(SelectTrigger3, { className: "w-[130px] h-8 text-xs", children: /* @__PURE__ */ jsx18(SelectValue3, { placeholder: "Status" }) }),
|
|
2676
|
+
/* @__PURE__ */ jsxs16(SelectContent3, { children: [
|
|
2677
|
+
/* @__PURE__ */ jsx18(SelectItem3, { value: "open", children: "Aberta" }),
|
|
2678
|
+
/* @__PURE__ */ jsx18(SelectItem3, { value: "pending", children: "Pendente" }),
|
|
2679
|
+
/* @__PURE__ */ jsx18(SelectItem3, { value: "resolved", children: "Resolvida" })
|
|
2680
|
+
] })
|
|
2681
|
+
]
|
|
2682
|
+
}
|
|
2683
|
+
),
|
|
2684
|
+
selectedInbox.id_contact && /* @__PURE__ */ jsx18(
|
|
2685
|
+
Button13,
|
|
2686
|
+
{
|
|
2687
|
+
variant: "ghost",
|
|
2688
|
+
size: "icon",
|
|
2689
|
+
className: "h-8 w-8",
|
|
2690
|
+
onClick: () => setShowContactPanel((v) => !v),
|
|
2691
|
+
children: /* @__PURE__ */ jsx18(User, { className: "h-4 w-4" })
|
|
2692
|
+
}
|
|
2693
|
+
)
|
|
2694
|
+
] })
|
|
2695
|
+
] })
|
|
2696
|
+
}
|
|
2697
|
+
) }),
|
|
2698
|
+
showContactPanel && selectedInbox.id_contact && /* @__PURE__ */ jsx18(
|
|
2699
|
+
ContactInfoPanel,
|
|
2700
|
+
{
|
|
2701
|
+
contact: contact ?? null,
|
|
2702
|
+
isLoading: contactLoading,
|
|
2703
|
+
onClose: () => setShowContactPanel(false)
|
|
2704
|
+
}
|
|
2705
|
+
)
|
|
2706
|
+
] }) : /* @__PURE__ */ jsxs16("div", { className: "flex-1 flex flex-col items-center justify-center text-muted-foreground gap-3", children: [
|
|
2707
|
+
/* @__PURE__ */ jsx18(MessageCircle, { className: "h-12 w-12 opacity-20" }),
|
|
2708
|
+
/* @__PURE__ */ jsx18("p", { className: "text-sm", children: "Selecione uma conversa para come\xE7ar" })
|
|
2709
|
+
] }) })
|
|
2710
|
+
] });
|
|
2711
|
+
}
|
|
2712
|
+
|
|
2713
|
+
// src/components/channels-page.tsx
|
|
2714
|
+
import { useState as useState13 } from "react";
|
|
2715
|
+
import {
|
|
2716
|
+
Button as Button14,
|
|
2717
|
+
AlertDialog as AlertDialog4,
|
|
2718
|
+
AlertDialogAction as AlertDialogAction4,
|
|
2719
|
+
AlertDialogCancel as AlertDialogCancel4,
|
|
2720
|
+
AlertDialogContent as AlertDialogContent4,
|
|
2721
|
+
AlertDialogDescription as AlertDialogDescription4,
|
|
2722
|
+
AlertDialogFooter as AlertDialogFooter4,
|
|
2723
|
+
AlertDialogHeader as AlertDialogHeader4,
|
|
2724
|
+
AlertDialogTitle as AlertDialogTitle4,
|
|
2725
|
+
Skeleton as Skeleton5
|
|
2726
|
+
} from "@greatapps/greatauth-ui/ui";
|
|
2727
|
+
import { Plus as Plus2, QrCode, Unplug, LogOut } from "lucide-react";
|
|
2728
|
+
import { toast as toast6 } from "sonner";
|
|
2729
|
+
import { Fragment as Fragment5, jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2730
|
+
function ChannelCardWrapper({
|
|
2731
|
+
channel,
|
|
2732
|
+
config,
|
|
2733
|
+
renderAgentSelect,
|
|
2734
|
+
getAgentInfo
|
|
2735
|
+
}) {
|
|
2736
|
+
const { data: status } = useChannelWhatsappStatus(config, channel.id);
|
|
2737
|
+
const disconnectChannel = useDisconnectChannel(config);
|
|
2738
|
+
const logoutChannel = useLogoutChannel(config);
|
|
2739
|
+
const deleteChannel = useDeleteChannel(config);
|
|
2740
|
+
const [qrOpen, setQrOpen] = useState13(false);
|
|
2741
|
+
const [editOpen, setEditOpen] = useState13(false);
|
|
2742
|
+
const [deleteOpen, setDeleteOpen] = useState13(false);
|
|
2743
|
+
const isFullyConnected = status?.connected === true && status?.logged_in === true;
|
|
2744
|
+
const hasSession = !!channel.external_id;
|
|
2745
|
+
const agentInfo = getAgentInfo?.(channel.id_agent);
|
|
2746
|
+
function handleDisconnect() {
|
|
2747
|
+
disconnectChannel.mutate(channel.id, {
|
|
2748
|
+
onSuccess: () => toast6.success("Canal desconectado"),
|
|
2749
|
+
onError: () => toast6.error("Erro ao desconectar")
|
|
2750
|
+
});
|
|
2751
|
+
}
|
|
2752
|
+
function handleLogout() {
|
|
2753
|
+
logoutChannel.mutate(channel.id, {
|
|
2754
|
+
onSuccess: () => toast6.success("Logout realizado. Ser\xE1 necess\xE1rio novo QR code."),
|
|
2755
|
+
onError: () => toast6.error("Erro ao fazer logout")
|
|
2756
|
+
});
|
|
2757
|
+
}
|
|
2758
|
+
function handleDelete() {
|
|
2759
|
+
deleteChannel.mutate(channel.id, {
|
|
2760
|
+
onSuccess: () => {
|
|
2761
|
+
toast6.success("Canal exclu\xEDdo");
|
|
2762
|
+
setDeleteOpen(false);
|
|
2763
|
+
},
|
|
2764
|
+
onError: () => toast6.error("Erro ao excluir canal")
|
|
2765
|
+
});
|
|
2766
|
+
}
|
|
2767
|
+
return /* @__PURE__ */ jsxs17(Fragment5, { children: [
|
|
2768
|
+
/* @__PURE__ */ jsx19(
|
|
2769
|
+
ChannelCard,
|
|
2770
|
+
{
|
|
2771
|
+
channel,
|
|
2772
|
+
config,
|
|
2773
|
+
onEdit: () => setEditOpen(true),
|
|
2774
|
+
onDelete: () => setDeleteOpen(true),
|
|
2775
|
+
linkedAgentName: agentInfo?.name,
|
|
2776
|
+
linkedAgentActive: agentInfo?.active !== false,
|
|
2777
|
+
actions: /* @__PURE__ */ jsxs17("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
2778
|
+
!isFullyConnected && /* @__PURE__ */ jsxs17(
|
|
2779
|
+
Button14,
|
|
2780
|
+
{
|
|
2781
|
+
size: "sm",
|
|
2782
|
+
variant: "outline",
|
|
2783
|
+
onClick: () => setQrOpen(true),
|
|
2784
|
+
children: [
|
|
2785
|
+
/* @__PURE__ */ jsx19(QrCode, { className: "mr-1.5 h-3.5 w-3.5" }),
|
|
2786
|
+
"Conectar via QR"
|
|
2787
|
+
]
|
|
2788
|
+
}
|
|
2789
|
+
),
|
|
2790
|
+
isFullyConnected && /* @__PURE__ */ jsxs17(
|
|
2791
|
+
Button14,
|
|
2792
|
+
{
|
|
2793
|
+
size: "sm",
|
|
2794
|
+
variant: "outline",
|
|
2795
|
+
onClick: handleDisconnect,
|
|
2796
|
+
disabled: disconnectChannel.isPending,
|
|
2797
|
+
children: [
|
|
2798
|
+
/* @__PURE__ */ jsx19(Unplug, { className: "mr-1.5 h-3.5 w-3.5" }),
|
|
2799
|
+
"Desconectar"
|
|
2800
|
+
]
|
|
2801
|
+
}
|
|
2802
|
+
),
|
|
2803
|
+
hasSession && /* @__PURE__ */ jsxs17(
|
|
2804
|
+
Button14,
|
|
2805
|
+
{
|
|
2806
|
+
size: "sm",
|
|
2807
|
+
variant: "outline",
|
|
2808
|
+
className: "text-destructive hover:text-destructive",
|
|
2809
|
+
onClick: handleLogout,
|
|
2810
|
+
disabled: logoutChannel.isPending,
|
|
2811
|
+
children: [
|
|
2812
|
+
/* @__PURE__ */ jsx19(LogOut, { className: "mr-1.5 h-3.5 w-3.5" }),
|
|
2813
|
+
"Logout"
|
|
2814
|
+
]
|
|
2815
|
+
}
|
|
2816
|
+
)
|
|
2817
|
+
] })
|
|
2818
|
+
}
|
|
2819
|
+
),
|
|
2820
|
+
/* @__PURE__ */ jsx19(
|
|
2821
|
+
WhatsappQrDialog,
|
|
2822
|
+
{
|
|
2823
|
+
open: qrOpen,
|
|
2824
|
+
onOpenChange: setQrOpen,
|
|
2825
|
+
channelId: channel.id,
|
|
2826
|
+
config
|
|
2827
|
+
}
|
|
2828
|
+
),
|
|
2829
|
+
/* @__PURE__ */ jsx19(
|
|
2830
|
+
ChannelEditDialog,
|
|
2831
|
+
{
|
|
2832
|
+
open: editOpen,
|
|
2833
|
+
onOpenChange: setEditOpen,
|
|
2834
|
+
channel,
|
|
2835
|
+
config,
|
|
2836
|
+
renderAgentSelect
|
|
2837
|
+
}
|
|
2838
|
+
),
|
|
2839
|
+
/* @__PURE__ */ jsx19(AlertDialog4, { open: deleteOpen, onOpenChange: setDeleteOpen, children: /* @__PURE__ */ jsxs17(AlertDialogContent4, { children: [
|
|
2840
|
+
/* @__PURE__ */ jsxs17(AlertDialogHeader4, { children: [
|
|
2841
|
+
/* @__PURE__ */ jsx19(AlertDialogTitle4, { children: "Excluir canal?" }),
|
|
2842
|
+
/* @__PURE__ */ jsxs17(AlertDialogDescription4, { children: [
|
|
2843
|
+
'O canal "',
|
|
2844
|
+
channel.name,
|
|
2845
|
+
'" ser\xE1 removido permanentemente. Todas as conversas associadas ser\xE3o perdidas.'
|
|
2846
|
+
] })
|
|
2847
|
+
] }),
|
|
2848
|
+
/* @__PURE__ */ jsxs17(AlertDialogFooter4, { children: [
|
|
2849
|
+
/* @__PURE__ */ jsx19(AlertDialogCancel4, { children: "Cancelar" }),
|
|
2850
|
+
/* @__PURE__ */ jsx19(
|
|
2851
|
+
AlertDialogAction4,
|
|
2852
|
+
{
|
|
2853
|
+
className: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
2854
|
+
onClick: handleDelete,
|
|
2855
|
+
children: "Excluir"
|
|
2856
|
+
}
|
|
2857
|
+
)
|
|
2858
|
+
] })
|
|
2859
|
+
] }) })
|
|
2860
|
+
] });
|
|
2861
|
+
}
|
|
2862
|
+
function ChannelsPage({
|
|
2863
|
+
config,
|
|
2864
|
+
renderAgentSelect,
|
|
2865
|
+
getAgentInfo
|
|
2866
|
+
}) {
|
|
2867
|
+
const { data: channels, isLoading } = useChannels(config);
|
|
2868
|
+
const [createOpen, setCreateOpen] = useState13(false);
|
|
2869
|
+
return /* @__PURE__ */ jsxs17("div", { className: "flex flex-col gap-6 p-4 flex-1 min-h-0 overflow-y-auto", children: [
|
|
2870
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex items-center justify-between", children: [
|
|
2871
|
+
/* @__PURE__ */ jsxs17("div", { children: [
|
|
2872
|
+
/* @__PURE__ */ jsx19("h1", { className: "text-xl font-semibold", children: "Canais" }),
|
|
2873
|
+
/* @__PURE__ */ jsx19("p", { className: "text-sm text-muted-foreground", children: "Gerencie seus canais de comunica\xE7\xE3o" })
|
|
2874
|
+
] }),
|
|
2875
|
+
/* @__PURE__ */ jsxs17(Button14, { onClick: () => setCreateOpen(true), children: [
|
|
2876
|
+
/* @__PURE__ */ jsx19(Plus2, { className: "mr-2 h-4 w-4" }),
|
|
2877
|
+
"Novo Canal"
|
|
2878
|
+
] })
|
|
2879
|
+
] }),
|
|
2880
|
+
isLoading ? /* @__PURE__ */ jsx19("div", { className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3", children: [1, 2, 3].map((i) => /* @__PURE__ */ jsxs17("div", { className: "rounded-lg border p-4 space-y-3", children: [
|
|
2881
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-2", children: [
|
|
2882
|
+
/* @__PURE__ */ jsx19(Skeleton5, { className: "h-9 w-9 rounded-md" }),
|
|
2883
|
+
/* @__PURE__ */ jsxs17("div", { className: "space-y-1", children: [
|
|
2884
|
+
/* @__PURE__ */ jsx19(Skeleton5, { className: "h-4 w-24" }),
|
|
2885
|
+
/* @__PURE__ */ jsx19(Skeleton5, { className: "h-3 w-32" })
|
|
2886
|
+
] })
|
|
2887
|
+
] }),
|
|
2888
|
+
/* @__PURE__ */ jsx19(Skeleton5, { className: "h-8 w-full" })
|
|
2889
|
+
] }, i)) }) : !channels?.length ? /* @__PURE__ */ jsxs17("div", { className: "flex flex-col items-center justify-center py-12 text-muted-foreground gap-3", children: [
|
|
2890
|
+
/* @__PURE__ */ jsx19(WhatsappIcon, { className: "h-12 w-12 opacity-20" }),
|
|
2891
|
+
/* @__PURE__ */ jsx19("p", { className: "text-sm", children: "Nenhum canal configurado" }),
|
|
2892
|
+
/* @__PURE__ */ jsxs17(Button14, { variant: "outline", onClick: () => setCreateOpen(true), children: [
|
|
2893
|
+
/* @__PURE__ */ jsx19(Plus2, { className: "mr-2 h-4 w-4" }),
|
|
2894
|
+
"Criar primeiro canal"
|
|
2895
|
+
] })
|
|
2896
|
+
] }) : /* @__PURE__ */ jsx19("div", { className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3", children: channels.map((channel) => /* @__PURE__ */ jsx19(
|
|
2897
|
+
ChannelCardWrapper,
|
|
2898
|
+
{
|
|
2899
|
+
channel,
|
|
2900
|
+
config,
|
|
2901
|
+
renderAgentSelect,
|
|
2902
|
+
getAgentInfo
|
|
2903
|
+
},
|
|
2904
|
+
channel.id
|
|
2905
|
+
)) }),
|
|
2906
|
+
/* @__PURE__ */ jsx19(
|
|
2907
|
+
ChannelCreateDialog,
|
|
2908
|
+
{
|
|
2909
|
+
open: createOpen,
|
|
2910
|
+
onOpenChange: setCreateOpen,
|
|
2911
|
+
config,
|
|
2912
|
+
renderAgentSelect
|
|
2913
|
+
}
|
|
2914
|
+
)
|
|
2915
|
+
] });
|
|
2916
|
+
}
|
|
2917
|
+
|
|
2918
|
+
// src/components/contacts-page.tsx
|
|
2919
|
+
import { useState as useState14 } from "react";
|
|
2920
|
+
import { Button as Button15 } from "@greatapps/greatauth-ui/ui";
|
|
2921
|
+
import { Plus as Plus3 } from "lucide-react";
|
|
2922
|
+
import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2923
|
+
function ContactsPage({ config }) {
|
|
2924
|
+
const [createOpen, setCreateOpen] = useState14(false);
|
|
2925
|
+
return /* @__PURE__ */ jsxs18("div", { className: "flex flex-col gap-6 p-4 flex-1 min-h-0 overflow-y-auto", children: [
|
|
2926
|
+
/* @__PURE__ */ jsxs18("div", { className: "flex items-center justify-between", children: [
|
|
2927
|
+
/* @__PURE__ */ jsxs18("div", { children: [
|
|
2928
|
+
/* @__PURE__ */ jsx20("h1", { className: "text-xl font-semibold", children: "Contatos" }),
|
|
2929
|
+
/* @__PURE__ */ jsx20("p", { className: "text-sm text-muted-foreground", children: "Gerencie seus contatos de conversas" })
|
|
2930
|
+
] }),
|
|
2931
|
+
/* @__PURE__ */ jsxs18(Button15, { onClick: () => setCreateOpen(true), children: [
|
|
2932
|
+
/* @__PURE__ */ jsx20(Plus3, { className: "mr-2 h-4 w-4" }),
|
|
2933
|
+
"Novo Contato"
|
|
2934
|
+
] })
|
|
2935
|
+
] }),
|
|
2936
|
+
/* @__PURE__ */ jsx20(ContactsTable, { config }),
|
|
2937
|
+
/* @__PURE__ */ jsx20(
|
|
2938
|
+
ContactFormDialog,
|
|
2939
|
+
{
|
|
2940
|
+
open: createOpen,
|
|
2941
|
+
onOpenChange: setCreateOpen,
|
|
2942
|
+
config
|
|
2943
|
+
}
|
|
2944
|
+
)
|
|
2945
|
+
] });
|
|
2946
|
+
}
|
|
2947
|
+
|
|
2948
|
+
// src/components/chat-dashboard.tsx
|
|
2949
|
+
import { useState as useState15, useMemo as useMemo5 } from "react";
|
|
2950
|
+
import {
|
|
2951
|
+
Card,
|
|
2952
|
+
CardContent,
|
|
2953
|
+
CardHeader,
|
|
2954
|
+
CardTitle,
|
|
2955
|
+
Badge as Badge3,
|
|
2956
|
+
Progress,
|
|
2957
|
+
Skeleton as Skeleton6,
|
|
2958
|
+
cn as cn6
|
|
2959
|
+
} from "@greatapps/greatauth-ui/ui";
|
|
2960
|
+
import {
|
|
2961
|
+
Inbox as InboxIcon2,
|
|
2962
|
+
MessageCircle as MessageCircle2,
|
|
2963
|
+
Clock as Clock2,
|
|
2964
|
+
CircleCheck,
|
|
2965
|
+
ArrowRight
|
|
2966
|
+
} from "lucide-react";
|
|
2967
|
+
import { formatDistanceToNow as formatDistanceToNow2 } from "date-fns";
|
|
2968
|
+
import { ptBR as ptBR5 } from "date-fns/locale";
|
|
2969
|
+
import { Fragment as Fragment6, jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
2970
|
+
function getGreeting(userName) {
|
|
2971
|
+
const hour = (/* @__PURE__ */ new Date()).getHours();
|
|
2972
|
+
const prefix = hour < 12 ? "Bom dia" : hour < 18 ? "Boa tarde" : "Boa noite";
|
|
2973
|
+
return userName ? `${prefix}, ${userName}!` : `${prefix}!`;
|
|
2974
|
+
}
|
|
2975
|
+
var statusColors2 = {
|
|
2976
|
+
open: "bg-green-500/10 text-green-600 border-green-200",
|
|
2977
|
+
pending: "bg-yellow-500/10 text-yellow-600 border-yellow-200",
|
|
2978
|
+
resolved: "bg-zinc-500/10 text-zinc-500 border-zinc-200"
|
|
2979
|
+
};
|
|
2980
|
+
var statusLabels2 = {
|
|
2981
|
+
open: "Aberta",
|
|
2982
|
+
pending: "Pendente",
|
|
2983
|
+
resolved: "Resolvida"
|
|
2984
|
+
};
|
|
2985
|
+
function StatCard({
|
|
2986
|
+
title,
|
|
2987
|
+
value,
|
|
2988
|
+
total,
|
|
2989
|
+
icon: Icon,
|
|
2990
|
+
loading,
|
|
2991
|
+
accentColor,
|
|
2992
|
+
onClick
|
|
2993
|
+
}) {
|
|
2994
|
+
const pct = total && value ? Math.round(value / total * 100) : 0;
|
|
2995
|
+
return /* @__PURE__ */ jsxs19(
|
|
2996
|
+
Card,
|
|
2997
|
+
{
|
|
2998
|
+
className: cn6("cursor-pointer transition-shadow hover:shadow-md border-l-4", accentColor),
|
|
2999
|
+
onClick,
|
|
3000
|
+
children: [
|
|
3001
|
+
/* @__PURE__ */ jsxs19(CardHeader, { className: "flex flex-row items-center justify-between pb-2", children: [
|
|
3002
|
+
/* @__PURE__ */ jsx21(CardTitle, { className: "text-sm font-medium text-muted-foreground", children: title }),
|
|
3003
|
+
/* @__PURE__ */ jsx21(Icon, { className: "h-4 w-4 text-muted-foreground" })
|
|
3004
|
+
] }),
|
|
3005
|
+
/* @__PURE__ */ jsx21(CardContent, { className: "space-y-2", children: loading ? /* @__PURE__ */ jsx21(Skeleton6, { className: "h-8 w-16" }) : /* @__PURE__ */ jsxs19(Fragment6, { children: [
|
|
3006
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex items-baseline gap-2", children: [
|
|
3007
|
+
/* @__PURE__ */ jsx21("p", { className: "text-2xl font-bold", children: value ?? 0 }),
|
|
3008
|
+
total !== void 0 && total > 0 && title !== "Total" && /* @__PURE__ */ jsxs19("span", { className: "text-xs text-muted-foreground", children: [
|
|
3009
|
+
"de ",
|
|
3010
|
+
total
|
|
3011
|
+
] })
|
|
3012
|
+
] }),
|
|
3013
|
+
title !== "Total" && /* @__PURE__ */ jsx21(Progress, { value: pct, className: "h-1" })
|
|
3014
|
+
] }) })
|
|
3015
|
+
]
|
|
3016
|
+
}
|
|
3017
|
+
);
|
|
3018
|
+
}
|
|
3019
|
+
function ChannelHealthCard({
|
|
3020
|
+
channel,
|
|
3021
|
+
config,
|
|
3022
|
+
onClick
|
|
3023
|
+
}) {
|
|
3024
|
+
const { data: status } = useChannelWhatsappStatus(config, channel.id);
|
|
3025
|
+
return /* @__PURE__ */ jsxs19(
|
|
3026
|
+
"div",
|
|
3027
|
+
{
|
|
3028
|
+
className: "flex items-center gap-3 rounded-lg border p-3 cursor-pointer transition-colors hover:bg-accent",
|
|
3029
|
+
onClick,
|
|
3030
|
+
children: [
|
|
3031
|
+
/* @__PURE__ */ jsx21("div", { className: "flex h-9 w-9 items-center justify-center rounded-md bg-green-500/10", children: /* @__PURE__ */ jsx21(WhatsappIcon, { className: "h-5 w-5 text-green-600" }) }),
|
|
3032
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex-1 min-w-0", children: [
|
|
3033
|
+
/* @__PURE__ */ jsx21("p", { className: "text-sm font-medium truncate", children: channel.name }),
|
|
3034
|
+
/* @__PURE__ */ jsx21("p", { className: "text-xs text-muted-foreground truncate", children: channel.identifier || "Sem n\xFAmero" })
|
|
3035
|
+
] }),
|
|
3036
|
+
/* @__PURE__ */ jsx21(WhatsappStatusBadge, { status, hasSession: !!channel.external_id })
|
|
3037
|
+
]
|
|
3038
|
+
}
|
|
3039
|
+
);
|
|
3040
|
+
}
|
|
3041
|
+
function RecentConversationItem({
|
|
3042
|
+
inbox,
|
|
3043
|
+
onClick
|
|
3044
|
+
}) {
|
|
3045
|
+
const timestamp = inbox.last_message_at || inbox.datetime_add;
|
|
3046
|
+
const timeAgo = formatDistanceToNow2(new Date(timestamp), {
|
|
3047
|
+
addSuffix: true,
|
|
3048
|
+
locale: ptBR5
|
|
3049
|
+
});
|
|
3050
|
+
const lastMessage = inbox.last_message_content_type === "text" ? inbox.last_message_content : inbox.last_message_content_type ? `[${inbox.last_message_content_type}]` : null;
|
|
3051
|
+
const directionPrefix = inbox.last_message_direction === "outbound" ? "Voc\xEA: " : "";
|
|
3052
|
+
return /* @__PURE__ */ jsxs19(
|
|
3053
|
+
"div",
|
|
3054
|
+
{
|
|
3055
|
+
className: "flex items-center gap-3 rounded-lg p-3 cursor-pointer transition-colors hover:bg-accent",
|
|
3056
|
+
onClick,
|
|
3057
|
+
children: [
|
|
3058
|
+
/* @__PURE__ */ jsx21(ContactAvatar, { name: inbox.contact_name || "?", className: "h-9 w-9" }),
|
|
3059
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex-1 min-w-0", children: [
|
|
3060
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex items-center justify-between gap-2", children: [
|
|
3061
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-2 min-w-0", children: [
|
|
3062
|
+
/* @__PURE__ */ jsx21("span", { className: "text-sm font-medium truncate", children: inbox.contact_name || "Desconhecido" }),
|
|
3063
|
+
inbox.channel_name && /* @__PURE__ */ jsx21(Badge3, { variant: "outline", className: "shrink-0 text-[10px] px-1.5 py-0 text-muted-foreground", children: inbox.channel_name })
|
|
3064
|
+
] }),
|
|
3065
|
+
/* @__PURE__ */ jsx21("span", { className: "text-xs text-muted-foreground shrink-0", children: timeAgo })
|
|
3066
|
+
] }),
|
|
3067
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex items-center justify-between gap-2 mt-0.5", children: [
|
|
3068
|
+
/* @__PURE__ */ jsx21("p", { className: "text-xs text-muted-foreground truncate", children: lastMessage ? `${directionPrefix}${lastMessage}` : "Sem mensagens" }),
|
|
3069
|
+
/* @__PURE__ */ jsx21(
|
|
3070
|
+
Badge3,
|
|
3071
|
+
{
|
|
3072
|
+
variant: "outline",
|
|
3073
|
+
className: cn6("shrink-0 text-[10px] px-1.5 py-0", statusColors2[inbox.status]),
|
|
3074
|
+
children: statusLabels2[inbox.status] || inbox.status
|
|
3075
|
+
}
|
|
3076
|
+
)
|
|
3077
|
+
] })
|
|
3078
|
+
] })
|
|
3079
|
+
]
|
|
3080
|
+
}
|
|
3081
|
+
);
|
|
3082
|
+
}
|
|
3083
|
+
function ChatDashboard({
|
|
3084
|
+
config,
|
|
3085
|
+
userName,
|
|
3086
|
+
onNavigateToInbox,
|
|
3087
|
+
onNavigateToChannels,
|
|
3088
|
+
renderExtraSection
|
|
3089
|
+
}) {
|
|
3090
|
+
const [selectedChannelId, setSelectedChannelId] = useState15(null);
|
|
3091
|
+
const { data: stats, isLoading: statsLoading } = useInboxStats(config);
|
|
3092
|
+
const { data: inboxes, isLoading: inboxesLoading } = useInboxes(config);
|
|
3093
|
+
const { data: channels, isLoading: channelsLoading } = useChannels(config);
|
|
3094
|
+
const filteredInboxes = useMemo5(() => {
|
|
3095
|
+
if (!inboxes) return [];
|
|
3096
|
+
if (!selectedChannelId) return inboxes;
|
|
3097
|
+
return inboxes.filter((i) => i.id_channel === selectedChannelId);
|
|
3098
|
+
}, [inboxes, selectedChannelId]);
|
|
3099
|
+
const filteredStats = useMemo5(() => {
|
|
3100
|
+
if (!selectedChannelId) return stats;
|
|
3101
|
+
const open = filteredInboxes.filter((i) => i.status === "open").length;
|
|
3102
|
+
const pending = filteredInboxes.filter((i) => i.status === "pending").length;
|
|
3103
|
+
const resolved = filteredInboxes.filter((i) => i.status === "resolved").length;
|
|
3104
|
+
return { total: filteredInboxes.length, open, pending, resolved };
|
|
3105
|
+
}, [stats, filteredInboxes, selectedChannelId]);
|
|
3106
|
+
const recentInboxes = useMemo5(() => {
|
|
3107
|
+
return [...filteredInboxes].sort((a, b) => {
|
|
3108
|
+
const da = a.last_message_at || a.datetime_add;
|
|
3109
|
+
const db = b.last_message_at || b.datetime_add;
|
|
3110
|
+
return new Date(db).getTime() - new Date(da).getTime();
|
|
3111
|
+
}).slice(0, 5);
|
|
3112
|
+
}, [filteredInboxes]);
|
|
3113
|
+
return /* @__PURE__ */ jsxs19("div", { className: "flex flex-col gap-6 p-4 flex-1 min-h-0 overflow-y-auto", children: [
|
|
3114
|
+
/* @__PURE__ */ jsxs19("div", { children: [
|
|
3115
|
+
/* @__PURE__ */ jsx21("h1", { className: "text-xl font-semibold", children: getGreeting(userName) }),
|
|
3116
|
+
/* @__PURE__ */ jsx21("p", { className: "text-sm text-muted-foreground", children: "Aqui est\xE1 o resumo das suas conversas e canais." })
|
|
3117
|
+
] }),
|
|
3118
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-2 flex-wrap", children: [
|
|
3119
|
+
/* @__PURE__ */ jsx21(
|
|
3120
|
+
"button",
|
|
3121
|
+
{
|
|
3122
|
+
className: cn6(
|
|
3123
|
+
"inline-flex items-center gap-1.5 rounded-full border px-3 py-1 text-xs font-medium transition-colors",
|
|
3124
|
+
!selectedChannelId ? "bg-primary text-primary-foreground border-primary" : "bg-background text-muted-foreground hover:bg-accent hover:text-accent-foreground"
|
|
3125
|
+
),
|
|
3126
|
+
onClick: () => setSelectedChannelId(null),
|
|
3127
|
+
children: "Todos os canais"
|
|
3128
|
+
}
|
|
3129
|
+
),
|
|
3130
|
+
channelsLoading ? /* @__PURE__ */ jsxs19(Fragment6, { children: [
|
|
3131
|
+
/* @__PURE__ */ jsx21(Skeleton6, { className: "h-7 w-24 rounded-full" }),
|
|
3132
|
+
/* @__PURE__ */ jsx21(Skeleton6, { className: "h-7 w-28 rounded-full" })
|
|
3133
|
+
] }) : channels?.map((channel) => /* @__PURE__ */ jsxs19(
|
|
3134
|
+
"button",
|
|
3135
|
+
{
|
|
3136
|
+
className: cn6(
|
|
3137
|
+
"inline-flex items-center gap-1.5 rounded-full border px-3 py-1 text-xs font-medium transition-colors",
|
|
3138
|
+
selectedChannelId === channel.id ? "bg-primary text-primary-foreground border-primary" : "bg-background text-muted-foreground hover:bg-accent hover:text-accent-foreground"
|
|
3139
|
+
),
|
|
3140
|
+
onClick: () => setSelectedChannelId(channel.id),
|
|
3141
|
+
children: [
|
|
3142
|
+
/* @__PURE__ */ jsx21(WhatsappIcon, { className: "h-3 w-3" }),
|
|
3143
|
+
channel.name
|
|
3144
|
+
]
|
|
3145
|
+
},
|
|
3146
|
+
channel.id
|
|
3147
|
+
))
|
|
3148
|
+
] }),
|
|
3149
|
+
/* @__PURE__ */ jsxs19("div", { className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-4", children: [
|
|
3150
|
+
/* @__PURE__ */ jsx21(
|
|
3151
|
+
StatCard,
|
|
3152
|
+
{
|
|
3153
|
+
title: "Total",
|
|
3154
|
+
value: filteredStats?.total,
|
|
3155
|
+
total: filteredStats?.total,
|
|
3156
|
+
icon: InboxIcon2,
|
|
3157
|
+
loading: statsLoading && !selectedChannelId,
|
|
3158
|
+
accentColor: "border-l-blue-500",
|
|
3159
|
+
onClick: () => onNavigateToInbox?.()
|
|
3160
|
+
}
|
|
3161
|
+
),
|
|
3162
|
+
/* @__PURE__ */ jsx21(
|
|
3163
|
+
StatCard,
|
|
3164
|
+
{
|
|
3165
|
+
title: "Abertas",
|
|
3166
|
+
value: filteredStats?.open,
|
|
3167
|
+
total: filteredStats?.total,
|
|
3168
|
+
icon: MessageCircle2,
|
|
3169
|
+
loading: statsLoading && !selectedChannelId,
|
|
3170
|
+
accentColor: "border-l-green-500",
|
|
3171
|
+
onClick: () => onNavigateToInbox?.({ status: "open" })
|
|
3172
|
+
}
|
|
3173
|
+
),
|
|
3174
|
+
/* @__PURE__ */ jsx21(
|
|
3175
|
+
StatCard,
|
|
3176
|
+
{
|
|
3177
|
+
title: "Pendentes",
|
|
3178
|
+
value: filteredStats?.pending,
|
|
3179
|
+
total: filteredStats?.total,
|
|
3180
|
+
icon: Clock2,
|
|
3181
|
+
loading: statsLoading && !selectedChannelId,
|
|
3182
|
+
accentColor: "border-l-yellow-500",
|
|
3183
|
+
onClick: () => onNavigateToInbox?.({ status: "pending" })
|
|
3184
|
+
}
|
|
3185
|
+
),
|
|
3186
|
+
/* @__PURE__ */ jsx21(
|
|
3187
|
+
StatCard,
|
|
3188
|
+
{
|
|
3189
|
+
title: "Resolvidas",
|
|
3190
|
+
value: filteredStats?.resolved,
|
|
3191
|
+
total: filteredStats?.total,
|
|
3192
|
+
icon: CircleCheck,
|
|
3193
|
+
loading: statsLoading && !selectedChannelId,
|
|
3194
|
+
accentColor: "border-l-zinc-400",
|
|
3195
|
+
onClick: () => onNavigateToInbox?.({ status: "resolved" })
|
|
3196
|
+
}
|
|
3197
|
+
)
|
|
3198
|
+
] }),
|
|
3199
|
+
/* @__PURE__ */ jsxs19(Card, { children: [
|
|
3200
|
+
/* @__PURE__ */ jsxs19(CardHeader, { className: "flex flex-row items-center justify-between", children: [
|
|
3201
|
+
/* @__PURE__ */ jsx21(CardTitle, { className: "text-sm font-medium", children: "Sa\xFAde dos Canais" }),
|
|
3202
|
+
onNavigateToChannels && /* @__PURE__ */ jsxs19(
|
|
3203
|
+
"button",
|
|
3204
|
+
{
|
|
3205
|
+
onClick: onNavigateToChannels,
|
|
3206
|
+
className: "text-xs text-primary hover:underline flex items-center gap-1",
|
|
3207
|
+
children: [
|
|
3208
|
+
"Gerenciar",
|
|
3209
|
+
/* @__PURE__ */ jsx21(ArrowRight, { className: "h-3 w-3" })
|
|
3210
|
+
]
|
|
3211
|
+
}
|
|
3212
|
+
)
|
|
3213
|
+
] }),
|
|
3214
|
+
/* @__PURE__ */ jsx21(CardContent, { children: channelsLoading ? /* @__PURE__ */ jsx21("div", { className: "space-y-3", children: [1, 2].map((i) => /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-3 p-3", children: [
|
|
3215
|
+
/* @__PURE__ */ jsx21(Skeleton6, { className: "h-8 w-8 rounded" }),
|
|
3216
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex-1 space-y-1", children: [
|
|
3217
|
+
/* @__PURE__ */ jsx21(Skeleton6, { className: "h-4 w-24" }),
|
|
3218
|
+
/* @__PURE__ */ jsx21(Skeleton6, { className: "h-3 w-32" })
|
|
3219
|
+
] })
|
|
3220
|
+
] }, i)) }) : !channels?.length ? /* @__PURE__ */ jsx21("div", { className: "flex items-center justify-center h-full text-sm text-muted-foreground py-8", children: "Nenhum canal configurado" }) : /* @__PURE__ */ jsx21("div", { className: "space-y-2", children: channels.map((channel) => /* @__PURE__ */ jsx21(
|
|
3221
|
+
ChannelHealthCard,
|
|
3222
|
+
{
|
|
3223
|
+
channel,
|
|
3224
|
+
config,
|
|
3225
|
+
onClick: () => onNavigateToInbox?.({ channelId: channel.id })
|
|
3226
|
+
},
|
|
3227
|
+
channel.id
|
|
3228
|
+
)) }) })
|
|
3229
|
+
] }),
|
|
3230
|
+
renderExtraSection?.(),
|
|
3231
|
+
/* @__PURE__ */ jsxs19(Card, { children: [
|
|
3232
|
+
/* @__PURE__ */ jsxs19(CardHeader, { className: "flex flex-row items-center justify-between", children: [
|
|
3233
|
+
/* @__PURE__ */ jsx21(CardTitle, { className: "text-sm font-medium", children: "Conversas Recentes" }),
|
|
3234
|
+
onNavigateToInbox && /* @__PURE__ */ jsxs19(
|
|
3235
|
+
"button",
|
|
3236
|
+
{
|
|
3237
|
+
onClick: () => onNavigateToInbox(),
|
|
3238
|
+
className: "text-xs text-primary hover:underline flex items-center gap-1",
|
|
3239
|
+
children: [
|
|
3240
|
+
"Ver todas",
|
|
3241
|
+
/* @__PURE__ */ jsx21(ArrowRight, { className: "h-3 w-3" })
|
|
3242
|
+
]
|
|
3243
|
+
}
|
|
3244
|
+
)
|
|
3245
|
+
] }),
|
|
3246
|
+
/* @__PURE__ */ jsx21(CardContent, { className: "p-0", children: inboxesLoading ? /* @__PURE__ */ jsx21("div", { className: "space-y-2 p-4", children: [1, 2, 3].map((i) => /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-3 p-3", children: [
|
|
3247
|
+
/* @__PURE__ */ jsx21(Skeleton6, { className: "h-9 w-9 rounded-full shrink-0" }),
|
|
3248
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex-1 space-y-1.5", children: [
|
|
3249
|
+
/* @__PURE__ */ jsx21(Skeleton6, { className: "h-4 w-28" }),
|
|
3250
|
+
/* @__PURE__ */ jsx21(Skeleton6, { className: "h-3 w-40" })
|
|
3251
|
+
] })
|
|
3252
|
+
] }, i)) }) : recentInboxes.length === 0 ? /* @__PURE__ */ jsx21("div", { className: "flex items-center justify-center py-8 text-sm text-muted-foreground", children: "Nenhuma conversa encontrada" }) : /* @__PURE__ */ jsx21("div", { className: "divide-y", children: recentInboxes.map((inbox) => /* @__PURE__ */ jsx21(
|
|
3253
|
+
RecentConversationItem,
|
|
3254
|
+
{
|
|
3255
|
+
inbox,
|
|
3256
|
+
onClick: () => onNavigateToInbox?.()
|
|
3257
|
+
},
|
|
3258
|
+
inbox.id
|
|
3259
|
+
)) }) })
|
|
3260
|
+
] })
|
|
3261
|
+
] });
|
|
3262
|
+
}
|
|
3263
|
+
export {
|
|
3264
|
+
ChannelCard,
|
|
3265
|
+
ChannelCreateDialog,
|
|
3266
|
+
ChannelEditDialog,
|
|
3267
|
+
ChannelsPage,
|
|
3268
|
+
ChatDashboard,
|
|
3269
|
+
ChatInput,
|
|
3270
|
+
ChatView,
|
|
3271
|
+
ContactAvatar,
|
|
3272
|
+
ContactFormDialog,
|
|
3273
|
+
ContactInfoPanel,
|
|
3274
|
+
ContactsPage,
|
|
3275
|
+
ContactsTable,
|
|
3276
|
+
DEFAULT_CHANNEL_STATUS_POLLING,
|
|
3277
|
+
DEFAULT_INBOX_POLLING,
|
|
3278
|
+
DEFAULT_MESSAGES_POLLING,
|
|
3279
|
+
DEFAULT_QR_POLLING,
|
|
3280
|
+
DataTable,
|
|
3281
|
+
InboxItem,
|
|
3282
|
+
InboxPage,
|
|
3283
|
+
InboxSidebar,
|
|
3284
|
+
MessageBubble,
|
|
3285
|
+
NewConversationDialog,
|
|
3286
|
+
WhatsappIcon,
|
|
3287
|
+
WhatsappQrDialog,
|
|
3288
|
+
WhatsappStatusBadge,
|
|
3289
|
+
cn7 as cn,
|
|
2619
3290
|
createGchatClient,
|
|
2620
3291
|
formatDateGroup,
|
|
2621
3292
|
formatMessageTime,
|