You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

278 lines
7.1 KiB

import { NotificationIface } from "../constants/app";
/**
* Notification utility methods to reduce code duplication
* and provide consistent notification patterns across the app
*/
export interface NotificationHelper {
notify: (notification: NotificationIface, timeout?: number) => void;
success: (text: string, timeout?: number) => void;
error: (text: string, timeout?: number) => void;
warning: (text: string, timeout?: number) => void;
info: (text: string, timeout?: number) => void;
toast: (title: string, text?: string, timeout?: number) => void;
copied: (item: string, timeout?: number) => void;
sent: (timeout?: number) => void;
confirm: (text: string, onYes: () => Promise<void>, timeout?: number) => void;
confirmationSubmitted: (timeout?: number) => void;
alreadyConfirmed: (timeout?: number) => void;
cannotConfirmIssuer: (timeout?: number) => void;
cannotConfirmHidden: (timeout?: number) => void;
notRegistered: (timeout?: number) => void;
notAGive: (timeout?: number) => void;
}
/**
* Standard notification timeouts
*/
export const NOTIFICATION_TIMEOUTS = {
BRIEF: 1000, // Very brief toasts ("Sent..." messages)
SHORT: 2000, // Short notifications (clipboard copies, quick confirmations)
STANDARD: 3000, // Standard notifications (success messages, general info)
LONG: 5000, // Longer notifications (errors, warnings, important info)
VERY_LONG: 7000, // Very long notifications (complex operations)
MODAL: -1, // Modal confirmations (no auto-dismiss)
} as const;
/**
* Standard notification titles
*/
export const NOTIFICATION_TITLES = {
SUCCESS: "Success",
ERROR: "Error",
WARNING: "Warning",
INFO: "Info",
COPIED: "Copied",
SENT: "Sent...",
CONFIRM: "Confirm",
NOT_REGISTERED: "Not Registered",
ALREADY_CONFIRMED: "Already Confirmed",
CANNOT_CONFIRM: "Cannot Confirm",
} as const;
/**
* Standard notification messages
*/
export const NOTIFICATION_MESSAGES = {
GENERIC_ERROR: "Something went wrong.",
GENERIC_SUCCESS: "Operation completed successfully.",
CLIPBOARD_COPIED: (item: string) => `${item} was copied to the clipboard.`,
SENT_BRIEF: "Sent...",
CONFIRMATION_SUBMITTED: "Confirmation submitted.",
ALREADY_CONFIRMED: "You already confirmed this claim.",
CANNOT_CONFIRM_ISSUER:
"You cannot confirm this because you issued this claim.",
CANNOT_CONFIRM_HIDDEN:
"You cannot confirm this because some people are hidden.",
NOT_REGISTERED: "Someone needs to register you before you can confirm.",
NOT_A_GIVE: "This is not a giving action to confirm.",
} as const;
/**
* Creates a notification helper with utility methods
*/
export function createNotificationHelper(
notifyFn: (notification: NotificationIface, timeout?: number) => void,
): NotificationHelper {
return {
notify: notifyFn,
// Success notifications
success: (text: string, timeout = NOTIFICATION_TIMEOUTS.STANDARD) => {
notifyFn(
{
group: "alert",
type: "success",
title: NOTIFICATION_TITLES.SUCCESS,
text,
},
timeout,
);
},
// Error notifications
error: (text: string, timeout = NOTIFICATION_TIMEOUTS.LONG) => {
notifyFn(
{
group: "alert",
type: "danger",
title: NOTIFICATION_TITLES.ERROR,
text,
},
timeout,
);
},
// Warning notifications
warning: (text: string, timeout = NOTIFICATION_TIMEOUTS.LONG) => {
notifyFn(
{
group: "alert",
type: "warning",
title: NOTIFICATION_TITLES.WARNING,
text,
},
timeout,
);
},
// Info notifications
info: (text: string, timeout = NOTIFICATION_TIMEOUTS.STANDARD) => {
notifyFn(
{
group: "alert",
type: "info",
title: NOTIFICATION_TITLES.INFO,
text,
},
timeout,
);
},
// Toast notifications (brief)
toast: (
title: string,
text?: string,
timeout = NOTIFICATION_TIMEOUTS.BRIEF,
) => {
notifyFn(
{
group: "alert",
type: "toast",
title,
text,
},
timeout,
);
},
// Clipboard copy notifications
copied: (item: string, timeout = NOTIFICATION_TIMEOUTS.SHORT) => {
notifyFn(
{
group: "alert",
type: "toast",
title: NOTIFICATION_TITLES.COPIED,
text: NOTIFICATION_MESSAGES.CLIPBOARD_COPIED(item),
},
timeout,
);
},
// Sent brief notification
sent: (timeout = NOTIFICATION_TIMEOUTS.BRIEF) => {
notifyFn(
{
group: "alert",
type: "toast",
title: NOTIFICATION_TITLES.SENT,
},
timeout,
);
},
// Confirmation modal
confirm: (
text: string,
onYes: () => Promise<void>,
timeout = NOTIFICATION_TIMEOUTS.MODAL,
) => {
notifyFn(
{
group: "modal",
type: "confirm",
title: NOTIFICATION_TITLES.CONFIRM,
text,
onYes,
},
timeout,
);
},
// Standard confirmation messages
confirmationSubmitted: (timeout = NOTIFICATION_TIMEOUTS.STANDARD) => {
notifyFn(
{
group: "alert",
type: "success",
title: NOTIFICATION_TITLES.SUCCESS,
text: NOTIFICATION_MESSAGES.CONFIRMATION_SUBMITTED,
},
timeout,
);
},
alreadyConfirmed: (timeout = NOTIFICATION_TIMEOUTS.STANDARD) => {
notifyFn(
{
group: "alert",
type: "info",
title: NOTIFICATION_TITLES.ALREADY_CONFIRMED,
text: NOTIFICATION_MESSAGES.ALREADY_CONFIRMED,
},
timeout,
);
},
cannotConfirmIssuer: (timeout = NOTIFICATION_TIMEOUTS.STANDARD) => {
notifyFn(
{
group: "alert",
type: "info",
title: NOTIFICATION_TITLES.CANNOT_CONFIRM,
text: NOTIFICATION_MESSAGES.CANNOT_CONFIRM_ISSUER,
},
timeout,
);
},
cannotConfirmHidden: (timeout = NOTIFICATION_TIMEOUTS.STANDARD) => {
notifyFn(
{
group: "alert",
type: "info",
title: NOTIFICATION_TITLES.CANNOT_CONFIRM,
text: NOTIFICATION_MESSAGES.CANNOT_CONFIRM_HIDDEN,
},
timeout,
);
},
notRegistered: (timeout = NOTIFICATION_TIMEOUTS.STANDARD) => {
notifyFn(
{
group: "alert",
type: "info",
title: NOTIFICATION_TITLES.NOT_REGISTERED,
text: NOTIFICATION_MESSAGES.NOT_REGISTERED,
},
timeout,
);
},
notAGive: (timeout = NOTIFICATION_TIMEOUTS.STANDARD) => {
notifyFn(
{
group: "alert",
type: "info",
title: NOTIFICATION_TITLES.INFO,
text: NOTIFICATION_MESSAGES.NOT_A_GIVE,
},
timeout,
);
},
};
}
/**
* Vue mixin to add notification helpers to components
*/
export const NotificationMixin = {
computed: {
$notifyHelper() {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return createNotificationHelper((this as any).$notify);
},
},
};