Added registrar tech contact; improvements to view registrar

This commit is contained in:
Pinga 2025-05-21 11:46:31 +03:00
parent 49080e783e
commit 46002b1505
5 changed files with 544 additions and 8 deletions

View file

@ -47,6 +47,7 @@ class RegistrarsController extends Controller
$data['owner']['cc'] = strtoupper($data['owner']['cc']);
$data['billing']['cc'] = strtoupper($data['billing']['cc']);
$data['tech']['cc'] = strtoupper($data['tech']['cc']);
$data['abuse']['cc'] = strtoupper($data['abuse']['cc']);
$phoneValidator = v::regex('/^\+\d{1,3}\.\d{2,12}$/');
@ -73,9 +74,13 @@ class RegistrarsController extends Controller
'email' => v::email(),
'owner' => v::optional(v::keySet(...$contactValidator)),
'billing' => v::optional(v::keySet(...$contactValidator)),
'tech' => v::optional(v::keySet(...$contactValidator)),
'abuse' => v::optional(v::keySet(...$contactValidator)),
'whoisServer' => v::domain(false),
'rdapServer' => v::domain(false),
'rdapServer' => v::oneOf(
v::domain(false),
v::url()->startsWith('http')
),
'url' => v::url(),
'abuseEmail' => v::email(),
'abusePhone' => v::optional($phoneValidator),
@ -219,6 +224,24 @@ class RegistrarsController extends Controller
]
);
$db->insert(
'registrar_contact',
[
'registrar_id' => $registrar_id,
'type' => 'tech',
'first_name' => $data['tech']['first_name'],
'last_name' => $data['tech']['last_name'],
'org' => $data['tech']['org'],
'street1' => $data['tech']['street1'],
'city' => $data['tech']['city'],
'sp' => $data['tech']['sp'],
'pc' => $data['tech']['pc'],
'cc' => strtolower($data['tech']['cc']),
'voice' => $data['tech']['voice'],
'email' => $data['tech']['email']
]
);
$db->insert(
'registrar_contact',
[
@ -332,6 +355,8 @@ class RegistrarsController extends Controller
$db = $this->container->get('db');
// Get the current URI
$uri = $request->getUri()->getPath();
$iso3166 = new ISO3166();
$countries = $iso3166->all();
if ($args) {
$args = trim(preg_replace('/\s+/', ' ', $args));
@ -359,7 +384,7 @@ class RegistrarsController extends Controller
}
}
$registrarContact = $db->selectRow('SELECT * FROM registrar_contact WHERE registrar_id = ?',
$contacts = $db->select('SELECT * FROM registrar_contact WHERE registrar_id = ?',
[ $registrar['id'] ]);
$registrarOte = $db->select('SELECT * FROM registrar_ote WHERE registrar_id = ? ORDER by command',
[ $registrar['id'] ]);
@ -392,9 +417,15 @@ class RegistrarsController extends Controller
// Check if the user is not an admin
$role = $_SESSION['auth_roles'] ?? null;
$countriesAssoc = [];
foreach ($countries as $country) {
$countriesAssoc[strtoupper($country['alpha2'])] = $country['name'];
}
return view($response,'admin/registrars/viewRegistrar.twig', [
'registrar' => $registrar,
'registrarContact' => $registrarContact,
'contacts' => $contacts,
'countries' => $countriesAssoc,
'firstHalf' => $firstHalf,
'secondHalf' => $secondHalf,
'userEmail' => $userEmail,
@ -664,6 +695,7 @@ class RegistrarsController extends Controller
$data['owner']['cc'] = strtoupper($data['owner']['cc']);
$data['billing']['cc'] = strtoupper($data['billing']['cc']);
$data['tech']['cc'] = strtoupper($data['tech']['cc']);
$data['abuse']['cc'] = strtoupper($data['abuse']['cc']);
$phoneValidator = v::regex('/^\+\d{1,3}\.\d{2,12}$/');
@ -690,9 +722,13 @@ class RegistrarsController extends Controller
'email' => v::email(),
'owner' => v::optional(v::keySet(...$contactValidator)),
'billing' => v::optional(v::keySet(...$contactValidator)),
'tech' => v::optional(v::keySet(...$contactValidator)),
'abuse' => v::optional(v::keySet(...$contactValidator)),
'whoisServer' => v::domain(false),
'rdapServer' => v::domain(false),
'rdapServer' => v::oneOf(
v::domain(false),
v::url()->startsWith('http')
),
'url' => v::url(),
'abuseEmail' => v::email(),
'abusePhone' => v::optional($phoneValidator),
@ -828,6 +864,26 @@ class RegistrarsController extends Controller
]
);
$db->update(
'registrar_contact',
[
'first_name' => $data['tech']['first_name'],
'last_name' => $data['tech']['last_name'],
'org' => $data['tech']['org'],
'street1' => $data['tech']['street1'],
'city' => $data['tech']['city'],
'sp' => $data['tech']['sp'],
'pc' => $data['tech']['pc'],
'cc' => strtolower($data['tech']['cc']),
'voice' => $data['tech']['voice'],
'email' => $data['tech']['email']
],
[
'registrar_id' => $registrar_id,
'type' => 'tech'
]
);
$db->update(
'registrar_contact',
[
@ -926,6 +982,7 @@ class RegistrarsController extends Controller
$data['owner']['cc'] = strtoupper($data['owner']['cc']);
$data['billing']['cc'] = strtoupper($data['billing']['cc']);
$data['tech']['cc'] = strtoupper($data['tech']['cc']);
$data['abuse']['cc'] = strtoupper($data['abuse']['cc']);
$phoneValidator = v::regex('/^\+\d{1,3}\.\d{2,12}$/');
@ -951,9 +1008,13 @@ class RegistrarsController extends Controller
'email' => v::email(),
'owner' => v::optional(v::keySet(...$contactValidator)),
'billing' => v::optional(v::keySet(...$contactValidator)),
'tech' => v::optional(v::keySet(...$contactValidator)),
'abuse' => v::optional(v::keySet(...$contactValidator)),
'whoisServer' => v::domain(false),
'rdapServer' => v::domain(false),
'rdapServer' => v::oneOf(
v::domain(false),
v::url()->startsWith('http')
),
'url' => v::url(),
'abuseEmail' => v::email(),
'abusePhone' => v::optional($phoneValidator),
@ -1079,6 +1140,26 @@ class RegistrarsController extends Controller
]
);
$db->update(
'registrar_contact',
[
'first_name' => $data['tech']['first_name'],
'last_name' => $data['tech']['last_name'],
'org' => $data['tech']['org'],
'street1' => $data['tech']['street1'],
'city' => $data['tech']['city'],
'sp' => $data['tech']['sp'],
'pc' => $data['tech']['pc'],
'cc' => strtolower($data['tech']['cc']),
'voice' => $data['tech']['voice'],
'email' => $data['tech']['email']
],
[
'registrar_id' => $registrar_id,
'type' => 'tech'
]
);
$db->update(
'registrar_contact',
[

View file

@ -172,6 +172,9 @@
<li class="nav-item" role="presentation">
<button class="nav-link" id="billing-tab" data-bs-toggle="tab" data-bs-target="#billing" type="button" role="tab" aria-controls="billing" aria-selected="false">{{ __('Billing') }}</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="tech-tab" data-bs-toggle="tab" data-bs-target="#tech" type="button" role="tab" aria-controls="tech" aria-selected="false">{{ __('Technical') }}</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="abuse-tab" data-bs-toggle="tab" data-bs-target="#abuse" type="button" role="tab" aria-controls="abuse" aria-selected="false">{{ __('Abuse') }}</button>
</li>
@ -302,6 +305,65 @@
</div>
</div>
<!-- Tech Tab -->
<div class="tab-pane fade" id="tech" role="tabpanel" aria-labelledby="tech-tab">
<div class="mt-3">
<div class="row">
<!-- First Column -->
<div class="col-md-6">
<div class="mb-3">
<label for="billingFirstName" class="form-label required">{{ __('First Name') }}</label>
<input type="text" class="form-control" id="billingFirstName" name="tech[first_name]" required>
</div>
<div class="mb-3">
<label for="billingLastName" class="form-label required">{{ __('Last Name') }}</label>
<input type="text" class="form-control" id="billingLastName" name="tech[last_name]" required>
</div>
<div class="mb-3">
<label for="billingOrg" class="form-label">{{ __('Organization') }}</label>
<input type="text" class="form-control" id="billingOrg" name="tech[org]">
</div>
<div class="mb-3">
<label for="billingStreet1" class="form-label">{{ __('Street Address') }}</label>
<input type="text" class="form-control" id="billingStreet1" name="tech[street1]">
</div>
<div class="mb-3">
<label for="billingCity" class="form-label required">{{ __('City') }}</label>
<input type="text" class="form-control" id="billingCity" name="tech[city]" required>
</div>
</div>
<!-- Second Column -->
<div class="col-md-6">
<div class="mb-3">
<label for="billingSp" class="form-label">{{ __('State/Province') }}</label>
<input type="text" class="form-control" id="billingSp" name="tech[sp]">
</div>
<div class="mb-3">
<label for="billingPc" class="form-label">{{ __('Postal Code') }}</label>
<input type="text" class="form-control" id="billingPc" name="tech[pc]">
</div>
<div class="mb-3">
<label for="billingCc" class="form-label required">{{ __('Country') }}</label>
<select class="form-select" id="billingCc" name="tech[cc]" required="required">
{% for country in countries %}
<option value="{{ country.alpha2|lower }}">{{ country.name }}</option>
{% endfor %}
</select>
</div>
<div class="mb-3">
<label for="billingVoice" class="form-label">{{ __('Phone') }}</label>
<input type="tel" class="form-control" id="billingVoice" name="tech[voice]">
</div>
<div class="mb-3">
<label for="billingEmail" class="form-label required">{{ __('Email') }}</label>
<input type="text" class="form-control" id="billingEmail" name="tech[email]" required autocapitalize="none">
</div>
</div>
</div>
</div>
</div>
<!-- Abuse Tab -->
<div class="tab-pane fade" id="abuse" role="tabpanel" aria-labelledby="abuse-tab">
<div class="mt-3">
@ -545,10 +607,11 @@ document.addEventListener('DOMContentLoaded', function() {
copyCheckbox.addEventListener('change', function() {
if (this.checked) {
copyDataToTab('#billing');
copyDataToTab('#tech');
copyDataToTab('#abuse');
} else {
// Clear fields when unchecked, if desired
['#billing', '#abuse'].forEach(tabId => {
['#billing', '#tech', '#abuse'].forEach(tabId => {
const fields = document.querySelectorAll(`${tabId} input:not([type='checkbox']), ${tabId} select`);
fields.forEach(field => {
field.value = '';

View file

@ -169,6 +169,9 @@
<li class="nav-item" role="presentation">
<button class="nav-link" id="billing-tab" data-bs-toggle="tab" data-bs-target="#billing" type="button" role="tab" aria-controls="billing" aria-selected="false">{{ __('Billing') }}</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="tech-tab" data-bs-toggle="tab" data-bs-target="#tech" type="button" role="tab" aria-controls="tech" aria-selected="false">{{ __('Technical') }}</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="abuse-tab" data-bs-toggle="tab" data-bs-target="#abuse" type="button" role="tab" aria-controls="abuse" aria-selected="false">{{ __('Abuse') }}</button>
</li>
@ -307,6 +310,69 @@
</div>
</div>
<!-- Tech Tab -->
<div class="tab-pane fade" id="tech" role="tabpanel" aria-labelledby="tech-tab">
<div class="mt-3">
<div class="row">
{% for contact in contacts %}
{% if contact.type == 'tech' %}
<!-- First Column -->
<div class="col-md-6">
<div class="mb-3">
<label for="billingFirstName" class="form-label required">{{ __('First Name') }}</label>
<input type="text" class="form-control" id="billingFirstName" name="tech[first_name]" value="{{ contact.first_name }}" required>
</div>
<div class="mb-3">
<label for="billingLastName" class="form-label required">{{ __('Last Name') }}</label>
<input type="text" class="form-control" id="billingLastName" name="tech[last_name]" value="{{ contact.last_name }}"required>
</div>
<div class="mb-3">
<label for="billingOrg" class="form-label">{{ __('Organization') }}</label>
<input type="text" class="form-control" id="billingOrg" name="tech[org]" value="{{ contact.org }}">
</div>
<div class="mb-3">
<label for="billingStreet1" class="form-label">{{ __('Street Address') }}</label>
<input type="text" class="form-control" id="billingStreet1" name="tech[street1]" value="{{ contact.street1 }}">
</div>
<div class="mb-3">
<label for="billingCity" class="form-label required">{{ __('City') }}</label>
<input type="text" class="form-control" id="billingCity" name="tech[city]" value="{{ contact.city }}" required>
</div>
</div>
<!-- Second Column -->
<div class="col-md-6">
<div class="mb-3">
<label for="billingSp" class="form-label">{{ __('State/Province') }}</label>
<input type="text" class="form-control" id="billingSp" name="tech[sp]" value="{{ contact.sp }}">
</div>
<div class="mb-3">
<label for="billingPc" class="form-label">{{ __('Postal Code') }}</label>
<input type="text" class="form-control" id="billingPc" name="tech[pc]" value="{{ contact.pc }}">
</div>
<div class="mb-3">
<label for="billingCc" class="form-label required">{{ __('Country') }}</label>
<select class="form-select" id="billingCc" name="tech[cc]" required="required">
{% for country in countries %}
<option value="{{ country.alpha2 }}" {% if country.alpha2|lower == contact.cc %}selected{% endif %}>{{ country.name }}</option>
{% endfor %}
</select>
</div>
<div class="mb-3">
<label for="billingVoice" class="form-label">{{ __('Phone') }}</label>
<input type="tel" class="form-control" id="billingVoice" name="tech[voice]" value="{{ contact.voice }}">
</div>
<div class="mb-3">
<label for="billingEmail" class="form-label required">{{ __('Email') }}</label>
<input type="text" class="form-control" id="billingEmail" name="tech[email]" required autocapitalize="none" value="{{ contact.email }}">
</div>
</div>
{% endif %}
{% endfor %}
</div>
</div>
</div>
<!-- Abuse Tab -->
<div class="tab-pane fade" id="abuse" role="tabpanel" aria-labelledby="abuse-tab">
<div class="mt-3">
@ -600,10 +666,11 @@ document.addEventListener('DOMContentLoaded', function() {
copyCheckbox.addEventListener('change', function() {
if (this.checked) {
copyDataToTab('#billing');
copyDataToTab('#tech');
copyDataToTab('#abuse');
} else {
// Clear fields when unchecked, if desired
['#billing', '#abuse'].forEach(tabId => {
['#billing', '#tech', '#abuse'].forEach(tabId => {
const fields = document.querySelectorAll(`${tabId} input:not([type='checkbox']), ${tabId} select`);
fields.forEach(field => {
field.value = '';

View file

@ -151,6 +151,9 @@
<li class="nav-item" role="presentation">
<button class="nav-link" id="billing-tab" data-bs-toggle="tab" data-bs-target="#billing" type="button" role="tab" aria-controls="billing" aria-selected="false">{{ __('Billing') }}</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="tech-tab" data-bs-toggle="tab" data-bs-target="#tech" type="button" role="tab" aria-controls="tech" aria-selected="false">{{ __('Technical') }}</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="abuse-tab" data-bs-toggle="tab" data-bs-target="#abuse" type="button" role="tab" aria-controls="abuse" aria-selected="false">{{ __('Abuse') }}</button>
</li>
@ -289,6 +292,69 @@
</div>
</div>
<!-- Tech Tab -->
<div class="tab-pane fade" id="tech" role="tabpanel" aria-labelledby="tech-tab">
<div class="mt-3">
<div class="row">
{% for contact in contacts %}
{% if contact.type == 'tech' %}
<!-- First Column -->
<div class="col-md-6">
<div class="mb-3">
<label for="billingFirstName" class="form-label required">{{ __('First Name') }}</label>
<input type="text" class="form-control" id="billingFirstName" name="tech[first_name]" value="{{ contact.first_name }}" required>
</div>
<div class="mb-3">
<label for="billingLastName" class="form-label required">{{ __('Last Name') }}</label>
<input type="text" class="form-control" id="billingLastName" name="tech[last_name]" value="{{ contact.last_name }}"required>
</div>
<div class="mb-3">
<label for="billingOrg" class="form-label">{{ __('Organization') }}</label>
<input type="text" class="form-control" id="billingOrg" name="tech[org]" value="{{ contact.org }}">
</div>
<div class="mb-3">
<label for="billingStreet1" class="form-label">{{ __('Street Address') }}</label>
<input type="text" class="form-control" id="billingStreet1" name="tech[street1]" value="{{ contact.street1 }}">
</div>
<div class="mb-3">
<label for="billingCity" class="form-label required">{{ __('City') }}</label>
<input type="text" class="form-control" id="billingCity" name="tech[city]" value="{{ contact.city }}" required>
</div>
</div>
<!-- Second Column -->
<div class="col-md-6">
<div class="mb-3">
<label for="billingSp" class="form-label">{{ __('State/Province') }}</label>
<input type="text" class="form-control" id="billingSp" name="tech[sp]" value="{{ contact.sp }}">
</div>
<div class="mb-3">
<label for="billingPc" class="form-label">{{ __('Postal Code') }}</label>
<input type="text" class="form-control" id="billingPc" name="tech[pc]" value="{{ contact.pc }}">
</div>
<div class="mb-3">
<label for="billingCc" class="form-label required">{{ __('Country') }}</label>
<select class="form-select" id="billingCc" name="tech[cc]" required="required">
{% for country in countries %}
<option value="{{ country.alpha2 }}" {% if country.alpha2|lower == contact.cc %}selected{% endif %}>{{ country.name }}</option>
{% endfor %}
</select>
</div>
<div class="mb-3">
<label for="billingVoice" class="form-label">{{ __('Phone') }}</label>
<input type="tel" class="form-control" id="billingVoice" name="tech[voice]" value="{{ contact.voice }}">
</div>
<div class="mb-3">
<label for="billingEmail" class="form-label required">{{ __('Email') }}</label>
<input type="text" class="form-control" id="billingEmail" name="tech[email]" required autocapitalize="none" value="{{ contact.email }}">
</div>
</div>
{% endif %}
{% endfor %}
</div>
</div>
</div>
<!-- Abuse Tab -->
<div class="tab-pane fade" id="abuse" role="tabpanel" aria-labelledby="abuse-tab">
<div class="mt-3">
@ -560,10 +626,11 @@ document.addEventListener('DOMContentLoaded', function() {
copyCheckbox.addEventListener('change', function() {
if (this.checked) {
copyDataToTab('#billing');
copyDataToTab('#tech');
copyDataToTab('#abuse');
} else {
// Clear fields when unchecked, if desired
['#billing', '#abuse'].forEach(tabId => {
['#billing', '#tech', '#abuse'].forEach(tabId => {
const fields = document.querySelectorAll(`${tabId} input:not([type='checkbox']), ${tabId} select`);
fields.forEach(field => {
field.value = '';

View file

@ -121,6 +121,264 @@
</div>
</div>
</div>
<div class="card mb-3">
<div class="card-body">
<h5 class="card-title">{{ __('Registrar Contacts') }}</h5>
<ul class="nav nav-tabs nav-fill" id="contactTabs" role="tablist">
<!-- Tab Headers -->
<li class="nav-item" role="presentation">
<button class="nav-link active" id="owner-tab" data-bs-toggle="tab" data-bs-target="#owner" type="button" role="tab" aria-controls="owner" aria-selected="true">{{ __('Owner') }}</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="billing-tab" data-bs-toggle="tab" data-bs-target="#billing" type="button" role="tab" aria-controls="billing" aria-selected="false">{{ __('Billing') }}</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="tech-tab" data-bs-toggle="tab" data-bs-target="#tech" type="button" role="tab" aria-controls="tech" aria-selected="false">{{ __('Technical') }}</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="abuse-tab" data-bs-toggle="tab" data-bs-target="#abuse" type="button" role="tab" aria-controls="abuse" aria-selected="false">{{ __('Abuse') }}</button>
</li>
</ul>
<div class="tab-content" id="contactTabsContent">
<!-- Owner Tab -->
<div class="tab-pane fade show active" id="owner" role="tabpanel" aria-labelledby="owner-tab">
<div class="mt-3">
<div class="row">
{% for contact in contacts %}
{% if contact.type == 'owner' %}
<!-- First Column -->
<div class="col-md-6">
<div class="mb-3">
<label for="ownerFirstName" class="form-label">{{ __('First Name') }}</label>
<div class="form-control-plaintext">{{ contact.first_name }}</div>
</div>
<div class="mb-3">
<label for="ownerLastName" class="form-label">{{ __('Last Name') }}</label>
<div class="form-control-plaintext">{{ contact.last_name }}</div>
</div>
<div class="mb-3">
<label for="ownerOrg" class="form-label">{{ __('Organization') }}</label>
<div class="form-control-plaintext">{{ contact.org }}</div>
</div>
<div class="mb-3">
<label for="ownerStreet1" class="form-label">{{ __('Street Address') }}</label>
<div class="form-control-plaintext">{{ contact.street1 }}</div>
</div>
<div class="mb-3">
<label for="ownerCity" class="form-label">{{ __('City') }}</label>
<div class="form-control-plaintext">{{ contact.city }}</div>
</div>
</div>
<!-- Second Column -->
<div class="col-md-6">
<div class="mb-3">
<label for="ownerSp" class="form-label">{{ __('State/Province') }}</label>
<div class="form-control-plaintext">{{ contact.sp }}</div>
</div>
<div class="mb-3">
<label for="ownerPc" class="form-label">{{ __('Postal Code') }}</label>
<div class="form-control-plaintext">{{ contact.pc }}</div>
</div>
<div class="mb-3">
<label for="ownerCc" class="form-label">{{ __('Country') }}</label>
<div class="form-control-plaintext">{{ countries[contact.cc|upper] }}</div>
</div>
<div class="mb-3">
<label for="ownerVoice" class="form-label">{{ __('Phone') }}</label>
<div class="form-control-plaintext">{{ contact.voice }}</div>
</div>
<div class="mb-3">
<label for="ownerEmail" class="form-label">{{ __('Email') }}</label>
<div class="form-control-plaintext">{{ contact.email }}</div>
</div>
</div>
{% endif %}
{% endfor %}
</div>
</div>
</div>
<!-- Billing Tab -->
<div class="tab-pane fade" id="billing" role="tabpanel" aria-labelledby="billing-tab">
<div class="mt-3">
<div class="row">
{% for contact in contacts %}
{% if contact.type == 'billing' %}
<!-- First Column -->
<div class="col-md-6">
<div class="mb-3">
<label for="billingFirstName" class="form-label">{{ __('First Name') }}</label>
<div class="form-control-plaintext">{{ contact.first_name }}</div>
</div>
<div class="mb-3">
<label for="billingLastName" class="form-label">{{ __('Last Name') }}</label>
<div class="form-control-plaintext">{{ contact.last_name }}</div>
</div>
<div class="mb-3">
<label for="billingOrg" class="form-label">{{ __('Organization') }}</label>
<div class="form-control-plaintext">{{ contact.org }}</div>
</div>
<div class="mb-3">
<label for="billingStreet1" class="form-label">{{ __('Street Address') }}</label>
<div class="form-control-plaintext">{{ contact.street1 }}</div>
</div>
<div class="mb-3">
<label for="billingCity" class="form-label">{{ __('City') }}</label>
<div class="form-control-plaintext">{{ contact.city }}</div>
</div>
</div>
<!-- Second Column -->
<div class="col-md-6">
<div class="mb-3">
<label for="billingSp" class="form-label">{{ __('State/Province') }}</label>
<div class="form-control-plaintext">{{ contact.sp }}</div>
</div>
<div class="mb-3">
<label for="billingPc" class="form-label">{{ __('Postal Code') }}</label>
<div class="form-control-plaintext">{{ contact.pc }}</div>
</div>
<div class="mb-3">
<label for="billingCc" class="form-label">{{ __('Country') }}</label>
<div class="form-control-plaintext">{{ countries[contact.cc|upper] }}</div>
</div>
<div class="mb-3">
<label for="billingVoice" class="form-label">{{ __('Phone') }}</label>
<div class="form-control-plaintext">{{ contact.voice }}</div>
</div>
<div class="mb-3">
<label for="billingEmail" class="form-label">{{ __('Email') }}</label>
<div class="form-control-plaintext">{{ contact.email }}</div>
</div>
</div>
{% endif %}
{% endfor %}
</div>
</div>
</div>
<!-- Tech Tab -->
<div class="tab-pane fade" id="tech" role="tabpanel" aria-labelledby="tech-tab">
<div class="mt-3">
<div class="row">
{% for contact in contacts %}
{% if contact.type == 'tech' %}
<!-- First Column -->
<div class="col-md-6">
<div class="mb-3">
<label for="techFirstName" class="form-label">{{ __('First Name') }}</label>
<div class="form-control-plaintext">{{ contact.first_name }}</div>
</div>
<div class="mb-3">
<label for="techLastName" class="form-label">{{ __('Last Name') }}</label>
<div class="form-control-plaintext">{{ contact.last_name }}</div>
</div>
<div class="mb-3">
<label for="techOrg" class="form-label">{{ __('Organization') }}</label>
<div class="form-control-plaintext">{{ contact.org }}</div>
</div>
<div class="mb-3">
<label for="techStreet1" class="form-label">{{ __('Street Address') }}</label>
<div class="form-control-plaintext">{{ contact.street1 }}</div>
</div>
<div class="mb-3">
<label for="techCity" class="form-label">{{ __('City') }}</label>
<div class="form-control-plaintext">{{ contact.city }}</div>
</div>
</div>
<!-- Second Column -->
<div class="col-md-6">
<div class="mb-3">
<label for="techSp" class="form-label">{{ __('State/Province') }}</label>
<div class="form-control-plaintext">{{ contact.sp }}</div>
</div>
<div class="mb-3">
<label for="techPc" class="form-label">{{ __('Postal Code') }}</label>
<div class="form-control-plaintext">{{ contact.pc }}</div>
</div>
<div class="mb-3">
<label for="techCc" class="form-label">{{ __('Country') }}</label>
<div class="form-control-plaintext">{{ countries[contact.cc|upper] }}</div>
</div>
<div class="mb-3">
<label for="techVoice" class="form-label">{{ __('Phone') }}</label>
<div class="form-control-plaintext">{{ contact.voice }}</div>
</div>
<div class="mb-3">
<label for="techEmail" class="form-label">{{ __('Email') }}</label>
<div class="form-control-plaintext">{{ contact.email }}</div>
</div>
</div>
{% endif %}
{% endfor %}
</div>
</div>
</div>
<!-- Abuse Tab -->
<div class="tab-pane fade" id="abuse" role="tabpanel" aria-labelledby="abuse-tab">
<div class="mt-3">
<div class="row">
{% for contact in contacts %}
{% if contact.type == 'abuse' %}
<!-- First Column -->
<div class="col-md-6">
<div class="mb-3">
<label for="abuseFirstName" class="form-label">{{ __('First Name') }}</label>
<div class="form-control-plaintext">{{ contact.first_name }}</div>
</div>
<div class="mb-3">
<label for="abuseLastName" class="form-label">{{ __('Last Name') }}</label>
<div class="form-control-plaintext">{{ contact.last_name }}</div>
</div>
<div class="mb-3">
<label for="abuseOrg" class="form-label">{{ __('Organization') }}</label>
<div class="form-control-plaintext">{{ contact.org }}</div>
</div>
<div class="mb-3">
<label for="abuseStreet1" class="form-label">{{ __('Street Address') }}</label>
<div class="form-control-plaintext">{{ contact.street1 }}</div>
</div>
<div class="mb-3">
<label for="abuseCity" class="form-label">{{ __('City') }}</label>
<div class="form-control-plaintext">{{ contact.city }}</div>
</div>
</div>
<!-- Second Column -->
<div class="col-md-6">
<div class="mb-3">
<label for="abuseSp" class="form-label">{{ __('State/Province') }}</label>
<div class="form-control-plaintext">{{ contact.sp }}</div>
</div>
<div class="mb-3">
<label for="abusePc" class="form-label">{{ __('Postal Code') }}</label>
<div class="form-control-plaintext">{{ contact.pc }}</div>
</div>
<div class="mb-3">
<label for="abuseCc" class="form-label">{{ __('Country') }}</label>
<div class="form-control-plaintext">{{ countries[contact.cc|upper] }}</div>
</div>
<div class="mb-3">
<label for="abuseVoice" class="form-label">{{ __('Phone') }}</label>
<div class="form-control-plaintext">{{ contact.voice }}</div>
</div>
<div class="mb-3">
<label for="abuseEmail" class="form-label">{{ __('Email') }}</label>
<div class="form-control-plaintext">{{ contact.email }}</div>
</div>
</div>
{% endif %}
{% endfor %}
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<div class="card h-100">