@citiwave/im-disclaimer-modal
Version:
A customizable React disclaimer modal component with theme support
96 lines (77 loc) • 3.05 kB
text/typescript
import { useState, useCallback, useEffect } from 'react';
// Define disclaimer priorities - empty by default, will be populated by groups
export const DISCLAIMER_PRIORITIES: { [key: string]: number } = {};
type DisclaimerId = string;
interface DisclaimerQueueItem {
id: DisclaimerId;
isOpen: boolean;
priority: number;
}
const STORAGE_KEY = 'im-disclaimer-accepted';
export const useDisclaimerQueue = () => {
const [queue, setQueue] = useState<DisclaimerQueueItem[]>([]);
const [activeDisclaimer, setActiveDisclaimer] = useState<DisclaimerId | null>(null);
// Load accepted disclaimers from localStorage
useEffect(() => {
const acceptedDisclaimers = localStorage.getItem(STORAGE_KEY);
if (acceptedDisclaimers) {
const accepted = new Set(JSON.parse(acceptedDisclaimers));
// Filter out accepted disclaimers from the queue
setQueue(prev => prev.filter(item => !accepted.has(item.id)));
}
}, []);
const addToQueue = useCallback((id: DisclaimerId) => {
// Check if disclaimer was already accepted
const acceptedDisclaimers = localStorage.getItem(STORAGE_KEY);
const accepted = acceptedDisclaimers ? new Set(JSON.parse(acceptedDisclaimers)) : new Set();
if (accepted.has(id)) {
return; // Don't add if already accepted
}
setQueue(prev => {
// Don't add if already in queue
if (prev.some(item => item.id === id)) {
return prev;
}
const priority = DISCLAIMER_PRIORITIES[id];
const newQueue = [...prev, { id, isOpen: false, priority }].sort((a, b) => a.priority - b.priority);
// If no active disclaimer, activate the highest priority one
if (!activeDisclaimer) {
const highestPriority = newQueue[0];
if (highestPriority) {
setActiveDisclaimer(highestPriority.id);
}
}
return newQueue;
});
}, [activeDisclaimer]);
const removeFromQueue = useCallback((id: DisclaimerId) => {
// Add to accepted disclaimers in localStorage
const acceptedDisclaimers = localStorage.getItem(STORAGE_KEY);
const accepted = acceptedDisclaimers ? new Set(JSON.parse(acceptedDisclaimers)) : new Set();
accepted.add(id);
localStorage.setItem(STORAGE_KEY, JSON.stringify(Array.from(accepted)));
setQueue(prev => {
const newQueue = prev.filter(item => item.id !== id);
// If this was the active disclaimer, activate the next highest priority one
if (activeDisclaimer === id) {
const nextItem = newQueue[0];
if (nextItem) {
setActiveDisclaimer(nextItem.id);
} else {
setActiveDisclaimer(null);
}
}
return newQueue;
});
}, [activeDisclaimer]);
const isDisclaimerActive = useCallback((id: DisclaimerId) => {
return activeDisclaimer === id;
}, [activeDisclaimer]);
return {
addToQueue,
removeFromQueue,
isDisclaimerActive,
hasActiveDisclaimer: activeDisclaimer !== null,
getActiveDisclaimer: () => activeDisclaimer
};
};