Add mocks for the various setting pages.

This commit is contained in:
Eli Ribble 2025-12-12 21:52:55 +00:00
parent 637decea11
commit 5f86274b16
No known key found for this signature in database
9 changed files with 1205 additions and 18 deletions

18
html.go
View file

@ -62,6 +62,12 @@ var (
serviceRequestQuick = newBuiltTemplate("service-request-quick", "base")
serviceRequestQuickConfirmation = newBuiltTemplate("service-request-quick-confirmation", "base")
serviceRequestUpdates = newBuiltTemplate("service-request-updates", "base")
settingRoot = newBuiltTemplate("setting-mock", "base")
settingIntegration = newBuiltTemplate("setting-integration", "base")
settingPesticide = newBuiltTemplate("setting-pesticide", "base")
settingPesticideAdd = newBuiltTemplate("setting-pesticide-add", "base")
settingUsers = newBuiltTemplate("setting-user", "base")
settingUsersAdd = newBuiltTemplate("setting-user-add", "base")
signin = newBuiltTemplate("signin", "base")
signup = newBuiltTemplate("signup", "base")
)
@ -112,6 +118,12 @@ type ContentMockURLs struct {
ReportSchedule string
ReportUpdate string
Root string
Setting string
SettingIntegration string
SettingPesticide string
SettingPesticideAdd string
SettingUser string
SettingUserAdd string
}
type ContentMock struct {
DistrictName string
@ -367,6 +379,12 @@ func htmlMock(t string, w http.ResponseWriter, code string) {
ReportSchedule: fmt.Sprintf("/mock/report/%s/schedule", code),
ReportUpdate: fmt.Sprintf("/mock/report/%s/update", code),
Root: "/mock",
Setting: "/mock/setting",
SettingIntegration: "/mock/setting/integration",
SettingPesticide: "/mock/setting/pesticide",
SettingPesticideAdd: "/mock/setting/pesticide/add",
SettingUser: "/mock/setting/user",
SettingUserAdd: "/mock/setting/user/add",
},
}
template, ok := templatesByFilename[t]

View file

