mirror of
https://github.com/renee-png/acmcc.git
synced 2026-06-21 01:40:01 +00:00
Messaging: add explicit Delete button to the conversation header
The list-row trash is always-visible now, but add an unmissable "Delete" button in the open-conversation header (ChatView) too. Deletes the whole 1:1 conversation for everyone and clears the selection. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { useState, useRef, useEffect } from "react";
|
||||
import { useAuth } from "@/contexts/AuthContext";
|
||||
import { useChatMessages, usePartnerInfo } from "@/hooks/useDirectMessages";
|
||||
import { useChatMessages, usePartnerInfo, STAFF_GROUP_ID } from "@/hooks/useDirectMessages";
|
||||
import { supabase } from "@/integrations/supabase/client";
|
||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||
import { Button } from "@/components/ui/button";
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
interface Props {
|
||||
partnerId: string | null;
|
||||
partnerName: string;
|
||||
onDeleted?: () => void;
|
||||
}
|
||||
|
||||
function getInitials(name: string) {
|
||||
@@ -32,12 +33,26 @@ function formatMessageDate(dateStr: string) {
|
||||
return format(d, "MMM d, h:mm a");
|
||||
}
|
||||
|
||||
export default function ChatView({ partnerId, partnerName }: Props) {
|
||||
export default function ChatView({ partnerId, partnerName, onDeleted }: Props) {
|
||||
const { user, isAdmin, isStaff } = useAuth();
|
||||
const { messages, loading, sendMessage, deleteMessage } = useChatMessages(partnerId);
|
||||
const partnerInfo = usePartnerInfo(partnerId);
|
||||
const [draft, setDraft] = useState("");
|
||||
const [sending, setSending] = useState(false);
|
||||
const [deleteConvOpen, setDeleteConvOpen] = useState(false);
|
||||
|
||||
const canDeleteConversation = !!partnerId && partnerId !== STAFF_GROUP_ID;
|
||||
const deleteConversation = async () => {
|
||||
if (!user || !partnerId) return;
|
||||
const { error } = await supabase
|
||||
.from("direct_messages")
|
||||
.delete()
|
||||
.or(`and(sender_id.eq.${user.id},recipient_id.eq.${partnerId}),and(sender_id.eq.${partnerId},recipient_id.eq.${user.id})`);
|
||||
setDeleteConvOpen(false);
|
||||
if (error) { toast({ title: "Couldn't delete conversation", description: error.message, variant: "destructive" }); return; }
|
||||
toast({ title: "Conversation deleted" });
|
||||
onDeleted?.();
|
||||
};
|
||||
const [creatingRequestId, setCreatingRequestId] = useState<string | null>(null);
|
||||
const [deletingId, setDeletingId] = useState<string | null>(null);
|
||||
const scrollRef = useRef<HTMLDivElement>(null);
|
||||
@@ -133,7 +148,7 @@ export default function ChatView({ partnerId, partnerName }: Props) {
|
||||
{getInitials(partnerName)}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
<div className="min-w-0">
|
||||
<div className="min-w-0 flex-1">
|
||||
<div className="font-semibold text-sm truncate">{partnerName}</div>
|
||||
{partnerInfo && (partnerInfo.ownerName || partnerInfo.unit || partnerInfo.associationName) && (
|
||||
<div className="text-[11px] text-muted-foreground truncate">
|
||||
@@ -141,8 +156,35 @@ export default function ChatView({ partnerId, partnerName }: Props) {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{canDeleteConversation && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="shrink-0 gap-1 text-muted-foreground hover:text-destructive"
|
||||
onClick={() => setDeleteConvOpen(true)}
|
||||
>
|
||||
<Trash2 className="h-4 w-4" /> Delete
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<AlertDialog open={deleteConvOpen} onOpenChange={setDeleteConvOpen}>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>Delete this conversation?</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
This permanently deletes the conversation with {partnerName} for everyone. This can't be undone.
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
||||
<AlertDialogAction className="bg-destructive text-destructive-foreground hover:bg-destructive/90" onClick={deleteConversation}>
|
||||
Delete
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
|
||||
{/* Messages */}
|
||||
<div ref={scrollRef} className="flex-1 overflow-y-auto px-4 py-4 space-y-3">
|
||||
{loading ? (
|
||||
|
||||
@@ -62,7 +62,11 @@ export default function MessagesPage() {
|
||||
onMessageWholeBoard={handleMessageWholeBoard}
|
||||
/>
|
||||
</div>
|
||||
<ChatView partnerId={selectedPartnerId} partnerName={partnerName} />
|
||||
<ChatView
|
||||
partnerId={selectedPartnerId}
|
||||
partnerName={partnerName}
|
||||
onDeleted={() => { setSelectedPartnerId(null); setPartnerName(""); }}
|
||||
/>
|
||||
</div>
|
||||
</TabsContent>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user