Dealer_Onboard_Frontend/src/components/applications/ConstitutionalChangeDetails.tsx

788 lines
34 KiB
TypeScript

import { ArrowLeft, FileText, Calendar, User, Building2, CheckCircle2, Clock, AlertCircle, Upload, Download, Eye, ArrowRight, Shield, MessageSquare } from 'lucide-react';
import { Button } from '../ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../ui/card';
import { Badge } from '../ui/badge';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '../ui/tabs';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '../ui/table';
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from '../ui/dialog';
import { Textarea } from '../ui/textarea';
import { Label } from '../ui/label';
import { Input } from '../ui/input';
import { useState } from 'react';
import { User as UserType } from '../../lib/mock-data';
import { toast } from 'sonner';
import { mockConstitutionalChangeRequests } from './ConstitutionalChangePage';
interface ConstitutionalChangeDetailsProps {
requestId: string;
onBack: () => void;
currentUser: UserType | null;
onOpenWorknote?: (requestId: string, requestType: 'relocation' | 'constitutional-change' | 'fnf' | 'resignation' | 'termination', requestTitle: string) => void;
}
// Workflow stages as per the process flow
const workflowStages = [
{ id: 1, name: 'Request Created', key: 'created', role: 'Dealer' },
{ id: 2, name: 'ASM Review', key: 'asm', role: 'ASM' },
{ id: 3, name: 'RBM Review', key: 'rbm', role: 'RBM' },
{ id: 4, name: 'DD ZM Review', key: 'dd-zm', role: 'DD-ZM' },
{ id: 5, name: 'ZBH Review', key: 'zbh', role: 'ZBH' },
{ id: 6, name: 'DD Lead Review', key: 'dd-lead', role: 'DD Lead' },
{ id: 7, name: 'FDD Review', key: 'fdd', role: 'FDD' },
{ id: 8, name: 'DD Head Review', key: 'dd-head', role: 'DD Head' },
{ id: 9, name: 'NBH Review', key: 'nbh', role: 'NBH' },
{ id: 10, name: 'Docs Collection by DD H.O', key: 'docs-collection', role: 'DD H.O' },
{ id: 11, name: 'New Code Creation', key: 'code-creation', role: 'DD Admin' },
{ id: 12, name: 'New LOA Issuance', key: 'loa-issuance', role: 'DD Admin' },
{ id: 13, name: 'Closure of Request', key: 'closure', role: 'System' }
];
// Document requirements mapping (same as in ConstitutionalChangePage)
const documentRequirements: Record<string, number[]> = {
'Partnership': [1, 2, 3, 4, 8, 9, 10, 16],
'LLP': [1, 2, 3, 7, 8, 9, 10, 16],
'Pvt Ltd': [1, 2, 3, 5, 6, 7, 8, 10, 16],
'Proprietorship': [1, 2, 3, 10, 16]
};
const documentNames: Record<number, string> = {
1: 'GST',
2: 'Firm Pan Copy',
3: 'Self attested KYC\'s',
4: 'Partnership Agreement (Notarised)',
5: 'MOA (Applicable for Only Pvt.Ltd)',
6: 'AOA (Applicable for Only Pvt.Ltd)',
7: 'COI (Applicable for Only Pvt.Ltd & LLP)',
8: 'BPA - Business Purchase Agreement',
9: 'Firm Registration Certificate (Partnership)',
10: 'Cancelled Cheque',
11: 'LLP Agreement (Notarised)',
12: 'ZBH Approval',
13: 'NBH Approval',
14: 'RBM Approval',
15: 'DD-Lead Approval',
16: 'Declaration / Authorization Letter'
};
// Mock uploaded documents
const mockUploadedDocuments = [
{ docNumber: 1, fileName: 'GST_Certificate.pdf', uploadedOn: '2025-12-15', uploadedBy: 'Dealer', status: 'Verified' },
{ docNumber: 2, fileName: 'Firm_PAN.pdf', uploadedOn: '2025-12-15', uploadedBy: 'Dealer', status: 'Verified' },
{ docNumber: 3, fileName: 'KYC_Documents.pdf', uploadedOn: '2025-12-15', uploadedBy: 'Dealer', status: 'Pending Verification' },
{ docNumber: 4, fileName: 'Partnership_Agreement_Notarised.pdf', uploadedOn: '2025-12-16', uploadedBy: 'Dealer', status: 'Verified' },
];
// Mock workflow history
const mockWorkflowHistory = [
{
stage: 'Request Created',
actor: 'Amit Sharma (Dealer)',
action: 'Created',
date: '2025-12-15 10:30 AM',
comments: 'Submitted constitutional change request from Proprietorship to Partnership',
status: 'Completed'
},
{
stage: 'ASM Review',
actor: 'Rajesh Kumar (ASM)',
action: 'Approved',
date: '2025-12-16 02:15 PM',
comments: 'Verified dealer credentials and approved for next stage',
status: 'Completed'
},
{
stage: 'RBM Review',
actor: 'Priya Sharma (RBM)',
action: 'Under Review',
date: '2025-12-17 09:00 AM',
comments: 'Documents under verification',
status: 'In Progress'
},
];
// Mock worknotes - Discussion platform for this request
const initialWorknotes = [
{
id: 1,
user: 'Rajesh Kumar',
role: 'ASM',
message: 'I have reviewed the partnership agreement. All partners have proper KYC documentation. Looks good to proceed.',
timestamp: '2025-12-16 11:30 AM',
avatar: 'RK'
},
{
id: 2,
user: 'Priya Sharma',
role: 'RBM',
message: 'Can we get clarification on the profit sharing ratio mentioned in the partnership deed? It seems different from what was discussed.',
timestamp: '2025-12-17 02:45 PM',
avatar: 'PS'
},
{
id: 3,
user: 'Amit Sharma',
role: 'Dealer',
message: 'The profit sharing ratio is 60:40 as per the partnership deed. This was agreed upon by all partners and is correctly reflected in the document.',
timestamp: '2025-12-17 04:15 PM',
avatar: 'AS'
},
{
id: 4,
user: 'Priya Sharma',
role: 'RBM',
message: 'Thank you for the clarification. I have verified the BPA and other statutory documents. Everything appears to be in order.',
timestamp: '2025-12-18 10:00 AM',
avatar: 'PS'
}
];
const getTypeColor = (type: string) => {
switch(type) {
case 'Proprietorship': return 'bg-purple-100 text-purple-700 border-purple-300';
case 'Partnership': return 'bg-blue-100 text-blue-700 border-blue-300';
case 'LLP': return 'bg-indigo-100 text-indigo-700 border-indigo-300';
case 'Pvt Ltd': return 'bg-cyan-100 text-cyan-700 border-cyan-300';
default: return 'bg-slate-100 text-slate-700 border-slate-300';
}
};
const getStatusColor = (status: string) => {
if (status === 'Completed' || status === 'Verified') return 'bg-green-100 text-green-700 border-green-300';
if (status.includes('Review') || status.includes('Pending') || status === 'In Progress') return 'bg-yellow-100 text-yellow-700 border-yellow-300';
if (status.includes('Rejected')) return 'bg-red-100 text-red-700 border-red-300';
return 'bg-slate-100 text-slate-700 border-slate-300';
};
export function ConstitutionalChangeDetails({ requestId, onBack, currentUser, onOpenWorknote }: ConstitutionalChangeDetailsProps) {
const [isActionDialogOpen, setIsActionDialogOpen] = useState(false);
const [actionType, setActionType] = useState<'approve' | 'reject' | 'hold'>('approve');
const [comments, setComments] = useState('');
const [isUploadDialogOpen, setIsUploadDialogOpen] = useState(false);
const [isWorknoteDialogOpen, setIsWorknoteDialogOpen] = useState(false);
const [worknotes, setWorknotes] = useState(initialWorknotes);
const [newWorknote, setNewWorknote] = useState('');
// Find the request
const request = mockConstitutionalChangeRequests.find(r => r.id === requestId);
if (!request) {
return (
<div className="bg-white rounded-lg border border-slate-200 p-8 text-center">
<h2 className="text-slate-900 mb-2">Request Not Found</h2>
<p className="text-slate-600 mb-4">The constitutional change request you're looking for doesn't exist.</p>
<Button onClick={onBack}>Go Back</Button>
</div>
);
}
// Get required documents for this request
const requiredDocs = documentRequirements[request.targetType] || [];
// Calculate current stage index
const getCurrentStageIndex = () => {
const stageMap: Record<string, number> = {
'Dealer': 1,
'ASM': 2,
'RBM': 3,
'DD-ZM': 4,
'ZBH': 5,
'DD Lead': 6,
'FDD': 7,
'DD Head': 8,
'NBH': 9,
'DD H.O': 10,
'Closed': 13
};
return stageMap[request.currentStage] || 1;
};
const currentStageIndex = getCurrentStageIndex();
const handleAction = (type: 'approve' | 'reject' | 'hold') => {
setActionType(type);
setIsActionDialogOpen(true);
};
const handleSubmitAction = (e: React.FormEvent) => {
e.preventDefault();
const actionText = actionType === 'approve' ? 'approved' : actionType === 'reject' ? 'rejected' : 'put on hold';
toast.success(`Request ${actionText} successfully`);
setIsActionDialogOpen(false);
setComments('');
};
const handleUploadDocument = () => {
toast.success('Document uploaded successfully');
setIsUploadDialogOpen(false);
};
const handleAddWorknote = () => {
if (newWorknote.trim()) {
const newNote = {
id: worknotes.length + 1,
user: currentUser?.name || 'Anonymous',
role: currentUser?.role || 'User',
message: newWorknote,
timestamp: new Date().toLocaleString(),
avatar: currentUser?.name?.slice(0, 2).toUpperCase() || 'AN'
};
setWorknotes([...worknotes, newNote]);
setNewWorknote('');
toast.success('Worknote added successfully');
}
};
return (
<div className="space-y-6">
{/* Header */}
<div className="flex items-center justify-between">
<div className="flex items-center gap-4">
<Button
variant="outline"
onClick={onBack}
className="flex items-center gap-2"
>
<ArrowLeft className="w-4 h-4" />
Back
</Button>
<div>
<h1 className="text-slate-900">{request.id} - Constitutional Change Details</h1>
<p className="text-slate-600">
{request.dealerName} ({request.dealerCode})
</p>
</div>
</div>
<Badge className={getStatusColor(request.status)}>
{request.status}
</Badge>
</div>
{/* Request Overview */}
<Card>
<CardHeader>
<CardTitle>Request Overview</CardTitle>
</CardHeader>
<CardContent>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
<div>
<p className="text-slate-600 text-sm mb-1">Dealer Details</p>
<p className="text-slate-900">{request.dealerName}</p>
<p className="text-slate-600 text-sm">{request.dealerCode}</p>
<p className="text-slate-600 text-sm">{request.location}</p>
</div>
<div>
<p className="text-slate-600 text-sm mb-2">Constitutional Change</p>
<div className="flex items-center gap-2">
<Badge className={getTypeColor(request.currentType)}>
{request.currentType}
</Badge>
<ArrowRight className="w-4 h-4 text-slate-400" />
<Badge className={getTypeColor(request.targetType)}>
{request.targetType}
</Badge>
</div>
</div>
<div>
<p className="text-slate-600 text-sm mb-1">Request Information</p>
<p className="text-slate-900 text-sm">Submitted: {request.submittedOn}</p>
<p className="text-slate-600 text-sm">By: {request.submittedBy}</p>
<p className="text-slate-900 text-sm mt-2">Current Stage: {request.currentStage}</p>
</div>
</div>
<div className="mt-6">
<p className="text-slate-600 text-sm mb-2">Reason for Change</p>
<p className="text-slate-900">{request.reason}</p>
</div>
</CardContent>
</Card>
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
{/* Main Content */}
<div className="lg:col-span-2 space-y-6">
<Card>
<Tabs defaultValue="workflow" className="w-full">
<CardHeader className="pb-4">
<div className="overflow-x-auto -mx-6 px-6">
<TabsList className="w-max min-w-full justify-start">
<TabsTrigger value="workflow">Workflow Progress</TabsTrigger>
<TabsTrigger value="documents">Documents</TabsTrigger>
<TabsTrigger value="history">History & Audit Trail</TabsTrigger>
</TabsList>
</div>
</CardHeader>
<CardContent>
{/* Workflow Progress Tab */}
<TabsContent value="workflow" className="mt-0">
{/* Progress Bar */}
<div className="mb-8">
<div className="flex items-center justify-between mb-2">
<span className="text-slate-900">Overall Progress</span>
<span className="text-slate-600">{request.progressPercentage}%</span>
</div>
<div className="h-3 bg-slate-200 rounded-full overflow-hidden">
<div
className="h-full bg-amber-600 transition-all duration-500"
style={{ width: `${request.progressPercentage}%` }}
/>
</div>
</div>
{/* Workflow Stages */}
<div className="space-y-4">
{workflowStages.map((stage, index) => {
const isCompleted = index < currentStageIndex - 1;
const isCurrent = index === currentStageIndex - 1;
const isPending = index > currentStageIndex - 1;
return (
<div key={stage.id} className="flex items-start gap-4">
{/* Status Icon */}
<div className="flex flex-col items-center">
<div className={`w-10 h-10 rounded-full flex items-center justify-center ${
isCompleted ? 'bg-green-100' :
isCurrent ? 'bg-amber-100' :
'bg-slate-100'
}`}>
{isCompleted ? (
<CheckCircle2 className="w-5 h-5 text-green-600" />
) : isCurrent ? (
<Clock className="w-5 h-5 text-amber-600" />
) : (
<AlertCircle className="w-5 h-5 text-slate-400" />
)}
</div>
{index < workflowStages.length - 1 && (
<div className={`w-0.5 h-12 ${
isCompleted ? 'bg-green-300' : 'bg-slate-200'
}`} />
)}
</div>
{/* Stage Info */}
<div className={`flex-1 pb-8 ${isCurrent ? 'bg-amber-50 -ml-4 pl-4 pr-4 py-3 rounded-lg border border-amber-200' : ''}`}>
<div className="flex items-center justify-between">
<div>
<h4 className={`${isCurrent ? 'text-amber-900' : 'text-slate-900'}`}>
{stage.name}
</h4>
<p className={`text-sm ${isCurrent ? 'text-amber-700' : 'text-slate-600'}`}>
Responsible: {stage.role}
</p>
</div>
<Badge className={
isCompleted ? 'bg-green-100 text-green-700 border-green-300' :
isCurrent ? 'bg-amber-100 text-amber-700 border-amber-300' :
'bg-slate-100 text-slate-500 border-slate-300'
}>
{isCompleted ? 'Completed' : isCurrent ? 'In Progress' : 'Pending'}
</Badge>
</div>
</div>
</div>
);
})}
</div>
</TabsContent>
{/* Documents Tab */}
<TabsContent value="documents" className="mt-0">
<Tabs defaultValue="required" className="w-full">
<TabsList className="w-full justify-start mb-4">
<TabsTrigger value="required">Required for Process</TabsTrigger>
<TabsTrigger value="existing">Existing Documents</TabsTrigger>
</TabsList>
{/* Required Documents Sub-tab */}
<TabsContent value="required" className="mt-0">
<div className="space-y-4">
<div className="flex items-center justify-between">
<h4 className="text-slate-900">Document Checklist</h4>
<Dialog open={isUploadDialogOpen} onOpenChange={setIsUploadDialogOpen}>
<DialogTrigger asChild>
<Button size="sm" className="bg-amber-600 hover:bg-amber-700">
<Upload className="w-4 h-4 mr-2" />
Upload Document
</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Upload Document</DialogTitle>
<DialogDescription>
Select the document type and upload the file
</DialogDescription>
</DialogHeader>
<div className="space-y-4">
<div>
<Label>Document Type</Label>
<select className="w-full mt-1 px-3 py-2 border border-slate-300 rounded-md">
{requiredDocs.map(docNum => (
<option key={docNum} value={docNum}>
{documentNames[docNum]}
</option>
))}
</select>
</div>
<div>
<Label>Upload File</Label>
<Input type="file" className="mt-1" />
</div>
</div>
<DialogFooter>
<Button variant="outline" onClick={() => setIsUploadDialogOpen(false)}>
Cancel
</Button>
<Button
className="bg-amber-600 hover:bg-amber-700"
onClick={handleUploadDocument}
>
Upload
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</div>
<div className="space-y-2">
{requiredDocs.map((docNum) => {
const uploaded = mockUploadedDocuments.find(d => d.docNumber === docNum);
return (
<div
key={docNum}
className={`flex items-center justify-between p-3 rounded-lg border ${
uploaded ? 'bg-green-50 border-green-200' : 'bg-slate-50 border-slate-200'
}`}
>
<div className="flex items-center gap-3">
{uploaded ? (
<CheckCircle2 className="w-5 h-5 text-green-600" />
) : (
<AlertCircle className="w-5 h-5 text-slate-400" />
)}
<div>
<p className={uploaded ? 'text-green-900' : 'text-slate-900'}>
{documentNames[docNum]}
</p>
{uploaded && (
<p className="text-green-700 text-sm">{uploaded.fileName}</p>
)}
</div>
</div>
{uploaded ? (
<Badge className="bg-green-100 text-green-700 border-green-300">
{uploaded.status}
</Badge>
) : (
<Badge className="bg-slate-100 text-slate-600 border-slate-300">
Not Uploaded
</Badge>
)}
</div>
);
})}
</div>
</div>
</TabsContent>
{/* Existing Documents Sub-tab */}
<TabsContent value="existing" className="mt-0">
{mockUploadedDocuments.length > 0 ? (
<div>
<h4 className="text-slate-900 mb-3">All Uploaded Documents</h4>
<div className="border border-slate-200 rounded-lg overflow-hidden">
<Table>
<TableHeader>
<TableRow className="bg-slate-50">
<TableHead>Document Name</TableHead>
<TableHead>File Name</TableHead>
<TableHead>Uploaded On</TableHead>
<TableHead>Uploaded By</TableHead>
<TableHead>Status</TableHead>
<TableHead>Actions</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{mockUploadedDocuments.map((doc) => (
<TableRow key={doc.docNumber}>
<TableCell className="text-slate-900">
{documentNames[doc.docNumber]}
</TableCell>
<TableCell className="text-slate-600">
{doc.fileName}
</TableCell>
<TableCell className="text-slate-600">
{doc.uploadedOn}
</TableCell>
<TableCell className="text-slate-600">
{doc.uploadedBy}
</TableCell>
<TableCell>
<Badge className={getStatusColor(doc.status)}>
{doc.status}
</Badge>
</TableCell>
<TableCell>
<div className="flex items-center gap-2">
<Button size="sm" variant="outline">
<Eye className="w-4 h-4 mr-1" />
View
</Button>
<Button size="sm" variant="outline">
<Download className="w-4 h-4 mr-1" />
Download
</Button>
</div>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
</div>
) : (
<div className="text-center py-8 text-slate-500">
No documents uploaded yet
</div>
)}
</TabsContent>
</Tabs>
</TabsContent>
{/* History Tab */}
<TabsContent value="history" className="mt-0">
<div className="space-y-4">
{mockWorkflowHistory.map((entry, index) => (
<div key={index} className="flex items-start gap-4 pb-4 border-b border-slate-200 last:border-0">
<div className={`w-10 h-10 rounded-full flex items-center justify-center flex-shrink-0 ${
entry.status === 'Completed' ? 'bg-green-100' :
entry.status === 'In Progress' ? 'bg-amber-100' :
'bg-slate-100'
}`}>
{entry.status === 'Completed' ? (
<CheckCircle2 className="w-5 h-5 text-green-600" />
) : entry.status === 'In Progress' ? (
<Clock className="w-5 h-5 text-amber-600" />
) : (
<User className="w-5 h-5 text-slate-600" />
)}
</div>
<div className="flex-1">
<div className="flex items-start justify-between">
<div>
<h4 className="text-slate-900">{entry.stage}</h4>
<p className="text-slate-600 text-sm">{entry.actor}</p>
</div>
<Badge className={getStatusColor(entry.status)}>
{entry.action}
</Badge>
</div>
<p className="text-slate-600 text-sm mt-2">{entry.comments}</p>
<p className="text-slate-500 text-sm mt-1">{entry.date}</p>
</div>
</div>
))}
</div>
</TabsContent>
</CardContent>
</Tabs>
</Card>
</div>
{/* Right Sidebar - Actions */}
<div className="space-y-6">
{/* Current Status Card */}
<Card>
<CardHeader>
<CardTitle>Current Status</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<div>
<p className="text-slate-600 text-sm">Current Stage</p>
<p className="text-slate-900">{request.currentStage}</p>
</div>
</CardContent>
</Card>
{/* Actions Card */}
<Card>
<CardHeader>
<CardTitle>Actions</CardTitle>
</CardHeader>
<CardContent className="space-y-3">
<Button
className="w-full bg-green-600 hover:bg-green-700"
onClick={() => handleAction('approve')}
>
<CheckCircle2 className="w-4 h-4 mr-2" />
Approve Request
</Button>
<Button
variant="destructive"
className="w-full"
onClick={() => handleAction('reject')}
>
<AlertCircle className="w-4 h-4 mr-2" />
Reject Request
</Button>
<div className="border-t border-slate-200 pt-3 mt-3">
<Button
variant="outline"
className="w-full border-blue-300 text-blue-700 hover:bg-blue-50"
onClick={() => {
if (onOpenWorknote) {
onOpenWorknote(requestId, 'constitutional-change', `${request.dealerName} (${request.dealerCode}) - Constitutional Change Request`);
} else {
setIsWorknoteDialogOpen(true);
}
}}
>
<MessageSquare className="w-4 h-4 mr-2" />
Worknotes ({worknotes.length})
</Button>
</div>
</CardContent>
</Card>
</div>
</div>
{/* Action Dialog */}
<Dialog open={isActionDialogOpen} onOpenChange={setIsActionDialogOpen}>
<DialogContent>
<DialogHeader>
<DialogTitle>
{actionType === 'approve' ? 'Approve Request' :
actionType === 'reject' ? 'Reject Request' :
'Put Request on Hold'}
</DialogTitle>
<DialogDescription>
Please provide comments for this action. This will be recorded in the audit trail.
</DialogDescription>
</DialogHeader>
<form onSubmit={handleSubmitAction} className="space-y-4">
<div>
<Label htmlFor="comments">Comments *</Label>
<Textarea
id="comments"
value={comments}
onChange={(e) => setComments(e.target.value)}
placeholder="Enter your comments..."
rows={4}
required
/>
</div>
<DialogFooter>
<Button
type="button"
variant="outline"
onClick={() => setIsActionDialogOpen(false)}
>
Cancel
</Button>
<Button
type="submit"
className={
actionType === 'approve' ? 'bg-green-600 hover:bg-green-700' :
actionType === 'reject' ? 'bg-red-600 hover:bg-red-700' :
'bg-amber-600 hover:bg-amber-700'
}
>
{actionType === 'approve' ? 'Approve' :
actionType === 'reject' ? 'Reject' :
'Put on Hold'}
</Button>
</DialogFooter>
</form>
</DialogContent>
</Dialog>
{/* Worknotes Dialog */}
<Dialog open={isWorknoteDialogOpen} onOpenChange={setIsWorknoteDialogOpen}>
<DialogContent className="max-w-3xl max-h-[80vh]">
<DialogHeader>
<DialogTitle>Worknotes - Discussion Platform</DialogTitle>
<DialogDescription>
Collaborate with team members on this constitutional change request. All discussions are logged and timestamped.
</DialogDescription>
</DialogHeader>
<div className="space-y-4">
{/* Discussion Thread */}
<div className="space-y-2">
<Label>Discussion History ({worknotes.length} messages)</Label>
<div className="border border-slate-200 rounded-lg p-4 max-h-96 overflow-y-auto bg-slate-50">
<div className="space-y-4">
{worknotes.map((note) => (
<div key={note.id} className="flex items-start gap-3">
{/* Avatar */}
<div className="w-10 h-10 rounded-full bg-amber-600 flex items-center justify-center text-white flex-shrink-0">
{note.avatar}
</div>
{/* Message Content */}
<div className="flex-1 bg-white rounded-lg p-3 border border-slate-200">
<div className="flex items-start justify-between mb-1">
<div>
<h5 className="text-slate-900">{note.user}</h5>
<Badge variant="outline" className="border-slate-300 text-xs">
{note.role}
</Badge>
</div>
<span className="text-slate-500 text-xs">{note.timestamp}</span>
</div>
<p className="text-slate-700 text-sm mt-2">{note.message}</p>
</div>
</div>
))}
</div>
</div>
</div>
{/* Add New Worknote */}
<div className="space-y-2">
<Label htmlFor="newWorknote">Add New Worknote</Label>
<Textarea
id="newWorknote"
value={newWorknote}
onChange={(e) => setNewWorknote(e.target.value)}
placeholder="Type your message here... Share updates, ask questions, or provide feedback."
rows={3}
className="resize-none"
/>
<p className="text-slate-500 text-xs">
Posting as: {currentUser?.name || 'Anonymous'} ({currentUser?.role || 'User'})
</p>
</div>
</div>
<DialogFooter>
<Button
type="button"
variant="outline"
onClick={() => {
setIsWorknoteDialogOpen(false);
setNewWorknote('');
}}
>
Close
</Button>
<Button
type="button"
className="bg-amber-600 hover:bg-amber-700"
onClick={handleAddWorknote}
disabled={!newWorknote.trim()}
>
<MessageSquare className="w-4 h-4 mr-2" />
Post Worknote
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</div>
);
}