@ -117,6 +117,12 @@ func main() {
r.Get("/mock/service-request-quick", renderMock("service-request-quick"))
r.Get("/mock/service-request-quick-confirmation", renderMock("service-request-quick-confirmation"))
r.Get("/mock/service-request-updates", renderMock("service-request-updates"))
r.Get("/mock/setting", renderMock("setting-mock"))
r.Get("/mock/setting/integration", renderMock("setting-integration"))
r.Get("/mock/setting/pesticide", renderMock("setting-pesticide"))
r.Get("/mock/setting/pesticide/add", renderMock("setting-pesticide-add"))
r.Get("/mock/setting/user", renderMock("setting-user"))
r.Get("/mock/setting/user/add", renderMock("setting-user-add"))
r.Get("/oauth/refresh", getOAuthRefresh)

View file

@ -45,6 +45,11 @@
<td>Service Request</td>
<td>A page for members of the public to make a direct service request</td>
</tr>
<tr>
<td><a href="/mock/setting">/mock/setting</a></td>
<td>Settings</td>
<td>A page for management to control the behavior of Nidus</td>
</tr>
</tbody>
</table>
</div>

View file

@ -0,0 +1,257 @@
{{template "base.html" .}}
{{define "title"}}Dash{{end}}
{{define "extraheader"}}
<style>
.integration-card {
border-left: 5px solid #0d6efd;
transition: all 0.2s;
}
.integration-card:hover {
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
}
.integration-card.fieldseeker {
border-left-color: #0d6efd;
}
.integration-card.vectorsurv {
border-left-color: #198754;
}
.integration-card.veemac {
border-left-color: #dc3545;
}
.status-active {
color: #198754;
}
.status-inactive {
color: #dc3545;
}
.token-display {
font-family: monospace;
background-color: #f8f9fa;
padding: 0.25rem 0.5rem;
border-radius: 0.25rem;
border: 1px solid #dee2e6;
}
</style>
{{end}}
{{define "content"}}
<div class="container py-4">
<!-- Header -->
<div class="mb-4">
<h1>Integrations</h1>
<div class="alert alert-warning">
<i class="bi bi-exclamation-triangle me-2"></i>
<strong>Important:</strong> This page allows you to configure integration with third-party services. The credentials and tokens stored here provide access to external systems and should be protected. Only authorized personnel should modify these settings.
</div>
</div>
<!-- FieldSeeker GIS Integration -->
<div class="card mb-4 integration-card fieldseeker">
<div class="card-header d-flex justify-content-between align-items-center">
<div>
<h2 class="h5 mb-0">Frontier Precision's FieldSeeker GIS</h2>
</div>
<img src="https://via.placeholder.com/100x40?text=FieldSeeker" alt="FieldSeeker Logo" height="40">
</div>
<div class="card-body">
<div class="table-responsive mb-3">
<table class="table table-borderless">
<tbody>
<tr>
<td width="30%"><strong>OAuth Token Status</strong></td>
<td>
<span class="status-active">
<i class="bi bi-check-circle-fill me-1"></i> Active
</span>
</td>
</tr>
<tr>
<td><strong>Token Expiration</strong></td>
<td>26 days remaining (Expires on Dec 31, 2025)</td>
</tr>
<tr>
<td><strong>Integration Method</strong></td>
<td>Web Hooks</td>
</tr>
<tr>
<td><strong>Permission Level</strong></td>
<td>Read & Write</td>
</tr>
</tbody>
</table>
</div>
<div class="d-flex gap-2">
<button class="btn btn-primary">
<i class="bi bi-arrow-repeat me-2"></i>Refresh OAuth Token
</button>
<button class="btn btn-outline-danger">
<i class="bi bi-trash me-2"></i>Delete Token
</button>
</div>
</div>
</div>
<!-- VectorSurv Integration -->
<div class="card mb-4 integration-card vectorsurv">
<div class="card-header d-flex justify-content-between align-items-center">
<div>
<h2 class="h5 mb-0">VectorSurv</h2>
</div>
<img src="https://via.placeholder.com/100x40?text=VectorSurv" alt="VectorSurv Logo" height="40">
</div>
<div class="card-body">
<div class="table-responsive mb-3">
<table class="table table-borderless">
<tbody>
<tr>
<td width="30%"><strong>API Token</strong></td>
<td>
<span class="token-display">vs_9f72b5e3******************************c11d</span>
</td>
</tr>
<tr>
<td><strong>Last Synchronization</strong></td>
<td>December 5, 2025 at 08:34 AM (2 days ago)</td>
</tr>
<tr>
<td><strong>Synchronization Status</strong></td>
<td>
<span class="status-active">
<i class="bi bi-check-circle-fill me-1"></i> Active (Scheduled daily at 2:00 AM)
</span>
</td>
</tr>
</tbody>
</table>
</div>
<div class="d-flex gap-2">
<button class="btn btn-success" data-bs-toggle="modal" data-bs-target="#vectorsurvModal">
<i class="bi bi-pencil-square me-2"></i>Edit Token
</button>
<button class="btn btn-outline-danger">
<i class="bi bi-trash me-2"></i>Remove Integration
</button>
</div>
</div>
</div>
<!-- VeeMac Integration -->
<div class="card mb-4 integration-card veemac">
<div class="card-header d-flex justify-content-between align-items-center">
<div>
<h2 class="h5 mb-0">VeeMac</h2>
</div>
<img src="https://via.placeholder.com/100x40?text=VeeMac" alt="VeeMac Logo" height="40">
</div>
<div class="card-body">
<div class="table-responsive mb-3">
<table class="table table-borderless">
<tbody>
<tr>
<td width="30%"><strong>Username</strong></td>
<td>mosquito_district21</td>
</tr>
<tr>
<td><strong>Password</strong></td>
<td>••••••••••••</td>
</tr>
<tr>
<td><strong>Last Synchronization</strong></td>
<td>December 6, 2025 at 11:15 PM (Yesterday)</td>
</tr>
<tr>
<td><strong>Synchronization Status</strong></td>
<td>
<span class="status-inactive">
<i class="bi bi-x-circle-fill me-1"></i> Inactive (Manual sync only)
</span>
</td>
</tr>
</tbody>
</table>
</div>
<div class="d-flex gap-2">
<button class="btn btn-success" data-bs-toggle="modal" data-bs-target="#veemacModal">
<i class="bi bi-pencil-square me-2"></i>Edit Credentials
</button>
<button class="btn btn-outline-danger">
<i class="bi bi-trash me-2"></i>Remove Integration
</button>
</div>
</div>
</div>
</div>
<!-- VectorSurv Edit Token Modal -->
<div class="modal fade" id="vectorsurvModal" tabindex="-1" aria-labelledby="vectorsurvModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="vectorsurvModalLabel">Edit VectorSurv API Token</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form>
<div class="mb-3">
<label for="vectorsurvToken" class="form-label">API Token</label>
<input type="text" class="form-control" id="vectorsurvToken" value="vs_9f72b5e3c8a1d492f6b7e54321098c11d">
<div class="form-text">You can find this token in your VectorSurv account settings.</div>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="vectorsurvSyncCheck" checked>
<label class="form-check-label" for="vectorsurvSyncCheck">Enable automatic synchronization</label>
</div>
<div class="mb-3">
<label for="vectorsurvSyncTime" class="form-label">Sync Time</label>
<input type="time" class="form-control" id="vectorsurvSyncTime" value="02:00">
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-success">Save Changes</button>
</div>
</div>
</div>
</div>
<!-- VeeMac Edit Credentials Modal -->
<div class="modal fade" id="veemacModal" tabindex="-1" aria-labelledby="veemacModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="veemacModalLabel">Edit VeeMac Credentials</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form>
<div class="mb-3">
<label for="veemacUsername" class="form-label">Username</label>
<input type="text" class="form-control" id="veemacUsername" value="mosquito_district21">
</div>
<div class="mb-3">
<label for="veemacPassword" class="form-label">Password</label>
<input type="password" class="form-control" id="veemacPassword" value="password123">
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="veemacSyncCheck">
<label class="form-check-label" for="veemacSyncCheck">Enable automatic synchronization</label>
</div>
<div class="mb-3">
<label for="veemacSyncFrequency" class="form-label">Sync Frequency</label>
<select class="form-select" id="veemacSyncFrequency" disabled>
<option value="daily">Daily</option>
<option value="weekly">Weekly</option>
<option value="hourly">Hourly</option>
</select>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-danger">Save Changes</button>
</div>
</div>
</div>
</div>
{{end}}

192
templates/setting-mock.html Normal file
View file

@ -0,0 +1,192 @@
{{template "base.html" .}}
{{define "title"}}Dash{{end}}
{{define "extraheader"}}
<style>
.settings-card {
transition: transform 0.2s, box-shadow 0.2s;
height: 100%;
}
.settings-card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
}
.settings-icon {
font-size: 2.5rem;
width: 80px;
height: 80px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
margin-bottom: 1.5rem;
}
.icon-users {
color: #6f42c1;
background-color: rgba(111, 66, 193, 0.1);
}
.icon-pesticides {
color: #198754;
background-color: rgba(25, 135, 84, 0.1);
}
.icon-integrations {
color: #0d6efd;
background-color: rgba(13, 110, 253, 0.1);
}
.icon-notifications {
color: #fd7e14;
background-color: rgba(253, 126, 20, 0.1);
}
.icon-general {
color: #6c757d;
background-color: rgba(108, 117, 125, 0.1);
}
.icon-equipment {
color: #dc3545;
background-color: rgba(220, 53, 69, 0.1);
}
.last-updated {
font-size: 0.8rem;
color: #6c757d;
}
</style>
{{end}}
{{define "content"}}
<div class="container py-5">
<div class="row mb-4">
<div class="col">
<h1 class="display-5 mb-3">Settings</h1>
<p class="text-muted lead">Configure your organization's preferences and integrations</p>
</div>
</div>
<div class="row g-4">
<!-- User Management Card -->
<div class="col-12 col-md-6 col-lg-4">
<div class="card settings-card border-0 shadow-sm">
<div class="card-body p-4">
<div class="settings-icon icon-users">
<i class="bi bi-people-fill"></i>
</div>
<h2 class="h4 mb-2">User Management</h2>
<p class="text-muted mb-4">Manage staff accounts, roles, and permissions for your organization.</p>
<div class="d-flex justify-content-between align-items-center">
<a href="{{ .URLs.SettingUser }}" class="btn btn-outline-primary">
Manage Users
<i class="bi bi-arrow-right ms-1"></i>
</a>
<span class="last-updated">23 users</span>
</div>
</div>
</div>
</div>
<!-- Pesticide Products Card -->
<div class="col-12 col-md-6 col-lg-4">
<div class="card settings-card border-0 shadow-sm">
<div class="card-body p-4">
<div class="settings-icon icon-pesticides">
<i class="bi bi-droplet-fill"></i>
</div>
<h2 class="h4 mb-2">Pesticide Products</h2>
<p class="text-muted mb-4">Configure products, application rates, and field recommendations.</p>
<div class="d-flex justify-content-between align-items-center">
<a href="{{ .URLs.SettingPesticide }}" class="btn btn-outline-success">
Manage Products
<i class="bi bi-arrow-right ms-1"></i>
</a>
<span class="last-updated">12 active products</span>
</div>
</div>
</div>
</div>
<!-- Integrations Card -->
<div class="col-12 col-md-6 col-lg-4">
<div class="card settings-card border-0 shadow-sm">
<div class="card-body p-4">
<div class="settings-icon icon-integrations">
<i class="bi bi-gear-wide-connected"></i>
</div>
<h2 class="h4 mb-2">Integrations</h2>
<p class="text-muted mb-4">Configure connections with FieldSeeker, VectorSurv, and other services.</p>
<div class="d-flex justify-content-between align-items-center">
<a href="{{ .URLs.SettingIntegration }}" class="btn btn-outline-primary">
Manage Integrations
<i class="bi bi-arrow-right ms-1"></i>
</a>
<span class="last-updated">3 active connections</span>
</div>
</div>
</div>
</div>
<!-- Equipment Card -->
<div class="col-12 col-md-6 col-lg-4">
<div class="card settings-card border-0 shadow-sm">
<div class="card-body p-4">
<div class="settings-icon icon-equipment">
<i class="bi bi-tools"></i>
</div>
<h2 class="h4 mb-2">Equipment</h2>
<p class="text-muted mb-4">Manage your field equipment inventory, calibration, and maintenance.</p>
<div class="d-flex justify-content-between align-items-center">
<a href="equipment.html" class="btn btn-outline-danger">
Manage Equipment
<i class="bi bi-arrow-right ms-1"></i>
</a>
<span class="last-updated">Updated 5 days ago</span>
</div>
</div>
</div>
</div>
<!-- Notifications Card -->
<div class="col-12 col-md-6 col-lg-4">
<div class="card settings-card border-0 shadow-sm">
<div class="card-body p-4">
<div class="settings-icon icon-notifications">
<i class="bi bi-bell-fill"></i>
</div>
<h2 class="h4 mb-2">Notifications</h2>
<p class="text-muted mb-4">Configure email alerts, SMS notifications, and reporting preferences.</p>
<div class="d-flex justify-content-between align-items-center">
<a href="notifications.html" class="btn btn-outline-warning">
Manage Notifications
<i class="bi bi-arrow-right ms-1"></i>
</a>
<span class="last-updated">5 active alerts</span>
</div>
</div>
</div>
</div>
<!-- General Settings Card -->
<div class="col-12 col-md-6 col-lg-4">
<div class="card settings-card border-0 shadow-sm">
<div class="card-body p-4">
<div class="settings-icon icon-general">
<i class="bi bi-sliders"></i>
</div>
<h2 class="h4 mb-2">General Settings</h2>
<p class="text-muted mb-4">Configure organization details, branding, and system preferences.</p>
<div class="d-flex justify-content-between align-items-center">
<a href="general-settings.html" class="btn btn-outline-secondary">
Manage Settings
<i class="bi bi-arrow-right ms-1"></i>
</a>
<span class="last-updated">Updated yesterday</span>
</div>
</div>
</div>
</div>
</div>
<div class="mt-5 text-center text-muted">
<p class="small">
<i class="bi bi-shield-lock me-1"></i>
All changes made in settings are logged for audit purposes
</p>
</div>
</div>
{{end}}

