Skip to content

Commit

Permalink
Refactoring the alert context to make it general purpose and accept m…
Browse files Browse the repository at this point in the history
…ultiple alerts
  • Loading branch information
brickpop committed Feb 22, 2024
1 parent dbd4198 commit 67b1395
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 89 deletions.
Binary file modified bun.lockb
Binary file not shown.
36 changes: 36 additions & 0 deletions components/alert/alert-container.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { FC } from "react";
import { useAlertContext } from "@/context/AlertContext";
import { AlertCard, AlertVariant } from "@aragon/ods";
import { IAlert } from "@/utils/types";

const AlertContainer: FC = () => {
const { alerts } = useAlertContext();

return (
<div className="fixed bottom-0 right-0 w-96 m-10">
{alerts.map((alert: IAlert) => (
<AlertCard
className="mt-4"
key={alert.id}
message={alert.message}
description={alert.description}
variant={resolveVariant(alert.type)}
/>
))}
</div>
);
};

function resolveVariant(type: IAlert["type"]) {
let result: AlertVariant;
switch (type) {
case "error":
result = "critical";
break;
default:
result = type;
}
return result;
}

export default AlertContainer;
18 changes: 0 additions & 18 deletions components/alert/alerts.tsx

This file was deleted.

54 changes: 0 additions & 54 deletions components/alert/index.tsx

This file was deleted.

55 changes: 43 additions & 12 deletions context/AlertContext.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,60 @@
import React, { createContext, useState, useContext } from 'react';
import { IAlert } from '@/utils/types'
import React, { createContext, useState, useContext } from "react";
import { IAlert } from "@/utils/types";
import { usePublicClient } from "wagmi";

const DEFAULT_ALERT_TIMEOUT = 7 * 1000;

export type NewAlert = {
type: "success" | "info" | "error";
message: string;
description?: string;
txHash?: string;
timeout?: number;
};

export interface AlertContextProps {
alerts: IAlert[];
addAlert: (message: string, txHash: string) => void;
removeAlert: (id: number) => void;
addAlert: (newAlert: NewAlert) => void;
}

export const AlertContext = createContext<AlertContextProps | undefined>(undefined);
export const AlertContext = createContext<AlertContextProps | undefined>(
undefined
);

export const AlertProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
export const AlertProvider: React.FC<{ children: React.ReactNode }> = ({
children,
}) => {
const [alerts, setAlerts] = useState<IAlert[]>([]);
const client = usePublicClient();

// Add a new alert to the list
const addAlert = (alert: NewAlert) => {
const newAlert: IAlert = {
id: Date.now(),
message: alert.message,
description: alert.description,
type: alert.type,
};
if (alert.txHash && client) {
newAlert.explorerLink =
client.chain.blockExplorers?.default.url + "/tx/" + alert.txHash;
}
setAlerts(alerts.concat(newAlert));

// Function to add a new alert
const addAlert = (message: string, txHash: string) => {
setAlerts([...alerts, { message, txHash, id: Date.now() }]);
// Schedule the clean-up
const timeout = alert.timeout ?? DEFAULT_ALERT_TIMEOUT;
setTimeout(() => {
removeAlert(newAlert.id);
}, timeout);
};

// Function to remove an alert
const removeAlert = (id: number) => {
setAlerts(alerts?.filter((alert) => alert.id !== id));
setAlerts(alerts.filter((alert) => alert.id !== id));
};

return (
<AlertContext.Provider value={{ alerts, addAlert, removeAlert }}>
<AlertContext.Provider value={{ alerts, addAlert }}>
{children}
</AlertContext.Provider>
);
Expand All @@ -33,7 +64,7 @@ export const useAlertContext = () => {
const context = useContext(AlertContext);

if (!context) {
throw new Error('useThemeContext must be used inside the AlertProvider');
throw new Error("useContext must be used inside the AlertProvider");
}

return context;
Expand Down
2 changes: 0 additions & 2 deletions context/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { AlertProvider } from "./AlertContext";
import Alerts from "@/components/alert/alerts";
import { ReactNode } from "react";
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { config } from "@/context/Web3Modal";
Expand All @@ -22,7 +21,6 @@ export function RootContextProvider({ children, initialState }: { children: Reac
<QueryClientProvider client={queryClient}>
<AlertProvider>
{children}
<Alerts />
</AlertProvider>
</QueryClientProvider>
</WagmiProvider>
Expand Down
2 changes: 2 additions & 0 deletions pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { RootContextProvider } from "@/context";
import { Layout } from "@/components/layout";
import AlertContainer from "@/components/alert/alert-container";
import { Manrope } from "next/font/google";
import "@aragon/ods/index.css";
import "@/pages/globals.css";
Expand All @@ -22,6 +23,7 @@ export default function AragonetteApp({ Component, pageProps }: any) {
<Layout>
<Component {...pageProps} />
</Layout>
<AlertContainer />
</RootContextProvider>
</div>
);
Expand Down
8 changes: 5 additions & 3 deletions utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ export type Action = {
to: string;
value: bigint;
data: string;
}
};

export interface IAlert {
message: string;
txHash: string;
id: number;
type: "success" | "info" | "error";
message: string;
description?: string;
explorerLink?: string;
}

0 comments on commit 67b1395

Please sign in to comment.