@alfatech/livechat 2024.12.3-1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/.github/workflows/release.yml +33 -0
  2. package/.husky/pre-commit +2 -0
  3. package/README.md +30 -0
  4. package/biome.json +55 -0
  5. package/index.html +20 -0
  6. package/package.json +43 -0
  7. package/postcss.config.cjs +5 -0
  8. package/public/vite.svg +1 -0
  9. package/src/api/base.api.ts +118 -0
  10. package/src/api/error.ts +109 -0
  11. package/src/assets/react.svg +1 -0
  12. package/src/components/app/WidgetProvider.tsx +80 -0
  13. package/src/components/app/button/index.tsx +47 -0
  14. package/src/components/app/button/types.ts +68 -0
  15. package/src/components/app/card/profile.tsx +33 -0
  16. package/src/components/app/icon/index.tsx +144 -0
  17. package/src/components/app/input/checkbox.tsx +115 -0
  18. package/src/components/app/input/index.tsx +133 -0
  19. package/src/components/app/input/label.tsx +33 -0
  20. package/src/components/app/input/radio.tsx +143 -0
  21. package/src/components/app/input/select.tsx +54 -0
  22. package/src/components/app/input/textarea.tsx +68 -0
  23. package/src/components/app/input/toggle.tsx +162 -0
  24. package/src/components/app/input/verification.tsx +111 -0
  25. package/src/features/chat/chat.api.ts +30 -0
  26. package/src/features/chat/chat.types.ts +50 -0
  27. package/src/features/chat/partials/ChatCreateForm.tsx +103 -0
  28. package/src/features/chat/partials/ChatMessageFormFooter.tsx +67 -0
  29. package/src/features/chat/partials/ChatMessageSection.tsx +103 -0
  30. package/src/features/widget/components/WidgetIcon.tsx +26 -0
  31. package/src/features/widget/contexts/page-tracker.tsx +74 -0
  32. package/src/features/widget/hooks/page-tracker.tsx +57 -0
  33. package/src/features/widget/widget.api.ts +14 -0
  34. package/src/features/widget/widget.store.ts +16 -0
  35. package/src/features/widget/widget.types.ts +28 -0
  36. package/src/index.css +40 -0
  37. package/src/layouts/auth.tsx +17 -0
  38. package/src/layouts/chat.tsx +18 -0
  39. package/src/lib/cdn.tsx +3 -0
  40. package/src/lib/cookie.tsx +7 -0
  41. package/src/lib/debounce.tsx +23 -0
  42. package/src/lib/hooks/cookie.tsx +22 -0
  43. package/src/lib/hooks/dayjs.tsx +10 -0
  44. package/src/lib/hooks/dom.tsx +26 -0
  45. package/src/lib/hooks/form.tsx +26 -0
  46. package/src/lib/hooks/router.tsx +31 -0
  47. package/src/lib/list.tsx +14 -0
  48. package/src/lib/obj.tsx +23 -0
  49. package/src/lib/phone.tsx +12 -0
  50. package/src/main.tsx +31 -0
  51. package/src/pages/auth/registration-view.tsx +67 -0
  52. package/src/pages/chat/chat-detail-view.tsx +200 -0
  53. package/src/router/router.tsx +17 -0
  54. package/src/router/routes/auth-routes.ts +7 -0
  55. package/src/router/routes/chat-routes.ts +7 -0
  56. package/src/router/routes/index.ts +8 -0
  57. package/src/router/routes/routes.types.ts +0 -0
  58. package/src/types/i18n.ts +11 -0
  59. package/src/vite-env.d.ts +1 -0
  60. package/src/widget.tsx +19 -0
  61. package/src/ws/events.tsx +69 -0
  62. package/src/ws/guard.tsx +16 -0
  63. package/src/ws/hooks.tsx +122 -0
  64. package/tailwind.config.js +27 -0
  65. package/tsconfig.app.json +29 -0
  66. package/tsconfig.app.tsbuildinfo +1 -0
  67. package/tsconfig.json +7 -0
  68. package/tsconfig.node.json +22 -0
  69. package/tsconfig.node.tsbuildinfo +1 -0
  70. package/version.cjs +5 -0
  71. package/vite.config.ts +14 -0