View file

@ -0,0 +1,231 @@
{{template "base.html" .}}
{{define "title"}}Dash{{end}}
{{define "extraheader"}}
<style>
.section-heading {
font-size: 1.2rem;
font-weight: 600;
margin-bottom: 1rem;
padding-bottom: 0.5rem;
border-bottom: 1px solid #dee2e6;
}
.info-label {
font-weight: 600;
color: #495057;
}
.target-icon {
display: inline-block;
width: 30px;
height: 30px;
text-align: center;
line-height: 30px;
border-radius: 50%;
font-size: 14px;
font-weight: bold;
margin-right: 4px;
color: white;
}
.target-active {
background-color: #0d6efd;
}
.target-inactive {
background-color: #dee2e6;
color: #6c757d;
}
.tag {
display: inline-flex;
align-items: center;
padding: 0.4rem 0.8rem;
margin: 0.2rem;
border-radius: 30px;
background-color: #f8f9fa;
border: 1px solid #dee2e6;
font-size: 0.9rem;
}
.tag i {
margin-right: 0.5rem;
}
.tag-enabled {
background-color: #d1e7dd;
color: #0f5132;
border-color: #a3cfbb;
}
.tag-ppe {
background-color: #e2e3e5;
color: #41464b;
border-color: #d3d6d8;
}
.tag-equipment {
background-color: #cff4fc;
color: #055160;
border-color: #9eeaf9;
}
.tag-suitability {
background-color: #fff3cd;
color: #664d03;
border-color: #ffecb5;
}
.tag-optional {
background-color: #f8f9fa;
color: #6c757d;
border-color: #dee2e6;
}
</style>
{{end}}
{{define "content"}}
<div class="container py-4">
<!-- Breadcrumb -->
<nav aria-label="breadcrumb" class="mb-4">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="#">Settings</a></li>
<li class="breadcrumb-item"><a href="pesticide-config.html">Pesticide</a></li>
<li class="breadcrumb-item active" aria-current="page">VectoMax FG</li>
</ol>
</nav>
<!-- Main Content -->
<div class="card shadow-sm mb-4">
<div class="card-body">
<!-- Product Header -->
<div class="d-flex justify-content-between align-items-start mb-4">
<div>
<h1 class="mb-2">VectoMax FG</h1>
<p class="text-muted mb-0">Biological larvicide granules combining Bacillus thuringiensis subspecies israelensis and Bacillus sphaericus for extended residual control of mosquito larvae.</p>
</div>
<span class="tag tag-enabled">
<i class="bi bi-check-circle-fill"></i> Enabled
</span>
</div>
<!-- General Information -->
<div class="mb-4">
<h2 class="section-heading">General Information</h2>
<div class="row g-3">
<div class="col-md-6 col-lg-4">
<div class="info-label">Formulation</div>
<div>Granule</div>
</div>
<div class="col-md-6 col-lg-4">
<div class="info-label">EPA Registration Number</div>
<div>73049-429</div>
</div>
<div class="col-md-6 col-lg-4">
<div class="info-label">Active Ingredients</div>
<div>Bacillus thuringiensis subspecies israelensis (2.7%)<br>
Bacillus sphaericus (4.5%)</div>
</div>
<div class="col-md-6 col-lg-4">
<div class="info-label">Biological Targeting</div>
<div class="mt-1">
<span class="target-icon target-active" title="Instar Stage 1">I1</span>
<span class="target-icon target-active" title="Instar Stage 2">I2</span>
<span class="target-icon target-active" title="Instar Stage 3">I3</span>
<span class="target-icon target-active" title="Instar Stage 4">I4</span>
<span class="target-icon target-inactive" title="Pupae">P</span>
</div>
</div>
<div class="col-md-6 col-lg-4">
<div class="info-label">Application Rates</div>
<div>Low: 5 lbs/acre<br>
High: 20 lbs/acre</div>
</div>
<div class="col-md-6 col-lg-4">
<div class="info-label">Residual</div>
<div>Up to 30 days (environmental conditions dependent)</div>
</div>
</div>
</div>
<!-- Usage Notes -->
<div class="alert alert-info mb-4">
<div class="d-flex">
<div class="me-3">
<i class="bi bi-info-circle-fill fs-4"></i>
</div>
<div>
<h5 class="alert-heading">Key Usage Notes</h5>
<p class="mb-0">Apply evenly across water surface. Use higher rate when L4 present or when organic load is high. Avoid application in ponds with fish unless approved by a supervisor.</p>
</div>
</div>
</div>
<!-- PPE Requirements -->
<div class="mb-4">
<h2 class="section-heading">PPE Requirements</h2>
<div>
<span class="tag tag-ppe">
<i class="bi bi-hand-thumbs-up"></i> Gloves
</span>
<span class="tag tag-ppe">
<i class="bi bi-eyeglasses"></i> Eye Protection
</span>
<span class="tag tag-optional">
<i class="bi bi-mask"></i> Respirator (Optional)
</span>
</div>
</div>
<!-- Equipment Supported -->
<div class="mb-4">
<h2 class="section-heading">Equipment Supported</h2>
<div>
<span class="tag tag-equipment">
<i class="bi bi-backpack"></i> Backpack Spreader
</span>
<span class="tag tag-equipment">
<i class="bi bi-hand-index-thumb"></i> Hand Spreader
</span>
<span class="tag tag-equipment">
<i class="bi bi-truck"></i> Truck Granule Unit
</span>
</div>
</div>
<!-- Suitability -->
<div class="mb-4">
<h2 class="section-heading">Suitability</h2>
<div class="row g-3">
<div class="col-md-6 col-lg-3">
<div class="info-label">Pools</div>
<div><span class="badge bg-success">Recommended</span></div>
</div>
<div class="col-md-6 col-lg-3">
<div class="info-label">Vegetation</div>
<div><span class="badge bg-info text-dark">OK</span></div>
</div>
<div class="col-md-6 col-lg-3">
<div class="info-label">High Organics</div>
<div><span class="badge bg-info text-dark">OK</span></div>
</div>
<div class="col-md-6 col-lg-3">
<div class="info-label">Organic Crop Restriction</div>
<div><span class="badge bg-secondary">None</span></div>
</div>
</div>
</div>
<!-- Actions -->
<div class="d-flex justify-content-between mt-5 pt-3 border-top">
<button class="btn btn-outline-danger">
<i class="bi bi-trash me-2"></i> Remove from Inventory
</button>
<button class="btn btn-success">
<i class="bi bi-plus-circle me-2"></i> Add to Allowed Inventory
</button>
</div>
</div>
</div>
</div>
{{end}}

