Spaces:
Paused
Paused
| /** | |
| * SlackStatusWidget - Team Presence & Quick Message | |
| */ | |
| import React, { useState } from 'react'; | |
| import { MessageCircle, Users, Send, Circle } from 'lucide-react'; | |
| import { useLiveData } from '@/hooks/useLiveData'; | |
| import { useWidgetCommunication } from '@/contexts/WidgetContext'; | |
| import { cn } from '@/lib/utils'; | |
| export default function SlackStatusWidget({ widgetId }: { widgetId: string }) { | |
| const [message, setMessage] = useState(''); | |
| const { data } = useLiveData({ | |
| widgetId, | |
| widgetType: 'slack', | |
| requiredSources: ['slack-api'], | |
| autoConnect: true, | |
| pollInterval: 30000, | |
| }); | |
| const { broadcastEvent } = useWidgetCommunication(widgetId); | |
| const team = data?.team || []; | |
| const unreadChannels = data?.unreadChannels || 0; | |
| const handleSendMessage = () => { | |
| if (!message.trim()) return; | |
| broadcastEvent({ | |
| type: 'slack.message.sent', | |
| data: { message }, | |
| }); | |
| setMessage(''); | |
| }; | |
| return ( | |
| <div className="h-full flex flex-col bg-gradient-to-br from-amber-500/10 to-orange-500/10 backdrop-blur-sm border border-amber-500/30 rounded-lg overflow-hidden"> | |
| <div className="p-4 border-b border-amber-500/20"> | |
| <div className="flex items-center justify-between"> | |
| <div className="flex items-center gap-2"> | |
| <MessageCircle className="w-5 h-5 text-amber-400" /> | |
| <span className="font-display text-sm uppercase tracking-wider text-amber-400">Slack</span> | |
| </div> | |
| {unreadChannels > 0 && ( | |
| <div className="px-2 py-1 bg-amber-500 text-white rounded-full text-xs"> | |
| {unreadChannels} | |
| </div> | |
| )} | |
| </div> | |
| </div> | |
| <div className="p-4 space-y-3"> | |
| <div className="text-xs text-amber-300 mb-2 flex items-center gap-2"> | |
| <Users className="w-4 h-4" /> | |
| Team Status | |
| </div> | |
| {team.slice(0, 5).map((member: any) => ( | |
| <div key={member.id} className="flex items-center gap-3"> | |
| <Circle className={cn( | |
| "w-2 h-2", | |
| member.status === 'active' && "fill-green-400 text-green-400", | |
| member.status === 'away' && "fill-yellow-400 text-yellow-400", | |
| member.status === 'offline' && "fill-gray-400 text-gray-400" | |
| )} /> | |
| <div className="flex-1"> | |
| <div className="text-sm text-white">{member.name}</div> | |
| <div className="text-xs text-amber-300/50">{member.timezone}</div> | |
| </div> | |
| </div> | |
| ))} | |
| </div> | |
| <div className="mt-auto p-3 border-t border-amber-500/20 bg-black/20"> | |
| <div className="flex gap-2"> | |
| <input | |
| type="text" | |
| value={message} | |
| onChange={(e) => setMessage(e.target.value)} | |
| onKeyDown={(e) => e.key === 'Enter' && handleSendMessage()} | |
| placeholder="Quick message..." | |
| className="flex-1 px-3 py-2 bg-white/5 border border-amber-500/30 rounded text-sm text-white placeholder-amber-300/50 focus:outline-none focus:border-amber-500" | |
| /> | |
| <button | |
| onClick={handleSendMessage} | |
| className="p-2 bg-amber-500 hover:bg-amber-600 rounded transition-colors" | |
| > | |
| <Send className="w-4 h-4 text-white" /> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| ); | |
| } | |