@@ -0,0 +1,200 @@
1
+ import ProfileCard from "@/components/app/card/profile";
2
+ import Icon from "@/components/app/icon";
3
+ import WidgetProvider from "@/components/app/WidgetProvider";
4
+ import { chatClear } from "@/features/chat/chat.api";
5
+ import type {
6
+ ChatViewResult,
7
+ MessageListItem,
8
+ } from "@/features/chat/chat.types";
9
+ import ChatMessageFormFooter from "@/features/chat/partials/ChatMessageFormFooter";
10
+ import ChatMessageSection from "@/features/chat/partials/ChatMessageSection";
11
+ import { usePageTrackingWS } from "@/features/widget/hooks/page-tracker";
12
+ import { useWidgetStore } from "@/features/widget/widget.store";
13
+ import WidgetChatLayout from "@/layouts/chat";
14
+ import { useRouter } from "@/lib/hooks/router";
15
+ import { ReceiveEvents, SendEvents } from "@/ws/events";
16
+ import WebsocketGuard from "@/ws/guard";
17
+ import { useWebsocket } from "@/ws/hooks";
18
+ import { useCallback, useEffect, useState } from "react";
19
+
20
+ function ChatDetailView() {
21
+ const { widget, setOpen } = useWidgetStore();
22
+ const socket = useWebsocket();
23
+ const router = useRouter();
24
+ const [chat, setChat] = useState<ChatViewResult | null>(null);
25
+ const [messages, setMessages] = useState<MessageListItem[]>([]);
26
+ const [isTyping, setIsTyping] = useState(false);
27
+ const [closeVisible, setCloseVisible] = useState(false);
28
+ const [shortcutMessages, setShortcutMessages] = useState<MessageListItem[]>(
29
+ [],
30
+ );
31
+
32
+ const onClose = () => {
33
+ socket?.emit(SendEvents.ChatClose, {});
34
+ setOpen(false);
35
+ chatClear(widget!.client_id);
36
+ };
37
+
38
+ useEffect(() => {
39
+ socket?.emit(SendEvents.ChatView, {}, (chat) => {
40
+ if (chat === null) {
41
+ setOpen(false);
42
+ chatClear(widget!.client_id);
43
+ router.push("registration");
44
+ return;
45
+ }
46
+ setChat(chat);
47
+ });
48
+ }, []);
49
+
50
+ const addNewMessage = useCallback(
51
+ (msg: MessageListItem) => {
52
+ setMessages([...messages, msg]);
53
+ },
54
+ [messages],
55
+ );
56
+
57
+ useEffect(() => {
58
+ if (!socket) return;
59
+ socket.on(ReceiveEvents.MessageAgentCreate, (msg) => {
60
+ const m = {
61
+ content: msg.content,
62
+ created_at: msg.created_at,
63
+ files: msg.files,
64
+ id: msg._id,
65
+ sender_type: msg.sender_type,
66
+ answers: msg.answers,
67
+ reply_id: msg.reply_id,
68
+ };
69
+ if (shortcutMessages.length > 0) {
70
+ setShortcutMessages((prev) => [...prev, m]);
71
+ return;
72
+ }
73
+ if (msg.is_shortcut) setShortcutMessages([m]);
74
+ else addNewMessage(m);
75
+ });
76
+ socket.on(ReceiveEvents.ChatUserAssignee, (assignee) => {
77
+ setChat({
78
+ ...chat,
79
+ agent_name: assignee.name,
80
+ agent_avatar: assignee.avatar,
81
+ is_uploadable: chat?.is_uploadable ?? false,
82
+ });
83
+ });
84
+ socket.on(ReceiveEvents.MessageAgentTyping, () => {
85
+ setIsTyping(true);
86
+ });
87
+ return () => {
88
+ socket.off(ReceiveEvents.MessageAgentCreate);
89
+ socket.off(ReceiveEvents.ChatUserAssignee);
90
+ socket.off(ReceiveEvents.MessageAgentTyping);
91
+ };
92
+ }, [addNewMessage]);
93
+
94
+ useEffect(() => {
95
+ if (!socket) return;
96
+ socket.emit(SendEvents.MessageList, {}, (msgs) => {
97
+ setMessages(msgs);
98
+ });
99
+ }, []);
100
+
101
+ useEffect(() => {
102
+ const timeout = setTimeout(() => {
103
+ setIsTyping(false);
104
+ }, 1000);
105
+ return () => clearTimeout(timeout);
106
+ }, [isTyping]);
107
+
108
+ useEffect(() => {
109
+ if (!widget || shortcutMessages.length === 0) return;
110
+ const tmMS =
111
+ (widget.writing_timeout || 650) *
112
+ shortcutMessages[0].content.split(" ").length;
113
+ const timeout = setTimeout(() => {
114
+ addNewMessage(shortcutMessages[0]);
115
+ setShortcutMessages(shortcutMessages.slice(1));
116
+ }, tmMS);
117
+ return () => clearTimeout(timeout);
118
+ }, [shortcutMessages, widget]);
119
+
120
+ if (!chat) return null;
121
+ return (
122
+ <>
123
+ {closeVisible && (
124
+ <div className="absolute top-0 left-0 backdrop-blur-sm bg-slate-950/20 z-50 h-full w-full rounded-md">
125
+ <div className="flex flex-col items-center justify-center h-full mx-5">
126
+ <div className="bg-white p-4 rounded-md">
127
+ <div className="text-lg font-semibold text-neutral-900">
128
+ Sohbeti kapatmak istediğinize emin misiniz?
129
+ </div>
130
+ <div className="flex justify-between mt-4">
131
+ <button
132
+ type="button"
133
+ className="bg-red-500 text-white px-4 py-2 rounded-md"
134
+ onClick={onClose}
135
+ >
136
+ Evet
137
+ </button>
138
+ <button
139
+ type="button"
140
+ className="bg-neutral-200 text-neutral-900 px-4 py-2 rounded-md"
141
+ onClick={() => setCloseVisible(false)}
142
+ >
143
+ Vazgeç
144
+ </button>
145
+ </div>
146
+ </div>
147
+ </div>
148
+ </div>
149
+ )}
150
+
151
+ <section className="bg-white h-full w-full rounded-md border flex flex-col">
152
+ <header className="border-b p-4 bg-zink-600 rounded-t-md flex justify-between items-center">
153
+ {chat?.agent_name ? (
154
+ <ProfileCard
155
+ name={chat.agent_name}
156
+ avatar={chat.agent_avatar}
157
+ className="text-neutral-300"
158
+ />
159
+ ) : (
160
+ <div className="text-white">Chat with us</div>
161
+ )}
162
+ <button
163
+ type="button"
164
+ className="text-white"
165
+ onClick={() => setCloseVisible(true)}
166
+ >
167
+ <Icon.X className="w-6 h-6 cursor-pointer" />
168
+ </button>
169
+ </header>
170
+ <ChatMessageSection
171
+ messages={messages}
172
+ isTyping={isTyping || shortcutMessages.length > 0}
173
+ />
174
+ <ChatMessageFormFooter
175
+ onNewMessage={(msg) => {
176
+ addNewMessage(msg);
177
+ }}
178
+ />
179
+ </section>
180
+ </>
181
+ );
182
+ }
183
+
184
+ function Tracking() {
185
+ usePageTrackingWS();
186
+ return null;
187
+ }
188
+
189
+ export default function ChatDetail() {
190
+ return (
191
+ <WebsocketGuard>
192
+ <WidgetProvider defaultOpen>
193
+ <WidgetChatLayout>
194
+ <ChatDetailView />
195
+ </WidgetChatLayout>
196
+ </WidgetProvider>
197
+ <Tracking />
198
+ </WebsocketGuard>
199
+ );
200
+ }
@@ -0,0 +1,17 @@
1
+ import { MemoryRouter, Route, Routes } from "react-router-dom";
2
+ import { protectedRoutes, publicRoutes } from "./routes";
3
+
4
+ export default function AppRouter() {
5
+ return (
6
+ <MemoryRouter future={{ v7_startTransition: true }}>
7
+ <Routes>
8
+ {protectedRoutes.map((route: any, idx: number) => (
9
+ <Route key={idx} path={route.path} element={<route.component />} />
10
+ ))}
11
+ {publicRoutes.map((route: any, idx: number) => (
12
+ <Route path={route.path} key={idx} element={<route.component />} />
13
+ ))}
14
+ </Routes>
15
+ </MemoryRouter>
16
+ );
17
+ }
@@ -0,0 +1,7 @@
1
+ import RegistrationView from "../../pages/auth/registration-view";
2
+
3
+ export const authRoutes = [
4
+ { path: "/", component: RegistrationView, name: "registration" },
5
+ ] as const;
6
+
7
+ export type AuthRouteNames = (typeof authRoutes)[number]["name"];
@@ -0,0 +1,7 @@
1
+ import ChatDetailView from "@/pages/chat/chat-detail-view";
2
+
3
+ export const chatRoutes = [
4
+ { path: "/chat", component: ChatDetailView, name: "chat" },
5
+ ] as const;
6
+
7
+ export type ChatRouteNames = (typeof chatRoutes)[number]["name"];
@@ -0,0 +1,8 @@
1
+ import { authRoutes } from "./auth-routes";
2
+ import { chatRoutes } from "./chat-routes";
3
+
4
+ export const protectedRoutes = [...chatRoutes];
5
+
6
+ export const publicRoutes = [...authRoutes];
7
+
8
+ export const allRoutes = [...protectedRoutes, ...publicRoutes];
File without changes
@@ -0,0 +1,11 @@
1
+ export enum Timezone {
2
+ Istanbul = "Europe/Istanbul",
3
+ Berlin = "Europe/Berlin",
4
+ London = "Europe/London",
5
+ NewYork = "America/New_York",
6
+ }
7
+
8
+ export enum Lang {
9
+ Tr = "tr",
10
+ En = "en",
11
+ }
@@ -0,0 +1 @@
1
+ /// <reference types="vite/client" />
package/src/widget.tsx ADDED
@@ -0,0 +1,19 @@
1
+ import { createRoot } from "react-dom/client";
2
+ import "./index.css";
3
+ import App from "./main.tsx";
4
+ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
5
+
6
+ type Options = {
7
+ container: HTMLElement;
8
+ link_id: string;
9
+ };
10
+
11
+ const queryClient = new QueryClient();
12
+
13
+ export default function widget({ container, link_id }: Options) {
14
+ createRoot(container).render(
15
+ <QueryClientProvider client={queryClient}>
16
+ <App link_id={link_id} />
17
+ </QueryClientProvider>,
18
+ );
19
+ }
@@ -0,0 +1,69 @@
1
+ import type {
2
+ ChatViewResult,
3
+ MessageEntity,
4
+ MessageListItem,
5
+ } from "@/features/chat/chat.types";
6
+
7
+ export enum SendEvents {
8
+ ChatView = "chat:user:view",
9
+ ChatClose = "chat:user:close",
10
+ MessageList = "message:list",
11
+ MessageCreate = "message:create",
12
+ MessageTyping = "message:typing",
13
+ WidgetOpen = "widget:open",
14
+ WidgetClose = "widget:close",
15
+ PageChange = "page-change",
16
+ }
17
+
18
+ export enum ReceiveEvents {
19
+ MessageAgentCreate = "message:agent:create",
20
+ MessageAgentTyping = "message:agent:typing",
21
+ Banned = "banned",
22
+ ChatUserClose = "chat:user:close",
23
+ ChatUserAssignee = "chat:user:assignee",
24
+ }
25
+
26
+ export type ReceiveEventTypes = {
27
+ [ReceiveEvents.MessageAgentCreate]: MessageEntity;
28
+ [ReceiveEvents.MessageAgentTyping]: {};
29
+ [ReceiveEvents.Banned]: {};
30
+ [ReceiveEvents.ChatUserClose]: {};
31
+ [ReceiveEvents.ChatUserAssignee]: {
32
+ chat_id: string;
33
+ id: string;
34
+ title: string;
35
+ name: string;
36
+ avatar: string;
37
+ };
38
+ };
39
+
40
+ export type SendEventTypes = {
41
+ [SendEvents.ChatView]: {};
42
+ [SendEvents.MessageList]: {};
43
+ [SendEvents.ChatClose]: {};
44
+ [SendEvents.MessageCreate]: {
45
+ content: string;
46
+ };
47
+ [SendEvents.WidgetOpen]: {};
48
+ [SendEvents.WidgetClose]: {};
49
+ [SendEvents.PageChange]: {
50
+ page: string;
51
+ };
52
+ [SendEvents.MessageTyping]: {
53
+ content: string;
54
+ };
55
+ };
56
+
57
+ export type EventCallbackTypes = {
58
+ [SendEvents.ChatView]: ChatViewResult;
59
+ [SendEvents.ChatClose]: boolean;
60
+ [SendEvents.MessageList]: MessageListItem[];
61
+ [SendEvents.MessageCreate]: MessageListItem;
62
+ [SendEvents.WidgetOpen]: {};
63
+ [SendEvents.WidgetClose]: {};
64
+ [SendEvents.PageChange]: {};
65
+ [SendEvents.MessageTyping]: {};
66
+ };
67
+
68
+ export type EventCallbackAndSendTypeKeys = keyof EventCallbackTypes &
69
+ keyof SendEventTypes;
@@ -0,0 +1,16 @@
1
+ import { type PropsWithChildren, useEffect } from "react";
2
+ import { useWebsocket } from "./hooks";
3
+
4
+ export default function WebsocketGuard({ children }: PropsWithChildren) {
5
+ const socket = useWebsocket();
6
+
7
+ useEffect(() => {
8
+ if (!socket) return;
9
+ socket.connect();
10
+ }, []);
11
+
12
+ if (!socket || !socket.connected) {
13
+ return null;
14
+ }
15
+ return children;
16
+ }
@@ -0,0 +1,122 @@
1
+ import { createContext, useContext, useState } from "react";
2
+ import { type Socket, io } from "socket.io-client";
3
+ import type {
4
+ EventCallbackAndSendTypeKeys,
5
+ EventCallbackTypes,
6
+ ReceiveEventTypes,
7
+ SendEventTypes,
8
+ } from "./events";
9
+ import { getCookieVal } from "@/lib/cookie";
10
+
11
+ type EventHandler<T = any> = (e: T) => void;
12
+
13
+ type WebSocketContext = {
14
+ socket: Socket | null;
15
+ connected: boolean;
16
+ events: Record<string, EventHandler>;
17
+ connect: () => void;
18
+ reconnect: () => void;
19
+ disconnect: () => void;
20
+ on: <T extends keyof ReceiveEventTypes>(
21
+ event: T,
22
+ handler: EventHandler<ReceiveEventTypes[T]>,
23
+ ) => void;
24
+ off: <T extends keyof ReceiveEventTypes>(event: T) => void;
25
+ emit: <T extends keyof SendEventTypes>(
26
+ event: T,
27
+ data: SendEventTypes[T],
28
+ callback?: (data: EventCallbackTypes[T]) => void,
29
+ ) => void;
30
+ };
31
+
32
+ const websocketContext = createContext<WebSocketContext | null>(null);
33
+
34
+ export const useWebsocket = () => {
35
+ return useContext(websocketContext);
36
+ };
37
+
38
+ export const WebSocketProvider = ({ children }: React.PropsWithChildren) => {
39
+ const [socket, setSocket] = useState<Socket | null>(null);
40
+ const [connected, setConnected] = useState<boolean>(false);
41
+ const [events, setEvents] = useState<Record<string, EventHandler>>({});
42
+
43
+ const connect = () => {
44
+ const s = io(import.meta.env.VITE_WS_URL as string, {
45
+ transports: ["websocket"],
46
+ auth: {
47
+ customer_token: getCookieVal("customer_token"),
48
+ device_id: getCookieVal("device_id"),
49
+ customer_refresh_token: getCookieVal("customer_refresh_token"),
50
+ },
51
+ });
52
+ s.on("error", (err) => {
53
+ console.error("Websocket error", err);
54
+ });
55
+
56
+ s.on("connect", () => {
57
+ setSocket(s);
58
+ setConnected(true);
59
+ });
60
+ };
61
+
62
+ const reconnect = () => {
63
+ if (socket) {
64
+ socket.connect();
65
+ setConnected(true);
66
+ }
67
+ };
68
+
69
+ const disconnect = () => {
70
+ if (socket) {
71
+ socket.disconnect();
72
+ setConnected(false);
73
+ }
74
+ };
75
+
76
+ const on = <T extends keyof ReceiveEventTypes>(
77
+ event: T,
78
+ handler: EventHandler<ReceiveEventTypes[T]>,
79
+ ) => {
80
+ if (socket) {
81
+ socket.on(event as any, (args: any) => {
82
+ handler(args);
83
+ });
84
+ setEvents({ ...events, [event]: handler });
85
+ }
86
+ };
87
+
88
+ const off = <T extends keyof ReceiveEventTypes>(event: T) => {
89
+ if (socket && events[event]) {
90
+ socket.off(event, events[event] as any);
91
+ delete events[event];
92
+ }
93
+ };
94
+
95
+ const emit = <T extends EventCallbackAndSendTypeKeys>(
96
+ event: T,
97
+ data: SendEventTypes[T],
98
+ callback?: (data: EventCallbackTypes[T]) => void,
99
+ ) => {
100
+ if (socket) {
101
+ socket.emit(event, data, callback);
102
+ }
103
+ };
104
+
105
+ return (
106
+ <websocketContext.Provider
107
+ value={{
108
+ socket,
109
+ connected,
110
+ events,
111
+ connect,
112
+ reconnect,
113
+ disconnect,
114
+ on,
115
+ off,
116
+ emit,
117
+ }}
118
+ >
119
+ {children}
120
+ </websocketContext.Provider>
121
+ );
122
+ };
@@ -0,0 +1,27 @@
1
+ /** @type {import('tailwindcss').Config} */
2
+ export default {
3
+ content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
4
+ theme: {
5
+ extend: {
6
+ width: {
7
+ 86: "22.5rem",
8
+ },
9
+ colors: {
10
+ zink: {
11
+ 50: "#E2EAF3",
12
+ 100: "#C8D7E9",
13
+ 200: "#92AFD3",
14
+ 300: "#5885BC",
15
+ 400: "#395F8E",
16
+ 500: "#233A57",
17
+ 600: "#1C2E45",
18
+ 700: "#132337",
19
+ 800: "#0F1824",
20
+ 900: "#070C12",
21
+ 950: "#030507",
22
+ },
23
+ },
24
+ },
25
+ },
26
+ plugins: [],
27
+ };
@@ -0,0 +1,29 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "useDefineForClassFields": true,
5
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
6
+ "module": "ESNext",
7
+ "skipLibCheck": true,
8
+
9
+ /* Bundler mode */
10
+ "moduleResolution": "bundler",
11
+ "allowImportingTsExtensions": true,
12
+ "isolatedModules": true,
13
+ "moduleDetection": "force",
14
+ "noEmit": true,
15
+ "jsx": "react-jsx",
16
+ "paths": {
17
+ "@/*": ["./src/*"],
18
+ "~/*": ["/*"]
19
+ },
20
+ "baseUrl": ".",
21
+
22
+ /* Linting */
23
+ "strict": true,
24
+ "noUnusedLocals": true,
25
+ "noUnusedParameters": true,
26
+ "noFallthroughCasesInSwitch": true
27
+ },
28
+ "include": ["src"]
29
+ }
@@ -0,0 +1 @@
1
+ {"root":["./src/main.tsx","./src/vite-env.d.ts","./src/widget.tsx","./src/api/base.api.ts","./src/api/error.ts","./src/components/app/WidgetProvider.tsx","./src/components/app/button/index.tsx","./src/components/app/button/types.ts","./src/components/app/card/profile.tsx","./src/components/app/icon/index.tsx","./src/components/app/input/checkbox.tsx","./src/components/app/input/index.tsx","./src/components/app/input/label.tsx","./src/components/app/input/radio.tsx","./src/components/app/input/select.tsx","./src/components/app/input/textarea.tsx","./src/components/app/input/toggle.tsx","./src/components/app/input/verification.tsx","./src/features/chat/chat.api.ts","./src/features/chat/chat.types.ts","./src/features/chat/partials/ChatCreateForm.tsx","./src/features/chat/partials/ChatMessageFormFooter.tsx","./src/features/chat/partials/ChatMessageSection.tsx","./src/features/widget/widget.api.ts","./src/features/widget/widget.store.ts","./src/features/widget/widget.types.ts","./src/features/widget/components/WidgetIcon.tsx","./src/features/widget/contexts/page-tracker.tsx","./src/features/widget/hooks/page-tracker.tsx","./src/layouts/auth.tsx","./src/layouts/chat.tsx","./src/lib/cdn.tsx","./src/lib/cookie.tsx","./src/lib/debounce.tsx","./src/lib/list.tsx","./src/lib/obj.tsx","./src/lib/phone.tsx","./src/lib/hooks/cookie.tsx","./src/lib/hooks/dayjs.tsx","./src/lib/hooks/dom.tsx","./src/lib/hooks/form.tsx","./src/lib/hooks/router.tsx","./src/pages/auth/registration-view.tsx","./src/pages/chat/chat-detail-view.tsx","./src/router/router.tsx","./src/router/routes/auth-routes.ts","./src/router/routes/chat-routes.ts","./src/router/routes/index.ts","./src/router/routes/routes.types.ts","./src/types/i18n.ts","./src/ws/events.tsx","./src/ws/guard.tsx","./src/ws/hooks.tsx"],"version":"5.7.2"}
package/tsconfig.json ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "files": [],
3
+ "references": [
4
+ { "path": "./tsconfig.app.json" },
5
+ { "path": "./tsconfig.node.json" }
6
+ ]
7
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": ["ES2023"],
5
+ "module": "ESNext",
6
+ "skipLibCheck": true,
7
+
8
+ /* Bundler mode */
9
+ "moduleResolution": "bundler",
10
+ "allowImportingTsExtensions": true,
11
+ "isolatedModules": true,
12
+ "moduleDetection": "force",
13
+ "noEmit": true,
14
+
15
+ /* Linting */
16
+ "strict": true,
17
+ "noUnusedLocals": true,
18
+ "noUnusedParameters": true,
19
+ "noFallthroughCasesInSwitch": true
20
+ },
21
+ "include": ["vite.config.ts"]
22
+ }
@@ -0,0 +1 @@
1
+ {"root":["./vite.config.ts"],"version":"5.7.2"}
package/version.cjs ADDED
@@ -0,0 +1,5 @@
1
+ var fs = require("fs");
2
+ var pjson = require("./package.json");
3
+ var nversion = process.argv[2];
4
+ pjson.version = nversion;
5
+ fs.writeFileSync("./package.json", JSON.stringify(pjson, null, 2));
package/vite.config.ts ADDED
@@ -0,0 +1,14 @@
1
+ import { defineConfig } from "vite";
2
+ import react from "@vitejs/plugin-react-swc";
3
+ import { resolve } from "node:path";
4
+
5
+ // https://vitejs.dev/config/
6
+ export default defineConfig({
7
+ plugins: [react()],
8
+ resolve: {
9
+ alias: {
10
+ "@": resolve(__dirname, "src"),
11
+ "~": resolve(__dirname),
12
+ },
13
+ },
14
+ });