View file

@ -0,0 +1,211 @@
{{template "base.html" .}}
{{define "title"}}Dash{{end}}
{{define "extraheader"}}
<style>
.target-icon {
display: inline-block;
width: 24px;
height: 24px;
text-align: center;
line-height: 24px;
border-radius: 50%;
font-size: 12px;
font-weight: bold;
margin-right: 2px;
color: white;
}
.target-active {
background-color: #0d6efd;
}
.target-inactive {
background-color: #dee2e6;
color: #6c757d;
}
.table-responsive {
overflow-x: auto;
}
th {
white-space: nowrap;
}
</style>
{{end}}
{{define "content"}}
<div class="container-fluid p-4">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="mb-0">Pesticide Products Configuration</h1>
<a href="{{ .URLs.SettingPesticideAdd }}" class="btn btn-primary" id="addProductBtn">
<i class="bi bi-plus-circle me-2"></i>Add New Product
</a>
</div>
<div class="card">
<div class="card-body">
<div class="table-responsive">
<table class="table table-striped table-hover align-middle">
<thead class="table-light">
<tr>
<th>Product</th>
<th>Formulation</th>
<th>Targets</th>
<th>Residual (days)</th>
<th>Low Rate</th>
<th>Max Rate</th>
<th>Pools</th>
<th>Info</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<!-- Sample pesticide data -->
<tr>
<td><strong>BVA Oil</strong></td>
<td>Liquid</td>
<td>
<span class="target-icon target-inactive" title="Instar Stage 1">I1</span>
<span class="target-icon target-inactive" title="Instar Stage 2">I2</span>
<span class="target-icon target-inactive" title="Instar Stage 3">I3</span>
<span class="target-icon target-inactive" title="Instar Stage 4">I4</span>
<span class="target-icon target-active" title="Pupae">P</span>
</td>
<td>1</td>
<td>0.5 gal/acre</td>
<td>5 gal/acre</td>
<td><span class="badge bg-success">Recommended</span></td>
<td>
<a href="product-details.html?id=bva-oil" class="btn btn-sm btn-info" title="Product Information">
<i class="bi bi-info-circle"></i>
</a>
</td>
<td>
<button class="btn btn-sm btn-primary" title="Edit">
<i class="bi bi-pencil"></i>
</button>
<button class="btn btn-sm btn-danger" title="Delete">
<i class="bi bi-trash"></i>
</button>
</td>
</tr>
<tr>
<td><strong>VectoMax FG</strong></td>
<td>Granule</td>
<td>
<span class="target-icon target-active" title="Instar Stage 1">I1</span>
<span class="target-icon target-active" title="Instar Stage 2">I2</span>
<span class="target-icon target-active" title="Instar Stage 3">I3</span>
<span class="target-icon target-active" title="Instar Stage 4">I4</span>
<span class="target-icon target-inactive" title="Pupae">P</span>
</td>
<td>30</td>
<td>5 lbs/acre</td>
<td>20 lbs/acre</td>
<td><span class="badge bg-success">Recommended</span></td>
<td>
<a href="product-details.html?id=vectomax-fg" class="btn btn-sm btn-info" title="Product Information">
<i class="bi bi-info-circle"></i>
</a>
</td>
<td>
<button class="btn btn-sm btn-primary" title="Edit">
<i class="bi bi-pencil"></i>
</button>
<button class="btn btn-sm btn-danger" title="Delete">
<i class="bi bi-trash"></i>
</button>
</td>
</tr>
<tr>
<td><strong>Censor</strong></td>
<td>Liquid</td>
<td>
<span class="target-icon target-active" title="Instar Stage 1">I1</span>
<span class="target-icon target-active" title="Instar Stage 2">I2</span>
<span class="target-icon target-active" title="Instar Stage 3">I3</span>
<span class="target-icon target-active" title="Instar Stage 4">I4</span>
<span class="target-icon target-inactive" title="Pupae">P</span>
</td>
<td>21</td>
<td>0.75 gal/acre</td>
<td>2.5 gal/acre</td>
<td><span class="badge bg-warning text-dark">Allowed</span></td>
<td>
<a href="product-details.html?id=censor" class="btn btn-sm btn-info" title="Product Information">
<i class="bi bi-info-circle"></i>
</a>
</td>
<td>
<button class="btn btn-sm btn-primary" title="Edit">
<i class="bi bi-pencil"></i>
</button>
<button class="btn btn-sm btn-danger" title="Delete">
<i class="bi bi-trash"></i>
</button>
</td>
</tr>
<tr>
<td><strong>AquaBac XT</strong></td>
<td>Liquid</td>
<td>
<span class="target-icon target-active" title="Instar Stage 1">I1</span>
<span class="target-icon target-active" title="Instar Stage 2">I2</span>
<span class="target-icon target-active" title="Instar Stage 3">I3</span>
<span class="target-icon target-inactive" title="Instar Stage 4">I4</span>
<span class="target-icon target-inactive" title="Pupae">P</span>
</td>
<td>14</td>
<td>0.25 gal/acre</td>
<td>2 gal/acre</td>
<td><span class="badge bg-danger">Prohibited</span></td>
<td>
<a href="product-details.html?id=aquabac-xt" class="btn btn-sm btn-info" title="Product Information">
<i class="bi bi-info-circle"></i>
</a>
</td>
<td>
<button class="btn btn-sm btn-primary" title="Edit">
<i class="bi bi-pencil"></i>
</button>
<button class="btn btn-sm btn-danger" title="Delete">
<i class="bi bi-trash"></i>
</button>
</td>
</tr>
<tr>
<td><strong>Natular G30</strong></td>
<td>Granule</td>
<td>
<span class="target-icon target-active" title="Instar Stage 1">I1</span>
<span class="target-icon target-active" title="Instar Stage 2">I2</span>
<span class="target-icon target-active" title="Instar Stage 3">I3</span>
<span class="target-icon target-active" title="Instar Stage 4">I4</span>
<span class="target-icon target-inactive" title="Pupae">P</span>
</td>
<td>30</td>
<td>5 lbs/acre</td>
<td>12 lbs/acre</td>
<td><span class="badge bg-secondary">Discouraged</span></td>
<td>
<a href="product-details.html?id=natular-g30" class="btn btn-sm btn-info" title="Product Information">
<i class="bi bi-info-circle"></i>
</a>
</td>
<td>
<button class="btn btn-sm btn-primary" title="Edit">
<i class="bi bi-pencil"></i>
</button>
<button class="btn btn-sm btn-danger" title="Delete">
<i class="bi bi-trash"></i>
</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
{{end}}

