Skip to content

Commit

Permalink
feat: add ChainSelectionModal component and enhance query client pers…
Browse files Browse the repository at this point in the history
…istence in GlobalProvider
  • Loading branch information
ewhal committed Nov 22, 2024
1 parent 37cf9b6 commit 514fe13
Show file tree
Hide file tree
Showing 9 changed files with 795 additions and 26 deletions.
18 changes: 8 additions & 10 deletions packages/moon-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@
"types": "./dist/index.d.ts"
}
},
"files": [
"dist",
"src"
],
"files": ["dist", "src"],
"husky": {
"hooks": {
"pre-commit": "tsdx lint"
Expand Down Expand Up @@ -60,7 +57,6 @@
"build-storybook": "storybook build"
},
"peerDependencies": {
"@tanstack/react-query": "^5.0.0",
"react": "^18.0.0",
"react-dom": "^18.0.0"
},
Expand All @@ -74,6 +70,7 @@
"@radix-ui/react-dropdown-menu": "^2.1.2",
"@radix-ui/react-navigation-menu": "^1.2.1",
"@radix-ui/react-progress": "^1.1.0",
"@radix-ui/react-slider": "^1.2.1",
"@radix-ui/react-switch": "^1.1.1",
"@radix-ui/react-tabs": "^1.1.1",
"@radix-ui/react-toast": "^1.2.2",
Expand All @@ -89,7 +86,11 @@
"@supabase/realtime-js": "^2.10.7",
"@supabase/storage-js": "^2.7.1",
"@supabase/supabase-js": "^2.45.4",
"@tanstack/query-core": "^5.59.6",
"@tanstack/react-query": "^5.60.6",
"@tanstack/query-core": "^5.60.6",
"@tanstack/react-query-persist-client": "^5.60.6",
"@tanstack/query-sync-storage-persister": "^5.60.6",

"@wagmi/connectors": "^5.2.1",
"@wagmi/core": "^2.14.0",
"class-variance-authority": "^0.7.0",
Expand All @@ -101,7 +102,6 @@
"react-copy-to-clipboard": "^5.1.0",
"react-icons": "^5.3.0",
"react-modal": "^3.16.1",
"react-query": "^3.39.3",
"react-tabs": "^6.0.2",
"siwe": "^2.3.2",
"usehooks-ts": "^3.1.0",
Expand Down Expand Up @@ -155,8 +155,6 @@
"vite": "^5.4.8"
},
"eslintConfig": {
"extends": [
"plugin:storybook/recommended"
]
"extends": ["plugin:storybook/recommended"]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
import { useEffect, useState } from "react";
import * as DialogPrimitive from "@radix-ui/react-dialog";
import { motion, AnimatePresence } from "framer-motion";
import { useMoonAuth } from "../../../context";

export interface Notification {
id: number;
text: string;
sender_id: number | null;
receiver_id: number;
read: boolean;
created_at: string;
}

export const NotificationComponent = () => {
const { supabaseClient: supabase, user } = useMoonAuth();
const [notifications, setNotifications] = useState<Notification[]>([]);
const [open, setOpen] = useState(false);
const [selectedNotification, setSelectedNotification] =
useState<Notification | null>(null);

useEffect(() => {
const fetchNotifications = async () => {
if (user) {
const { data, error } = await supabase
.from("notifications")
.select("*")
.eq("receiver_id", user.id)
.order("created_at", { ascending: false });

if (error) {
console.error("Error fetching notifications:", error);
} else {
setNotifications(data as Notification[]);
}
}
};

fetchNotifications();

const channel = supabase
.channel("notifications")
.on(
"postgres_changes",
{
event: "INSERT",
schema: "public",
table: "notifications",
filter: `receiver_id=eq.${user?.id}`,
},
(payload) => {
setNotifications((prevNotifications) => [
...prevNotifications,
payload.new as Notification,
]);
},
)
.subscribe();

return () => {
channel.unsubscribe();
};
}, [supabase, user]);

const dismissNotification = async (notificationId: number) => {
try {
const { error } = await supabase
.from("notifications")
.update({ read: true })
.eq("id", notificationId);

if (error) {
console.error("Error dismissing notification:", error);
} else {
setNotifications((prevNotifications) =>
prevNotifications.map((notification) =>
notification.id === notificationId
? { ...notification, read: true }
: notification,
),
);
}
} catch (error) {
console.error("Error dismissing notification:", error);
}
};

const openNotificationModal = (notification: Notification) => {
setSelectedNotification(notification);
setOpen(true);
};

const closeNotificationModal = () => {
setSelectedNotification(null);
setOpen(false);
};

return (
<div className="fixed bottom-4 right-4 z-50">
<AnimatePresence>
{notifications.map((notification) => (
<motion.div
key={notification.id}
initial={{ opacity: 0, y: 50 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 50 }}
transition={{ duration: 0.3 }}
className={`bg-white rounded-lg shadow-lg p-4 mb-4 ${
notification.read ? "opacity-50" : ""
}`}
>
<div className="flex justify-between items-center">
<p
className="text-gray-800 cursor-pointer"
onClick={() => openNotificationModal(notification)}
>
{notification.text}
</p>
<button
className="text-gray-500 hover:text-gray-800 focus:outline-none"
onClick={() => dismissNotification(notification.id)}
>
<svg
className="h-5 w-5"
fill="none"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path d="M6 18L18 6M6 6l12 12"></path>
</svg>
</button>
</div>
</motion.div>
))}
</AnimatePresence>

{/* Notification Modal */}
<DialogPrimitive.Root open={open} onOpenChange={setOpen}>
<AnimatePresence>
{open && (
<DialogPrimitive.Portal forceMount>
<DialogPrimitive.Overlay
className="fixed inset-0 bg-black/30"
asChild
>
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.3 }}
className="fixed inset-0 flex items-center justify-center"
>
<DialogPrimitive.Content
asChild
className="bg-white rounded-lg shadow-lg p-6 max-w-md"
>
<div>
<DialogPrimitive.Title className="text-xl font-semibold mb-4">
Notification
</DialogPrimitive.Title>
<DialogPrimitive.Description className="text-gray-600 mb-6">
{selectedNotification?.text}
</DialogPrimitive.Description>
<div className="flex justify-end">
<DialogPrimitive.Close asChild>
<button
className="bg-blue-500 hover:bg-blue-600 text-white font-semibold py-2 px-4 rounded focus:outline-none"
onClick={closeNotificationModal}
>
Close
</button>
</DialogPrimitive.Close>
</div>
</div>
</DialogPrimitive.Content>
</motion.div>
</DialogPrimitive.Overlay>
</DialogPrimitive.Portal>
)}
</AnimatePresence>
</DialogPrimitive.Root>
</div>
);
};

export default NotificationComponent;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./Notifications";
1 change: 1 addition & 0 deletions packages/moon-react/src/components/Core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from "./Modal";
export * from "./Dropdown";

export * from "./ToolTip";
export * from "./Notifications";
Loading

0 comments on commit 514fe13

Please sign in to comment.