@codeswayam/ui 1.1.1 → 1.3.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/README.md +727 -173
- package/dist/components/base/badge.d.ts +1 -1
- package/dist/components/base/button.d.ts +2 -2
- package/dist/components/base/button.d.ts.map +1 -1
- package/dist/components/base/button.js +2 -2
- package/dist/components/brand/BrandFooterSection.d.ts +8 -0
- package/dist/components/brand/BrandFooterSection.d.ts.map +1 -0
- package/dist/components/brand/BrandFooterSection.js +97 -0
- package/dist/components/brand/BrandNav.d.ts +17 -0
- package/dist/components/brand/BrandNav.d.ts.map +1 -0
- package/dist/components/brand/BrandNav.js +64 -0
- package/dist/components/data/DataTable.d.ts +18 -0
- package/dist/components/data/DataTable.d.ts.map +1 -0
- package/dist/components/data/DataTable.js +36 -0
- package/dist/components/data/EmptyState.d.ts +23 -0
- package/dist/components/data/EmptyState.d.ts.map +1 -0
- package/dist/components/data/EmptyState.js +9 -0
- package/dist/components/data/TableToolbar.d.ts +17 -0
- package/dist/components/data/TableToolbar.d.ts.map +1 -0
- package/dist/components/data/TableToolbar.js +21 -0
- package/dist/components/display/CopyButton.d.ts +14 -0
- package/dist/components/display/CopyButton.d.ts.map +1 -0
- package/dist/components/display/CopyButton.js +37 -0
- package/dist/components/display/PageHeader.d.ts +11 -0
- package/dist/components/display/PageHeader.d.ts.map +1 -0
- package/dist/components/display/PageHeader.js +5 -0
- package/dist/components/display/StatCard.d.ts +23 -0
- package/dist/components/display/StatCard.d.ts.map +1 -0
- package/dist/components/display/StatCard.js +6 -0
- package/dist/components/feedback/ConfirmDialog.d.ts +18 -0
- package/dist/components/feedback/ConfirmDialog.d.ts.map +1 -0
- package/dist/components/feedback/ConfirmDialog.js +10 -0
- package/dist/components/feedback/ErrorState.d.ts +10 -0
- package/dist/components/feedback/ErrorState.d.ts.map +1 -0
- package/dist/components/feedback/ErrorState.js +7 -0
- package/dist/components/feedback/Skeleton.d.ts +26 -0
- package/dist/components/feedback/Skeleton.d.ts.map +1 -0
- package/dist/components/feedback/Skeleton.js +31 -0
- package/dist/components/neural/AICreditBadge.d.ts +9 -0
- package/dist/components/neural/AICreditBadge.d.ts.map +1 -0
- package/dist/components/neural/AICreditBadge.js +31 -0
- package/dist/components/neural/AIImageGeneratorModal.d.ts +9 -0
- package/dist/components/neural/AIImageGeneratorModal.d.ts.map +1 -0
- package/dist/components/neural/AIImageGeneratorModal.js +66 -0
- package/dist/components/neural/AIPromptPlayground.d.ts +10 -0
- package/dist/components/neural/AIPromptPlayground.d.ts.map +1 -0
- package/dist/components/neural/AIPromptPlayground.js +66 -0
- package/dist/components/neural/KnowledgeBasePicker.d.ts +18 -0
- package/dist/components/neural/KnowledgeBasePicker.d.ts.map +1 -0
- package/dist/components/neural/KnowledgeBasePicker.js +42 -0
- package/dist/components/neural/WorkflowPicker.d.ts +18 -0
- package/dist/components/neural/WorkflowPicker.d.ts.map +1 -0
- package/dist/components/neural/WorkflowPicker.js +46 -0
- package/dist/components/neural/index.d.ts +11 -0
- package/dist/components/neural/index.d.ts.map +1 -0
- package/dist/components/neural/index.js +5 -0
- package/dist/components/saas/NotificationBell.d.ts +12 -0
- package/dist/components/saas/NotificationBell.d.ts.map +1 -0
- package/dist/components/saas/NotificationBell.js +52 -0
- package/dist/components/saas/status-badge.d.ts +15 -8
- package/dist/components/saas/status-badge.d.ts.map +1 -1
- package/dist/components/saas/status-badge.js +46 -25
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -4
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/useNotifications.d.ts +24 -0
- package/dist/utils/useNotifications.d.ts.map +1 -0
- package/dist/utils/useNotifications.js +71 -0
- package/dist/utils/useWebPush.d.ts +14 -0
- package/dist/utils/useWebPush.d.ts.map +1 -0
- package/dist/utils/useWebPush.js +110 -0
- package/package.json +4 -3
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface InAppNotification {
|
|
2
|
+
id: number;
|
|
3
|
+
userId: number;
|
|
4
|
+
title: string;
|
|
5
|
+
message: string;
|
|
6
|
+
category: "billing" | "security" | "updates" | "marketing" | "system";
|
|
7
|
+
actionUrl?: string | null;
|
|
8
|
+
isRead: boolean;
|
|
9
|
+
readAt?: string | null;
|
|
10
|
+
createdAt: string;
|
|
11
|
+
}
|
|
12
|
+
export interface UseNotificationsOptions {
|
|
13
|
+
apiUrl?: string;
|
|
14
|
+
pollIntervalMs?: number;
|
|
15
|
+
}
|
|
16
|
+
export declare function useNotifications(options?: UseNotificationsOptions): {
|
|
17
|
+
notifications: InAppNotification[];
|
|
18
|
+
unreadCount: number;
|
|
19
|
+
loading: boolean;
|
|
20
|
+
refresh: () => Promise<void>;
|
|
21
|
+
markAsRead: (id: number) => Promise<void>;
|
|
22
|
+
markAllAsRead: () => Promise<void>;
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=useNotifications.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useNotifications.d.ts","sourceRoot":"","sources":["../../src/utils/useNotifications.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;IACtE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,uBAA4B;;;;;qBAoCvD,MAAM;;EA0CpB"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useState, useEffect, useCallback } from "react";
|
|
3
|
+
export function useNotifications(options = {}) {
|
|
4
|
+
const apiUrl = options.apiUrl || process.env.NEXT_PUBLIC_API_URL || "http://localhost:3000";
|
|
5
|
+
const pollIntervalMs = options.pollIntervalMs ?? 30000;
|
|
6
|
+
const [notifications, setNotifications] = useState([]);
|
|
7
|
+
const [unreadCount, setUnreadCount] = useState(0);
|
|
8
|
+
const [loading, setLoading] = useState(false);
|
|
9
|
+
const fetchNotifications = useCallback(async () => {
|
|
10
|
+
try {
|
|
11
|
+
setLoading(true);
|
|
12
|
+
const res = await fetch(`${apiUrl}/notifications/in-app?limit=15`, {
|
|
13
|
+
credentials: "include",
|
|
14
|
+
});
|
|
15
|
+
if (res.ok) {
|
|
16
|
+
const data = await res.json();
|
|
17
|
+
setNotifications(data.notifications || []);
|
|
18
|
+
setUnreadCount(data.unreadCount || 0);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
// Best-effort fetch
|
|
23
|
+
}
|
|
24
|
+
finally {
|
|
25
|
+
setLoading(false);
|
|
26
|
+
}
|
|
27
|
+
}, [apiUrl]);
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
fetchNotifications();
|
|
30
|
+
if (pollIntervalMs > 0) {
|
|
31
|
+
const interval = setInterval(fetchNotifications, pollIntervalMs);
|
|
32
|
+
return () => clearInterval(interval);
|
|
33
|
+
}
|
|
34
|
+
}, [fetchNotifications, pollIntervalMs]);
|
|
35
|
+
const markAsRead = useCallback(async (id) => {
|
|
36
|
+
// Optimistic update
|
|
37
|
+
setNotifications((prev) => prev.map((n) => (n.id === id ? { ...n, isRead: true } : n)));
|
|
38
|
+
setUnreadCount((c) => Math.max(0, c - 1));
|
|
39
|
+
try {
|
|
40
|
+
await fetch(`${apiUrl}/notifications/in-app/${id}/read`, {
|
|
41
|
+
method: "PATCH",
|
|
42
|
+
credentials: "include",
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
// Revert on critical failure if needed
|
|
47
|
+
}
|
|
48
|
+
}, [apiUrl]);
|
|
49
|
+
const markAllAsRead = useCallback(async () => {
|
|
50
|
+
// Optimistic update
|
|
51
|
+
setNotifications((prev) => prev.map((n) => ({ ...n, isRead: true })));
|
|
52
|
+
setUnreadCount(0);
|
|
53
|
+
try {
|
|
54
|
+
await fetch(`${apiUrl}/notifications/in-app/read-all`, {
|
|
55
|
+
method: "POST",
|
|
56
|
+
credentials: "include",
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// Revert if needed
|
|
61
|
+
}
|
|
62
|
+
}, [apiUrl]);
|
|
63
|
+
return {
|
|
64
|
+
notifications,
|
|
65
|
+
unreadCount,
|
|
66
|
+
loading,
|
|
67
|
+
refresh: fetchNotifications,
|
|
68
|
+
markAsRead,
|
|
69
|
+
markAllAsRead,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface UseWebPushOptions {
|
|
2
|
+
apiUrl?: string;
|
|
3
|
+
saasId?: string;
|
|
4
|
+
swPath?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function useWebPush(options?: UseWebPushOptions): {
|
|
7
|
+
isSupported: boolean;
|
|
8
|
+
isSubscribed: boolean;
|
|
9
|
+
permission: NotificationPermission;
|
|
10
|
+
loading: boolean;
|
|
11
|
+
subscribe: () => Promise<boolean>;
|
|
12
|
+
unsubscribe: () => Promise<boolean>;
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=useWebPush.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useWebPush.d.ts","sourceRoot":"","sources":["../../src/utils/useWebPush.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB;;;;;;;EA2GzD"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useState, useEffect, useCallback } from "react";
|
|
3
|
+
function urlBase64ToUint8Array(base64String) {
|
|
4
|
+
const padding = "=".repeat((4 - (base64String.length % 4)) % 4);
|
|
5
|
+
const base64 = (base64String + padding).replace(/-/g, "+").replace(/_/g, "/");
|
|
6
|
+
const rawData = window.atob(base64);
|
|
7
|
+
const outputArray = new Uint8Array(rawData.length);
|
|
8
|
+
for (let i = 0; i < rawData.length; ++i) {
|
|
9
|
+
outputArray[i] = rawData.charCodeAt(i);
|
|
10
|
+
}
|
|
11
|
+
return outputArray;
|
|
12
|
+
}
|
|
13
|
+
export function useWebPush(options = {}) {
|
|
14
|
+
const apiUrl = options.apiUrl || process.env.NEXT_PUBLIC_API_URL || "http://localhost:3000";
|
|
15
|
+
const swPath = options.swPath || "/sw.js";
|
|
16
|
+
const saasId = options.saasId;
|
|
17
|
+
const [isSupported, setIsSupported] = useState(false);
|
|
18
|
+
const [isSubscribed, setIsSubscribed] = useState(false);
|
|
19
|
+
const [permission, setPermission] = useState("default");
|
|
20
|
+
const [loading, setLoading] = useState(false);
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
if (typeof window !== "undefined" && "serviceWorker" in navigator && "PushManager" in window) {
|
|
23
|
+
setIsSupported(true);
|
|
24
|
+
setPermission(Notification.permission);
|
|
25
|
+
navigator.serviceWorker.ready.then((registration) => {
|
|
26
|
+
registration.pushManager.getSubscription().then((sub) => {
|
|
27
|
+
setIsSubscribed(!!sub);
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}, []);
|
|
32
|
+
const subscribe = useCallback(async () => {
|
|
33
|
+
if (!isSupported)
|
|
34
|
+
return false;
|
|
35
|
+
setLoading(true);
|
|
36
|
+
try {
|
|
37
|
+
const perm = await Notification.requestPermission();
|
|
38
|
+
setPermission(perm);
|
|
39
|
+
if (perm !== "granted") {
|
|
40
|
+
setLoading(false);
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
const registration = await navigator.serviceWorker.register(swPath);
|
|
44
|
+
await navigator.serviceWorker.ready;
|
|
45
|
+
// Fetch VAPID key
|
|
46
|
+
const vapidRes = await fetch(`${apiUrl}/notifications/vapid-public-key`);
|
|
47
|
+
if (!vapidRes.ok)
|
|
48
|
+
throw new Error("Failed to get VAPID public key");
|
|
49
|
+
const { publicKey } = await vapidRes.json();
|
|
50
|
+
const subscription = await registration.pushManager.subscribe({
|
|
51
|
+
userVisibleOnly: true,
|
|
52
|
+
applicationServerKey: urlBase64ToUint8Array(publicKey),
|
|
53
|
+
});
|
|
54
|
+
// Send to backend
|
|
55
|
+
const res = await fetch(`${apiUrl}/notifications/subscribe`, {
|
|
56
|
+
method: "POST",
|
|
57
|
+
headers: { "Content-Type": "application/json" },
|
|
58
|
+
credentials: "include",
|
|
59
|
+
body: JSON.stringify({
|
|
60
|
+
subscription: subscription.toJSON(),
|
|
61
|
+
saasId: saasId || null,
|
|
62
|
+
}),
|
|
63
|
+
});
|
|
64
|
+
if (res.ok) {
|
|
65
|
+
setIsSubscribed(true);
|
|
66
|
+
setLoading(false);
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
// Error handling
|
|
72
|
+
}
|
|
73
|
+
setLoading(false);
|
|
74
|
+
return false;
|
|
75
|
+
}, [apiUrl, isSupported, saasId, swPath]);
|
|
76
|
+
const unsubscribe = useCallback(async () => {
|
|
77
|
+
if (!isSupported)
|
|
78
|
+
return false;
|
|
79
|
+
setLoading(true);
|
|
80
|
+
try {
|
|
81
|
+
const registration = await navigator.serviceWorker.ready;
|
|
82
|
+
const sub = await registration.pushManager.getSubscription();
|
|
83
|
+
if (sub) {
|
|
84
|
+
await sub.unsubscribe();
|
|
85
|
+
await fetch(`${apiUrl}/notifications/unsubscribe`, {
|
|
86
|
+
method: "POST",
|
|
87
|
+
headers: { "Content-Type": "application/json" },
|
|
88
|
+
credentials: "include",
|
|
89
|
+
body: JSON.stringify({ endpoint: sub.endpoint }),
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
setIsSubscribed(false);
|
|
93
|
+
setLoading(false);
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
// Error handling
|
|
98
|
+
}
|
|
99
|
+
setLoading(false);
|
|
100
|
+
return false;
|
|
101
|
+
}, [apiUrl, isSupported]);
|
|
102
|
+
return {
|
|
103
|
+
isSupported,
|
|
104
|
+
isSubscribed,
|
|
105
|
+
permission,
|
|
106
|
+
loading,
|
|
107
|
+
subscribe,
|
|
108
|
+
unsubscribe,
|
|
109
|
+
};
|
|
110
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codeswayam/ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -29,7 +29,8 @@
|
|
|
29
29
|
"tailwind-merge": "^3.5.0"
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|
|
32
|
-
"
|
|
32
|
+
"@tanstack/react-table": ">=8.0.0",
|
|
33
|
+
"next": ">=15.0.0",
|
|
33
34
|
"react": ">=18",
|
|
34
35
|
"react-dom": ">=18"
|
|
35
36
|
},
|
|
@@ -38,4 +39,4 @@
|
|
|
38
39
|
"@types/react-dom": "^19",
|
|
39
40
|
"typescript": "^5.0.0"
|
|
40
41
|
}
|
|
41
|
-
}
|
|
42
|
+
}
|