deploy
Deploy restore contacts feature
fc06b79
@inject ContactManagementAPI.Services.UserContextService UserContext
@model ContactManagementAPI.Models.Contact
@{
ViewData["Title"] = $"Documents - {Model.FirstName} {Model.LastName}";
}
<div class="documents-container">
<div class="documents-header">
<a href="/home/details/@Model.Id" class="btn btn-secondary">
<i class="fas fa-arrow-left"></i> Back
</a>
<h2><i class="fas fa-file-archive"></i> Documents - @Model.FirstName @Model.LastName</h2>
</div>
@if (UserContext.HasRight(RightsCatalog.DocumentsManage))
{
<div class="document-upload">
<div class="upload-form">
<h4>Upload Document</h4>
<form id="uploadForm">
<div class="form-row">
<div class="form-group">
<label for="documentType">Document Type:</label>
<select id="documentType" class="form-control">
<option value="Other">Other</option>
<option value="ID">ID / Passport</option>
<option value="Address">Address Proof</option>
<option value="Contract">Contract</option>
<option value="Invoice">Invoice</option>
<option value="Certificate">Certificate</option>
<option value="Medical">Medical Records</option>
<option value="Financial">Financial</option>
</select>
</div>
<div class="form-group">
<label for="documentFile">Select File:</label>
<input type="file" id="documentFile" class="form-control" accept=".pdf,.doc,.docx,.xls,.xlsx,.txt,.ppt,.pptx" />
</div>
<div class="form-group">
<button type="button" class="btn btn-primary" onclick="uploadDocument()">
<i class="fas fa-upload"></i> Upload
</button>
</div>
</div>
</form>
</div>
</div>
}
@if (Model.Documents.Count == 0)
{
<div class="no-items">
<i class="fas fa-folder-open"></i>
<p>No documents attached. Upload your first document!</p>
</div>
}
else
{
<div class="document-list">
<table>
<thead>
<tr>
<th>File Name</th>
<th>Type</th>
<th>Size</th>
<th>Uploaded</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach (var doc in Model.Documents.OrderByDescending(d => d.UploadedAt))
{
<tr>
<td>
<i class="fas fa-file"></i> @doc.FileName
</td>
<td><span class="badge">@doc.DocumentType</span></td>
<td>@FormatFileSize(doc.FileSize)</td>
<td>@doc.UploadedAt.ToString("dd/MM/yyyy HH:mm")</td>
<td>
<a href="/document/download/@doc.Id/@Model.Id" class="btn btn-sm btn-info">
<i class="fas fa-download"></i> Download
</a>
@if (UserContext.HasRight(RightsCatalog.DocumentsManage))
{
<button type="button" class="btn btn-sm btn-danger delete-doc-btn" data-doc-id="@doc.Id">
<i class="fas fa-trash"></i> Delete
</button>
}
</td>
</tr>
}
</tbody>
</table>
</div>
}
</div>
<script>
const contactId = @Model.Id;
async function uploadDocument() {
const fileInput = document.getElementById('documentFile');
const documentType = document.getElementById('documentType').value;
if (!fileInput.files.length) {
alert('Please select a file');
return;
}
const formData = new FormData();
formData.append('contactId', contactId);
formData.append('documentFile', fileInput.files[0]);
formData.append('documentType', documentType);
try {
const response = await fetch('/document/upload', {
method: 'POST',
body: formData
});
const data = await response.json();
if (data.success) {
alert('Document uploaded successfully');
location.reload();
} else {
alert('Error: ' + data.message);
}
} catch (error) {
alert('Upload failed: ' + error.message);
}
}
document.querySelectorAll('.delete-doc-btn').forEach(btn => {
btn.addEventListener('click', async function() {
if (!confirm('Are you sure you want to delete this document?')) return;
const docId = this.dataset.docId;
try {
const response = await fetch('/document/delete', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ id: docId, contactId })
});
const data = await response.json();
if (data.success) {
location.reload();
} else {
alert('Error: ' + data.message);
}
} catch (error) {
alert('Error: ' + error.message);
}
});
});
@functions {
private string FormatFileSize(long bytes) {
if (bytes < 1024) return bytes + " B";
if (bytes < 1024 * 1024) return (bytes / 1024.0).ToString("F2") + " KB";
return (bytes / (1024.0 * 1024.0)).ToString("F2") + " MB";
}
}
</script>