View file

@ -0,0 +1,123 @@
{{template "base.html" .}}
{{define "title"}}Dash{{end}}
{{define "extraheader"}}
<style>
.form-check-input.switch-lg {
width: 3em;
height: 1.5em;
}
.required-field::after {
content: " *";
color: red;
}
</style>
{{end}}
{{define "content"}}
<div class="container py-5">
<div class="row justify-content-center">
<div class="col-lg-8">
<div class="card shadow">
<div class="card-header bg-white">
<div class="d-flex justify-content-between align-items-center">
<h3 class="mb-0">Add New User</h3>
<a href="user-management.html" class="btn btn-outline-secondary btn-sm">
<i class="bi bi-arrow-left me-1"></i> Back to Users
</a>
</div>
</div>
<div class="card-body">
<form id="addUserForm" class="needs-validation" novalidate>
<!-- Full Name -->
<div class="mb-3">
<label for="fullName" class="form-label required-field">Full Name</label>
<input type="text" class="form-control" id="fullName" required>
<div class="invalid-feedback">
Please provide the user's full name.
</div>
</div>
<!-- Email Address -->
<div class="mb-3">
<label for="emailAddress" class="form-label required-field">Email Address</label>
<input type="email" class="form-control" id="emailAddress" required>
<div class="invalid-feedback">
Please provide a valid email address.
</div>
<div class="form-text">An invitation will be sent to this email address.</div>
</div>
<!-- Username -->
<div class="mb-3">
<label for="username" class="form-label required-field">Username</label>
<input type="text" class="form-control" id="username" required>
<div class="invalid-feedback">
Please provide a username.
</div>
<div class="form-text">Username must be unique and contain only letters, numbers, and underscores.</div>
</div>
<div class="row">
<!-- Role -->
<div class="col-md-6 mb-3">
<label for="userRole" class="form-label required-field">Role</label>
<select class="form-select" id="userRole" required>
<option value="" selected disabled>Select a role</option>
<option value="lead">Lead</option>
<option value="technician">Technician</option>
<option value="administrator">Administrator</option>
</select>
<div class="invalid-feedback">
Please select a role.
</div>
</div>
<!-- Initial Status -->
<div class="col-md-6 mb-3">
<label for="initialStatus" class="form-label">Initial Status</label>
<select class="form-select" id="initialStatus">
<option value="invited" selected>Invited</option>
<option value="active">Active</option>
</select>
</div>
</div>
<!-- Permissions -->
<div class="mb-4">
<label class="form-label d-block">Permissions</label>
<div class="form-check form-switch">
<input class="form-check-input switch-lg" type="checkbox" id="serveWarrants">
<label class="form-check-label" for="serveWarrants">
Can serve warrants
</label>
</div>
</div>
<!-- Send welcome email checkbox -->
<div class="mb-4">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="sendWelcomeEmail" checked>
<label class="form-check-label" for="sendWelcomeEmail">
Send welcome email with login instructions
</label>
</div>
</div>
<hr>
<!-- Form actions -->
<div class="d-flex justify-content-end gap-2">
<a href="user-management.html" class="btn btn-secondary">
Cancel
</a>
<button type="submit" class="btn btn-primary">
<i class="bi bi-person-plus me-1"></i> Add User
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{{end}}

