| // src/components/messages/ChatNotificationSettingsModal.tsx | |
| import { useChatNotificationSettings } from "@/hooks/useChatNotificationSettings"; | |
| import { X, Bell, BellOff, Volume2, VolumeX, Eye, EyeOff, Clock } from "lucide-react"; | |
| interface ChatNotificationSettingsModalProps { | |
| isOpen: boolean; | |
| onClose: () => void; | |
| chatId: string; | |
| chatName: string; | |
| } | |
| export function ChatNotificationSettingsModal({ | |
| isOpen, | |
| onClose, | |
| chatId, | |
| chatName, | |
| }: ChatNotificationSettingsModalProps) { | |
| const { settings, loading, mute, unmute, togglePreview, toggleSound } = | |
| useChatNotificationSettings(chatId); | |
| if (!isOpen) return null; | |
| return ( | |
| <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4" onClick={onClose}> | |
| <div | |
| className="bg-white dark:bg-gray-800 rounded-2xl max-w-sm w-full p-6 shadow-xl" | |
| onClick={(e) => e.stopPropagation()} | |
| > | |
| <div className="flex items-center justify-between mb-4"> | |
| <h2 className="text-lg font-bold">Notifications</h2> | |
| <button onClick={onClose} className="text-gray-500 hover:text-gray-700"> | |
| <X className="w-5 h-5" /> | |
| </button> | |
| </div> | |
| <p className="text-sm text-gray-500 mb-4"> | |
| Customise notifications for <strong>{chatName}</strong> | |
| </p> | |
| {loading ? ( | |
| <div className="text-center py-4 text-gray-500">Loading...</div> | |
| ) : ( | |
| <div className="space-y-4"> | |
| {/* Mute / Unmute */} | |
| <div className="flex items-center justify-between"> | |
| <div className="flex items-center gap-3"> | |
| {settings.muted ? ( | |
| <BellOff className="w-5 h-5 text-gray-400" /> | |
| ) : ( | |
| <Bell className="w-5 h-5 text-primary" /> | |
| )} | |
| <span className="text-sm font-medium">Mute notifications</span> | |
| </div> | |
| <button | |
| onClick={() => (settings.muted ? unmute() : mute())} | |
| className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${ | |
| settings.muted ? "bg-gray-300 dark:bg-gray-600" : "bg-primary" | |
| }`} | |
| > | |
| <span | |
| className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${ | |
| settings.muted ? "translate-x-1" : "translate-x-6" | |
| }`} | |
| /> | |
| </button> | |
| </div> | |
| {/* Mute duration options (only when mute is toggled, we can extend) */} | |
| {settings.muted && ( | |
| <div className="flex gap-2 ml-8"> | |
| {[ | |
| { label: "1h", mins: 60 }, | |
| { label: "8h", mins: 480 }, | |
| { label: "Forever", mins: undefined }, | |
| ].map((opt) => ( | |
| <button | |
| key={opt.label} | |
| onClick={() => mute(opt.mins)} | |
| className="px-3 py-1 text-xs bg-gray-100 dark:bg-gray-700 rounded-full hover:bg-gray-200" | |
| > | |
| <Clock className="w-3 h-3 inline mr-1" /> | |
| {opt.label} | |
| </button> | |
| ))} | |
| </div> | |
| )} | |
| {/* Sound */} | |
| <div className="flex items-center justify-between"> | |
| <div className="flex items-center gap-3"> | |
| {settings.soundEnabled ? ( | |
| <Volume2 className="w-5 h-5 text-primary" /> | |
| ) : ( | |
| <VolumeX className="w-5 h-5 text-gray-400" /> | |
| )} | |
| <span className="text-sm font-medium">Sound</span> | |
| </div> | |
| <button | |
| onClick={toggleSound} | |
| className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${ | |
| settings.soundEnabled ? "bg-primary" : "bg-gray-300 dark:bg-gray-600" | |
| }`} | |
| > | |
| <span | |
| className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${ | |
| settings.soundEnabled ? "translate-x-6" : "translate-x-1" | |
| }`} | |
| /> | |
| </button> | |
| </div> | |
| {/* Message preview */} | |
| <div className="flex items-center justify-between"> | |
| <div className="flex items-center gap-3"> | |
| {settings.previewEnabled ? ( | |
| <Eye className="w-5 h-5 text-primary" /> | |
| ) : ( | |
| <EyeOff className="w-5 h-5 text-gray-400" /> | |
| )} | |
| <span className="text-sm font-medium">Message preview</span> | |
| </div> | |
| <button | |
| onClick={togglePreview} | |
| className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${ | |
| settings.previewEnabled ? "bg-primary" : "bg-gray-300 dark:bg-gray-600" | |
| }`} | |
| > | |
| <span | |
| className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${ | |
| settings.previewEnabled ? "translate-x-6" : "translate-x-1" | |
| }`} | |
| /> | |
| </button> | |
| </div> | |
| </div> | |
| )} | |
| <button onClick={onClose} className="btn btn-secondary w-full mt-6"> | |
| Done | |
| </button> | |
| </div> | |
| </div> | |
| ); | |
| } |
Xet Storage Details
- Size:
- 5.56 kB
- Xet hash:
- 2a549e3774ec0c871d3c445a8200bac3cacd6c53e9063e7e73b28dacd4d442fe
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.