a0bdd2b5b4
Replace all corruption variants with HTML entities across 226 view files: - 3-char UTF-8-as-Win1252 sequences (ae-corruption) - Standalone smart/curly quotes that break C# Razor expressions - Partially re-corrupted variants where the 3rd byte was normalised to ASCII tools/Fix-Encoding.ps1: re-runnable sweep; uses [char] code points so the script itself never contains a literal non-ASCII character; supports -DryRun .githooks/pre-commit: blocks commits containing the ae-corruption byte signature (xc3xa2xe2x82xac); git core.hooksPath = .githooks so the hook is repo-committed and active for all future work on this machine. Build clean; 225 unit tests pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
518 lines
30 KiB
Plaintext
518 lines
30 KiB
Plaintext
@model List<PowderCoating.Application.DTOs.Company.CompanyListDto>
|
|
|
|
@section Styles {
|
|
<style>
|
|
[data-bs-theme="dark"] a.text-dark { color: var(--bs-body-color) !important; }
|
|
[data-bs-theme="dark"] .bi-building[style*="color:#ccc"] { color: var(--bs-secondary-color) !important; }
|
|
</style>
|
|
}
|
|
|
|
@{
|
|
ViewData["Title"] = "Companies";
|
|
ViewData["PageIcon"] = "bi-building";
|
|
var planConfigs = ((IEnumerable<PowderCoating.Core.Entities.SubscriptionPlanConfig>)ViewBag.PlanConfigs)
|
|
.OrderBy(c => c.SortOrder).ToList();
|
|
var planBadgeColors = planConfigs.Select((c, i) => (c.Plan, i))
|
|
.ToDictionary(x => x.Plan, x => x.i switch { 0 => "bg-secondary", 1 => "bg-primary", 2 => "bg-info", _ => "bg-success" });
|
|
var planNames = planConfigs.ToDictionary(c => c.Plan, c => c.DisplayName);
|
|
string PlanBadge(int plan) => planBadgeColors.TryGetValue(plan, out var c) ? c : "bg-secondary";
|
|
string PlanName(int plan) => planNames.TryGetValue(plan, out var n) ? n : plan.ToString();
|
|
|
|
var searchTerm = (string?)ViewBag.SearchTerm;
|
|
var sortColumn = (string)(ViewBag.SortColumn ?? "CompanyName");
|
|
var sortDirection = (string)(ViewBag.SortDirection ?? "asc");
|
|
var pageNumber = (int)(ViewBag.PageNumber ?? 1);
|
|
var pageSize = (int)(ViewBag.PageSize ?? 25);
|
|
var totalPages = (int)(ViewBag.TotalPages ?? 1);
|
|
var totalCount = (int)(ViewBag.TotalCount ?? 0);
|
|
var impersonatingId = (int?)(ViewBag.ImpersonatingCompanyId);
|
|
var showChurned = (bool)(ViewBag.ShowChurned ?? false);
|
|
var churnedCount = (int)(ViewBag.ChurnedCount ?? 0);
|
|
|
|
string SortLink(string col)
|
|
{
|
|
var dir = (sortColumn == col && sortDirection == "asc") ? "desc" : "asc";
|
|
return Url.Action("Index", new { searchTerm, sortColumn = col, sortDirection = dir, pageNumber = 1, pageSize, showChurned })!;
|
|
}
|
|
|
|
string SortIcon(string col)
|
|
{
|
|
if (sortColumn != col) return "bi-chevron-expand text-muted";
|
|
return sortDirection == "asc" ? "bi-chevron-up" : "bi-chevron-down";
|
|
}
|
|
}
|
|
|
|
<div class="container-fluid">
|
|
<div class="d-flex justify-content-end mb-4">
|
|
<a asp-action="Create" class="btn btn-primary">
|
|
<i class="bi bi-plus-circle me-1"></i>Create New Company
|
|
</a>
|
|
</div>
|
|
|
|
<!-- Search -->
|
|
<div class="card shadow-sm mb-3">
|
|
<div class="card-body py-2">
|
|
<form asp-action="Index" method="get" class="row g-2 align-items-end">
|
|
<input type="hidden" name="sortColumn" value="@sortColumn" />
|
|
<input type="hidden" name="sortDirection" value="@sortDirection" />
|
|
<input type="hidden" name="pageSize" value="@pageSize" />
|
|
<input type="hidden" name="showChurned" value="@showChurned.ToString().ToLower()" />
|
|
<div class="col-md-6">
|
|
<div class="input-group">
|
|
<span class="input-group-text"><i class="bi bi-search"></i></span>
|
|
<input type="text" name="searchTerm" class="form-control"
|
|
placeholder="Search by name, code, email, phone…"
|
|
value="@searchTerm" />
|
|
</div>
|
|
</div>
|
|
<div class="col-auto">
|
|
<button type="submit" class="btn btn-primary"><i class="bi bi-search"></i></button>
|
|
@if (!string.IsNullOrWhiteSpace(searchTerm))
|
|
{
|
|
<a asp-action="Index" asp-route-sortColumn="@sortColumn"
|
|
asp-route-sortDirection="@sortDirection" asp-route-pageSize="@pageSize"
|
|
class="btn btn-outline-secondary ms-1">Clear</a>
|
|
}
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
@if (churnedCount > 0 && !showChurned)
|
|
{
|
|
<div class="alert alert-secondary alert-permanent d-flex align-items-center gap-2 mb-3 py-2">
|
|
<i class="bi bi-eye-slash text-muted"></i>
|
|
<span class="small"><strong>@churnedCount</strong> churned @(churnedCount == 1 ? "account" : "accounts") (expired or canceled 14+ days ago) hidden.</span>
|
|
<a href="@Url.Action("Index", new { searchTerm, sortColumn, sortDirection, pageNumber = 1, pageSize, showChurned = true })"
|
|
class="btn btn-sm btn-outline-secondary ms-auto py-0">Show churned</a>
|
|
</div>
|
|
}
|
|
else if (showChurned && churnedCount > 0)
|
|
{
|
|
<div class="alert alert-warning alert-permanent d-flex align-items-center gap-2 mb-3 py-2">
|
|
<i class="bi bi-eye text-warning"></i>
|
|
<span class="small">Showing all accounts including <strong>@churnedCount</strong> churned.</span>
|
|
<a href="@Url.Action("Index", new { searchTerm, sortColumn, sortDirection, pageNumber = 1, pageSize, showChurned = false })"
|
|
class="btn btn-sm btn-outline-secondary ms-auto py-0">Hide churned</a>
|
|
</div>
|
|
}
|
|
|
|
<div class="card shadow-sm">
|
|
<div class="card-body p-0">
|
|
@if (Model != null && Model.Any())
|
|
{
|
|
<div class="table-responsive">
|
|
<table class="table table-hover mb-0">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th>
|
|
<a href="@SortLink("CompanyName")" class="text-decoration-none text-dark d-flex align-items-center gap-1">
|
|
Company Name <i class="bi @SortIcon("CompanyName")"></i>
|
|
</a>
|
|
</th>
|
|
<th>Code</th>
|
|
<th>Contact Email</th>
|
|
<th>Phone</th>
|
|
<th>
|
|
<a href="@SortLink("Plan")" class="text-decoration-none text-dark d-flex align-items-center gap-1">
|
|
Plan <i class="bi @SortIcon("Plan")"></i>
|
|
</a>
|
|
</th>
|
|
<th>Health</th>
|
|
<th>Users</th>
|
|
<th>Setup Wizard</th>
|
|
<th>
|
|
<a href="@SortLink("Status")" class="text-decoration-none text-dark d-flex align-items-center gap-1">
|
|
Status <i class="bi @SortIcon("Status")"></i>
|
|
</a>
|
|
</th>
|
|
<th>
|
|
<a href="@SortLink("Created")" class="text-decoration-none text-dark d-flex align-items-center gap-1">
|
|
Created <i class="bi @SortIcon("Created")"></i>
|
|
</a>
|
|
</th>
|
|
<th class="text-end">Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@foreach (var company in Model)
|
|
{
|
|
var isImpersonating = impersonatingId.HasValue && impersonatingId.Value == company.Id;
|
|
var detailsUrl = Url.Action("Details", new { id = company.Id });
|
|
<tr class="@(isImpersonating ? "table-warning" : "")" style="cursor:pointer"
|
|
onclick="window.location='@detailsUrl'">
|
|
<td>
|
|
<strong>@company.CompanyName</strong>
|
|
@if (isImpersonating)
|
|
{
|
|
<span class="badge bg-warning text-dark ms-1">
|
|
<i class="bi bi-eye-fill me-1"></i>Active
|
|
</span>
|
|
}
|
|
</td>
|
|
<td>
|
|
@if (!string.IsNullOrEmpty(company.CompanyCode))
|
|
{
|
|
<span class="badge bg-secondary">@company.CompanyCode</span>
|
|
}
|
|
</td>
|
|
<td>@company.PrimaryContactEmail</td>
|
|
<td>@company.Phone</td>
|
|
<td>
|
|
<span class="badge @PlanBadge(company.SubscriptionPlan)">@PlanName(company.SubscriptionPlan)</span>
|
|
</td>
|
|
<td>
|
|
@{
|
|
var (hBadge, hLabel) = company.HealthRisk switch {
|
|
"Healthy" => ("bg-success-subtle text-success-emphasis border border-success-subtle", "Healthy"),
|
|
"AtRisk" => ("bg-warning-subtle text-warning-emphasis border border-warning-subtle", "At Risk"),
|
|
"Critical" => ("bg-danger-subtle text-danger-emphasis border border-danger-subtle", "Critical"),
|
|
"NeverActivated" => ("bg-secondary-subtle text-secondary-emphasis border border-secondary-subtle", "Never Active"),
|
|
_ => ("bg-secondary-subtle text-secondary-emphasis border border-secondary-subtle", company.HealthRisk)
|
|
};
|
|
}
|
|
<span class="badge @hBadge" title="Score: @company.HealthScore">@hLabel</span>
|
|
</td>
|
|
<td>
|
|
<span class="badge bg-primary rounded-pill">@company.UserCount</span>
|
|
</td>
|
|
<td>
|
|
@if (company.WizardCompleted)
|
|
{
|
|
var tooltip = company.WizardCompletedByName != null
|
|
? $"Completed by {company.WizardCompletedByName}"
|
|
+ (company.WizardCompletedAt.HasValue
|
|
? $" on {company.WizardCompletedAt.Value.Tz(ViewBag.CompanyTimeZone as string):MMM d, yyyy}"
|
|
: "")
|
|
: "Completed";
|
|
<span class="badge bg-success" title="@tooltip" data-bs-toggle="tooltip">
|
|
<i class="bi bi-check-circle-fill me-1"></i>Done
|
|
</span>
|
|
}
|
|
else
|
|
{
|
|
<span class="badge bg-light text-muted border">
|
|
<i class="bi bi-hourglass me-1"></i>Pending
|
|
</span>
|
|
}
|
|
</td>
|
|
<td>
|
|
@if (company.IsActive)
|
|
{
|
|
<span class="badge bg-success">Active</span>
|
|
}
|
|
else
|
|
{
|
|
<span class="badge bg-danger">Inactive</span>
|
|
}
|
|
</td>
|
|
<td>
|
|
<small class="text-muted">@company.CreatedAt.ToString("MMM d, yyyy")</small>
|
|
</td>
|
|
<td class="text-end" onclick="event.stopPropagation()">
|
|
<div class="btn-group btn-group-sm" role="group">
|
|
<a asp-action="Details" asp-route-id="@company.Id"
|
|
class="btn btn-outline-primary" title="View Details">
|
|
<i class="bi bi-eye"></i>
|
|
</a>
|
|
<a asp-action="Edit" asp-route-id="@company.Id"
|
|
class="btn btn-outline-secondary" title="Edit">
|
|
<i class="bi bi-pencil"></i>
|
|
</a>
|
|
<a asp-controller="SubscriptionManagement" asp-action="Manage" asp-route-id="@company.Id"
|
|
class="btn btn-outline-info" title="Manage Subscription & Features">
|
|
<i class="bi bi-credit-card"></i>
|
|
</a>
|
|
<form asp-action="ToggleActive" asp-route-id="@company.Id"
|
|
method="post" class="d-inline">
|
|
@Html.AntiForgeryToken()
|
|
<button type="submit"
|
|
class="btn @(company.IsActive ? "btn-outline-warning" : "btn-outline-success")"
|
|
title="@(company.IsActive ? "Deactivate" : "Activate")">
|
|
<i class="bi bi-@(company.IsActive ? "pause" : "play")"></i>
|
|
</button>
|
|
</form>
|
|
@if (isImpersonating)
|
|
{
|
|
<form asp-action="StopImpersonating" method="post" class="d-inline">
|
|
@Html.AntiForgeryToken()
|
|
<button type="submit" class="btn btn-warning" title="Stop Impersonating">
|
|
<i class="bi bi-x-circle"></i>
|
|
</button>
|
|
</form>
|
|
}
|
|
else
|
|
{
|
|
<form asp-action="StartImpersonating" method="post" class="d-inline">
|
|
@Html.AntiForgeryToken()
|
|
<input type="hidden" name="companyId" value="@company.Id" />
|
|
<button type="submit" class="btn btn-outline-dark" title="Impersonate this company">
|
|
<i class="bi bi-person-fill-gear"></i>
|
|
</button>
|
|
</form>
|
|
}
|
|
<button type="button"
|
|
class="btn btn-outline-danger"
|
|
title="Delete Company"
|
|
onclick="event.stopPropagation(); openDeleteModal(@company.Id, '@Html.Raw(company.CompanyName.Replace("'", "\\'"))', @company.UserCount, @company.JobCount, @company.QuoteCount, @company.CustomerCount)">
|
|
<i class="bi bi-trash"></i>
|
|
</button>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<!-- Mobile card view — shown on screens < 992px (table-responsive hidden by mobile-cards.css) -->
|
|
<div class="mobile-card-view">
|
|
<div class="mobile-card-list">
|
|
@foreach (var company in Model)
|
|
{
|
|
var isImpersonating = impersonatingId.HasValue && impersonatingId.Value == company.Id;
|
|
<a href="@Url.Action("Details", new { id = company.Id })" class="mobile-data-card text-decoration-none">
|
|
<div class="mobile-card-header">
|
|
<div class="mobile-card-icon bg-primary"><i class="bi bi-building"></i></div>
|
|
<div class="mobile-card-title">
|
|
<h6>@company.CompanyName</h6>
|
|
<small class="text-muted">@company.PrimaryContactEmail</small>
|
|
</div>
|
|
@if (company.IsActive)
|
|
{
|
|
<span class="badge bg-success">Active</span>
|
|
}
|
|
else
|
|
{
|
|
<span class="badge bg-danger">Inactive</span>
|
|
}
|
|
</div>
|
|
<div class="mobile-card-body">
|
|
<div class="mobile-card-row">
|
|
<span class="mobile-card-label">Plan</span>
|
|
<span class="mobile-card-value"><span class="badge @PlanBadge(company.SubscriptionPlan)">@PlanName(company.SubscriptionPlan)</span></span>
|
|
</div>
|
|
<div class="mobile-card-row">
|
|
<span class="mobile-card-label">Users</span>
|
|
<span class="mobile-card-value"><span class="badge bg-primary rounded-pill">@company.UserCount</span></span>
|
|
</div>
|
|
<div class="mobile-card-row">
|
|
<span class="mobile-card-label">Created</span>
|
|
<span class="mobile-card-value">@company.CreatedAt.ToString("MMM d, yyyy")</span>
|
|
</div>
|
|
@if (!string.IsNullOrEmpty(company.CompanyCode))
|
|
{
|
|
<div class="mobile-card-row">
|
|
<span class="mobile-card-label">Code</span>
|
|
<span class="mobile-card-value"><span class="badge bg-secondary">@company.CompanyCode</span></span>
|
|
</div>
|
|
}
|
|
</div>
|
|
<div class="mobile-card-footer">
|
|
<span class="btn btn-sm btn-outline-primary">View →</span>
|
|
</div>
|
|
</a>
|
|
}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Pagination -->
|
|
@if (totalPages > 1)
|
|
{
|
|
<div class="card-footer d-flex justify-content-between align-items-center">
|
|
<div class="text-muted small">
|
|
Showing @((pageNumber - 1) * pageSize + 1)–@(Math.Min(pageNumber * pageSize, totalCount)) of @totalCount companies
|
|
</div>
|
|
<div class="d-flex align-items-center gap-3">
|
|
<div>
|
|
<select class="form-select form-select-sm" onchange="changePageSize(this.value)">
|
|
@foreach (var size in new[] { 10, 25, 50, 100 })
|
|
{
|
|
<option value="@size" selected="@(pageSize == size)">@size per page</option>
|
|
}
|
|
</select>
|
|
</div>
|
|
<nav>
|
|
<ul class="pagination pagination-sm mb-0">
|
|
<li class="page-item @(pageNumber == 1 ? "disabled" : "")">
|
|
<a class="page-link" href="@Url.Action("Index", new { searchTerm, sortColumn, sortDirection, pageNumber = pageNumber - 1, pageSize, showChurned })">
|
|
<i class="bi bi-chevron-left"></i>
|
|
</a>
|
|
</li>
|
|
@for (int p = Math.Max(1, pageNumber - 2); p <= Math.Min(totalPages, pageNumber + 2); p++)
|
|
{
|
|
<li class="page-item @(p == pageNumber ? "active" : "")">
|
|
<a class="page-link" href="@Url.Action("Index", new { searchTerm, sortColumn, sortDirection, pageNumber = p, pageSize, showChurned })">@p</a>
|
|
</li>
|
|
}
|
|
<li class="page-item @(pageNumber == totalPages ? "disabled" : "")">
|
|
<a class="page-link" href="@Url.Action("Index", new { searchTerm, sortColumn, sortDirection, pageNumber = pageNumber + 1, pageSize, showChurned })">
|
|
<i class="bi bi-chevron-right"></i>
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
}
|
|
}
|
|
else
|
|
{
|
|
<div class="text-center py-5">
|
|
<i class="bi bi-building text-secondary" style="font-size: 3rem;"></i>
|
|
<p class="text-muted mt-3">
|
|
@if (!string.IsNullOrWhiteSpace(searchTerm))
|
|
{
|
|
<text>No companies match "<strong>@searchTerm</strong>".</text>
|
|
}
|
|
else
|
|
{
|
|
<text>No companies found.</text>
|
|
}
|
|
</p>
|
|
@if (string.IsNullOrWhiteSpace(searchTerm))
|
|
{
|
|
<a asp-action="Create" class="btn btn-primary">
|
|
<i class="bi bi-plus-circle me-1"></i>Create Your First Company
|
|
</a>
|
|
}
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Delete Company Modal -->
|
|
<div class="modal fade" id="deleteCompanyModal" tabindex="-1" aria-labelledby="deleteCompanyModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered modal-lg">
|
|
<div class="modal-content border-0 shadow-lg">
|
|
<div class="modal-header bg-danger text-white">
|
|
<h5 class="modal-title" id="deleteCompanyModalLabel">
|
|
<i class="bi bi-exclamation-triangle-fill me-2"></i>Delete Company
|
|
</h5>
|
|
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body p-4">
|
|
<p class="mb-3">
|
|
You are about to delete <strong id="modal-company-name"></strong>. This company has the following data:
|
|
</p>
|
|
<div class="row g-3 mb-4">
|
|
<div class="col-3">
|
|
<div class="card border text-center p-2">
|
|
<div class="fs-4 fw-bold text-primary" id="modal-user-count">0</div>
|
|
<small class="text-muted">Users</small>
|
|
</div>
|
|
</div>
|
|
<div class="col-3">
|
|
<div class="card border text-center p-2">
|
|
<div class="fs-4 fw-bold text-success" id="modal-job-count">0</div>
|
|
<small class="text-muted">Jobs</small>
|
|
</div>
|
|
</div>
|
|
<div class="col-3">
|
|
<div class="card border text-center p-2">
|
|
<div class="fs-4 fw-bold text-info" id="modal-quote-count">0</div>
|
|
<small class="text-muted">Quotes</small>
|
|
</div>
|
|
</div>
|
|
<div class="col-3">
|
|
<div class="card border text-center p-2">
|
|
<div class="fs-4 fw-bold text-warning" id="modal-customer-count">0</div>
|
|
<small class="text-muted">Customers</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<hr />
|
|
|
|
<!-- Soft Delete Section -->
|
|
<div class="mb-4">
|
|
<h6 class="fw-bold text-warning"><i class="bi bi-pause-circle me-2"></i>Soft Delete (Deactivate)</h6>
|
|
<p class="text-muted small mb-2">
|
|
The company and all users will be <strong>deactivated</strong> but data is preserved.
|
|
This is reversible and can be undone by an administrator.
|
|
</p>
|
|
<form id="softDeleteForm" method="post">
|
|
@Html.AntiForgeryToken()
|
|
<input type="hidden" name="id" id="soft-delete-id" />
|
|
<button type="submit" class="btn btn-warning">
|
|
<i class="bi bi-pause-circle me-1"></i>Deactivate Company
|
|
</button>
|
|
</form>
|
|
</div>
|
|
|
|
<hr />
|
|
|
|
<!-- Hard Delete Section -->
|
|
<div>
|
|
<h6 class="fw-bold text-danger"><i class="bi bi-fire me-2"></i>Hard Delete (Permanent)</h6>
|
|
<p class="text-muted small mb-2">
|
|
<strong class="text-danger">This cannot be undone.</strong>
|
|
All company data — users, jobs, quotes, customers, invoices, and everything else — will be
|
|
<strong>permanently and irreversibly deleted</strong> from the database.
|
|
</p>
|
|
<div class="alert alert-danger alert-permanent py-2 mb-3">
|
|
<i class="bi bi-exclamation-octagon-fill me-2"></i>
|
|
Type <strong>DELETE</strong> below to enable permanent deletion.
|
|
</div>
|
|
<div class="mb-3">
|
|
<input type="text"
|
|
id="hard-delete-confirmation"
|
|
class="form-control"
|
|
placeholder="Type DELETE to confirm"
|
|
autocomplete="off"
|
|
oninput="validateHardDelete(this.value)" />
|
|
</div>
|
|
<form id="hardDeleteForm" method="post">
|
|
@Html.AntiForgeryToken()
|
|
<input type="hidden" name="id" id="hard-delete-id" />
|
|
<input type="hidden" name="confirmation" value="DELETE" />
|
|
<button type="submit" id="hard-delete-btn" class="btn btn-danger" disabled>
|
|
<i class="bi bi-trash-fill me-1"></i>Permanently Delete Everything
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Cancel</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
@section Scripts {
|
|
<script>
|
|
function changePageSize(size) {
|
|
const url = new URL(window.location.href);
|
|
url.searchParams.set('pageSize', size);
|
|
url.searchParams.set('pageNumber', '1');
|
|
url.searchParams.set('showChurned', '@showChurned.ToString().ToLower()');
|
|
window.location.href = url.toString();
|
|
}
|
|
|
|
function openDeleteModal(id, name, users, jobs, quotes, customers) {
|
|
document.getElementById('modal-company-name').textContent = name;
|
|
document.getElementById('modal-user-count').textContent = users;
|
|
document.getElementById('modal-job-count').textContent = jobs;
|
|
document.getElementById('modal-quote-count').textContent = quotes;
|
|
document.getElementById('modal-customer-count').textContent = customers;
|
|
|
|
document.getElementById('soft-delete-id').value = id;
|
|
document.getElementById('hard-delete-id').value = id;
|
|
|
|
document.getElementById('softDeleteForm').action = '/Companies/SoftDelete/' + id;
|
|
document.getElementById('hardDeleteForm').action = '/Companies/HardDelete/' + id;
|
|
|
|
// Reset hard delete input
|
|
document.getElementById('hard-delete-confirmation').value = '';
|
|
document.getElementById('hard-delete-btn').disabled = true;
|
|
|
|
new bootstrap.Modal(document.getElementById('deleteCompanyModal')).show();
|
|
}
|
|
|
|
function validateHardDelete(value) {
|
|
document.getElementById('hard-delete-btn').disabled = (value !== 'DELETE');
|
|
}
|
|
</script>
|
|
}
|