144
templates/setting-user.html Normal file
View file

@ -0,0 +1,144 @@
{{template "base.html" .}}
{{define "title"}}Dash{{end}}
{{define "extraheader"}}
<style>
.form-check-input.switch-lg {
width: 3em;
height: 1.5em;
}
.status-badge {
width: 100px;
}
</style>
{{end}}
{{define "content"}}
<div class="container-fluid p-4">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="mb-0">User Management</h1>
<a href="{{ .URLs.SettingUserAdd }}" class="btn btn-primary" id="addUserBtn">
<i class="bi bi-plus-circle me-2"></i>Add New User
</a>
</div>
<div class="card">
<div class="card-body">
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead class="table-light">
<tr>
<th>Full Name</th>
<th>Email Address</th>
<th>Username</th>
<th>Role</th>
<th>Serve Warrants</th>
<th>Status</th>
<th>Last Login</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<!-- Sample user data -->
<tr>
<td>John Doe</td>
<td>john.doe@example.com</td>
<td>johndoe</td>
<td>
<select class="form-select form-select-sm">
<option>Lead</option>
<option selected>Technician</option>
<option>Administrator</option>
</select>
</td>
<td>
<div class="form-check form-switch">
<input class="form-check-input switch-lg" type="checkbox" checked>
</div>
</td>
<td><span class="badge bg-success status-badge">Active</span></td>
<td>2023-06-15 09:45 AM</td>
<td>
<button class="btn btn-sm btn-warning" title="Deactivate">
<i class="bi bi-person-x"></i>
</button>
</td>
</tr>
<tr>
<td>Jane Smith</td>
<td>jane.smith@example.com</td>
<td>janesmith</td>
<td>
<select class="form-select form-select-sm">
<option selected>Lead</option>
<option>Technician</option>
<option>Administrator</option>
</select>
</td>
<td>
<div class="form-check form-switch">
<input class="form-check-input switch-lg" type="checkbox">
</div>
</td>
<td><span class="badge bg-success status-badge">Active</span></td>
<td>2023-06-17 14:20 PM</td>
<td>
<button class="btn btn-sm btn-warning" title="Deactivate">
<i class="bi bi-person-x"></i>
</button>
</td>
</tr>
<tr>
<td>Robert Johnson</td>
<td>robert.j@example.com</td>
<td>robertj</td>
<td>
<select class="form-select form-select-sm">
<option>Lead</option>
<option>Technician</option>
<option selected>Administrator</option>
</select>
</td>
<td>
<div class="form-check form-switch">
<input class="form-check-input switch-lg" type="checkbox" checked>
</div>
</td>
<td><span class="badge bg-secondary status-badge">Deactivated</span></td>
<td>2023-06-10 11:30 AM</td>
<td>
<button class="btn btn-sm btn-success" title="Activate">
<i class="bi bi-person-check"></i>
</button>
</td>
</tr>
<tr>
<td>Emily Wilson</td>
<td>emily.w@example.com</td>
<td>emilyw</td>
<td>
<select class="form-select form-select-sm">
<option>Lead</option>
<option selected>Technician</option>
<option>Administrator</option>
</select>
</td>
<td>
<div class="form-check form-switch">
<input class="form-check-input switch-lg" type="checkbox">
</div>
</td>
<td><span class="badge bg-warning text-dark status-badge">Invited</span></td>
<td>Never</td>
<td>
<button class="btn btn-sm btn-info" title="Resend Invitation">
<i class="bi bi-envelope"></i>
</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
{{end}}