mirror of
https://github.com/renee-png/acmcc.git
synced 2026-06-21 09:50:01 +00:00
183fe0a93c
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
155 lines
5.8 KiB
React
155 lines
5.8 KiB
React
import React, { useState, useEffect } from 'react';
|
|
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
|
|
import { ScrollArea } from '@/components/ui/scroll-area';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Separator } from '@/components/ui/separator';
|
|
import { Badge } from '@/components/ui/badge';
|
|
import { Calendar, Trash2, Edit, Mail, CheckCircle2 } from 'lucide-react';
|
|
import {
|
|
AlertDialog,
|
|
AlertDialogAction,
|
|
AlertDialogCancel,
|
|
AlertDialogContent,
|
|
AlertDialogDescription,
|
|
AlertDialogFooter,
|
|
AlertDialogHeader,
|
|
AlertDialogTitle,
|
|
} from "@/components/ui/alert-dialog";
|
|
import { useAuth } from '@/contexts/AuthContext';
|
|
import { supabase } from '@/integrations/supabase/client';
|
|
import { useToast } from '@/hooks/use-toast';
|
|
|
|
// NOTE: These sub-components are referenced but may need to be created separately:
|
|
// HomeownerRequestCommentsSection, HomeownerRequestVotingPanel,
|
|
// HomeownerRequestSummarySection, HomeownerRequestNotificationHistory, HomeownerRequestNotifyDialog
|
|
|
|
export default function HomeownerRequestDetailsDialog({ open, onOpenChange, request, onRefresh, onEdit }) {
|
|
const { userRole } = useAuth();
|
|
const { toast } = useToast();
|
|
const [refreshTrigger, setRefreshTrigger] = useState(0);
|
|
const [notifyDialogOpen, setNotifyDialogOpen] = useState(false);
|
|
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
|
const [localRequest, setLocalRequest] = useState(request);
|
|
|
|
useEffect(() => {
|
|
setLocalRequest(request);
|
|
}, [request]);
|
|
|
|
const fetchDetails = async () => {
|
|
if (!request?.id) return;
|
|
|
|
const { data: requestData, error: requestError } = await supabase
|
|
.from('homeowner_requests')
|
|
.select('*')
|
|
.eq('id', request.id)
|
|
.single();
|
|
|
|
if (requestError) {
|
|
console.error("Error fetching request details:", requestError);
|
|
return;
|
|
}
|
|
|
|
if (requestData) {
|
|
setLocalRequest(prev => ({
|
|
...prev,
|
|
...requestData,
|
|
}));
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (open) {
|
|
fetchDetails();
|
|
}
|
|
}, [open, request?.id, refreshTrigger]);
|
|
|
|
if (!localRequest) return null;
|
|
|
|
const isAdmin = userRole?.role === 'admin' || userRole?.role === 'manager';
|
|
|
|
const handleDelete = async () => {
|
|
try {
|
|
const { error } = await supabase.from('homeowner_requests').delete().eq('id', localRequest.id);
|
|
|
|
if (error) throw error;
|
|
|
|
toast({ title: 'Deleted', description: 'Homeowner request deleted successfully.' });
|
|
setDeleteDialogOpen(false);
|
|
onOpenChange(false);
|
|
if (onRefresh) onRefresh();
|
|
} catch (error) {
|
|
console.error("Delete failed:", error);
|
|
toast({ variant: 'destructive', title: 'Error', description: error.message || "Failed to delete request." });
|
|
}
|
|
};
|
|
|
|
const handleRefresh = () => {
|
|
setRefreshTrigger(prev => prev + 1);
|
|
fetchDetails();
|
|
if (onRefresh) onRefresh();
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
<DialogContent className="sm:max-w-[900px] h-[90vh] sm:h-[850px] flex flex-col p-0 gap-0">
|
|
<DialogHeader className="p-6 pb-4 border-b">
|
|
<div className="flex justify-between items-start gap-4">
|
|
<div className="space-y-2 flex-1">
|
|
<div className="flex items-center gap-2 mb-1">
|
|
<Badge variant={localRequest.status === 'open' ? 'default' : 'secondary'} className="capitalize px-2 py-0.5 text-xs font-normal">{localRequest.status}</Badge>
|
|
<span className="text-xs text-muted-foreground flex items-center gap-1"><Calendar className="w-3 h-3" /> {new Date(localRequest.created_at).toLocaleDateString()}</span>
|
|
</div>
|
|
<DialogTitle className="text-2xl font-bold leading-tight">{localRequest.title}</DialogTitle>
|
|
</div>
|
|
{isAdmin && (
|
|
<div className="flex gap-2">
|
|
<Button variant="outline" size="sm" onClick={() => onEdit(localRequest)}><Edit className="w-3.5 h-3.5 mr-2" /> Edit</Button>
|
|
<Button
|
|
variant="outline"
|
|
size="icon"
|
|
className="text-destructive hover:text-destructive hover:bg-destructive/10"
|
|
onClick={() => setDeleteDialogOpen(true)}
|
|
>
|
|
<Trash2 className="w-4 h-4" />
|
|
</Button>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</DialogHeader>
|
|
|
|
<ScrollArea className="flex-1 px-6">
|
|
<div className="py-6 space-y-8">
|
|
<div className="flex-1 space-y-6 min-w-0 w-full bg-card p-5 rounded-lg border shadow-sm">
|
|
{localRequest.description && (
|
|
<div className="text-lg text-foreground font-medium leading-relaxed">
|
|
{localRequest.description}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</ScrollArea>
|
|
</DialogContent>
|
|
</Dialog>
|
|
|
|
<AlertDialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
|
|
<AlertDialogContent>
|
|
<AlertDialogHeader>
|
|
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
|
|
<AlertDialogDescription>
|
|
This action cannot be undone. This will permanently delete the homeowner request
|
|
and all associated data.
|
|
</AlertDialogDescription>
|
|
</AlertDialogHeader>
|
|
<AlertDialogFooter>
|
|
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
|
<AlertDialogAction onClick={handleDelete} className="bg-destructive text-destructive-foreground hover:bg-destructive/90">
|
|
Delete Request
|
|
</AlertDialogAction>
|
|
</AlertDialogFooter>
|
|
</AlertDialogContent>
|
|
</AlertDialog>
|
|
</>
|
|
);
|
|
}
|