Link up settings in sidebar to settings page

This commit is contained in:
Eli Ribble 2026-02-09 19:57:12 +00:00
parent f00436b136
commit 316a94a6cf
No known key found for this signature in database
7 changed files with 243 additions and 236 deletions

View file

@ -41,7 +41,7 @@
</a>
</li>
<li>
<a href="#">
<a href="/setting">
<div class="menu-icon"><i class="bi bi-gear"></i></div>
<span class="menu-text ms-2">Settings</span>
</a>

View file

@ -146,7 +146,7 @@
latitude="36.3"
longitude="-119.2"
organization-id="{{ .User.Organization.ID }}"
tegola="{{ .Config.URLTegola }}"
tegola="{{ .URL.Tegola }}"
zoom="9"
/>
</div>

View file

@ -2,217 +2,6 @@
{{ 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

@ -2,7 +2,217 @@
{{ 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" }}
<p>Imagine settings here</p>
<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="{{ .URL.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="{{ .URL.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="{{ .URL.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

@ -24,7 +24,6 @@ import (
var ()
type Config struct {
URLTegola string
}
type ContentSource struct {
@ -52,7 +51,6 @@ type ContextCell struct {
User User
}
type ContextDashboard struct {
Config Config
CountTraps int
CountMosquitoSources int
CountServiceRequests int
@ -61,6 +59,7 @@ type ContextDashboard struct {
LastSync *time.Time
MapData ComponentMap
RecentRequests []ServiceRequestSummary
URL ContentURL
User User
}
@ -137,7 +136,16 @@ func getRoot(w http.ResponseWriter, r *http.Request) {
}
func getSettings(w http.ResponseWriter, r *http.Request, u *models.User) {
settings(w, r, u)
userContent, err := contentForUser(r.Context(), u)
if err != nil {
respondError(w, "Failed to get user content", err, http.StatusInternalServerError)
return
}
data := ContentAuthenticatedPlaceholder{
URL: newContentURL(),
User: userContent,
}
html.RenderOrError(w, "sync/settings.html", data)
}
func getSource(w http.ResponseWriter, r *http.Request, u *models.User) {
@ -291,9 +299,6 @@ func dashboard(ctx context.Context, w http.ResponseWriter, user *models.User) {
return
}
data := ContextDashboard{
Config: Config{
URLTegola: config.MakeURLTegola("/"),
},
CountTraps: int(trapCount),
CountMosquitoSources: int(sourceCount),
CountServiceRequests: int(serviceCount),
@ -308,18 +313,6 @@ func dashboard(ctx context.Context, w http.ResponseWriter, user *models.User) {
html.RenderOrError(w, "sync/dashboard.html", data)
}
func settings(w http.ResponseWriter, r *http.Request, user *models.User) {
userContent, err := contentForUser(r.Context(), user)
if err != nil {
respondError(w, "Failed to get user content", err, http.StatusInternalServerError)
return
}
data := ContentAuthenticatedPlaceholder{
User: userContent,
}
html.RenderOrError(w, "sync/settings.html", data)
}
func source(w http.ResponseWriter, r *http.Request, user *models.User, id uuid.UUID) {
org, err := user.Organization().One(r.Context(), db.PGInstance.BobDB)
if err != nil {

View file

@ -26,6 +26,7 @@ type ComponentMap struct {
Zoom int
}
type ContentAuthenticatedPlaceholder struct {
URL ContentURL
User User
}
type ContentMockURLs struct {

View file

@ -5,13 +5,27 @@ import (
)
type ContentURL struct {
PoolCSVUpload string
SamplePoolCSV string
PoolCSVUpload string
SamplePoolCSV string
Setting string
SettingIntegration string
SettingPesticide string
SettingPesticideAdd string
SettingUser string
SettingUserAdd string
Tegola string
}
func newContentURL() ContentURL {
return ContentURL{
PoolCSVUpload: config.MakeURLNidus("/pool/upload"),
SamplePoolCSV: config.MakeURLNidus("/static/file/sample-pool.csv"),
PoolCSVUpload: config.MakeURLNidus("/pool/upload"),
SamplePoolCSV: config.MakeURLNidus("/static/file/sample-pool.csv"),
Setting: config.MakeURLNidus("/setting"),
SettingIntegration: config.MakeURLNidus("/setting/integration"),
SettingPesticide: config.MakeURLNidus("/setting/pesticide"),
SettingPesticideAdd: config.MakeURLNidus("/setting/pesticide/add"),
SettingUser: config.MakeURLNidus("/setting/user"),
SettingUserAdd: config.MakeURLNidus("/setting/user/add"),
Tegola: config.MakeURLTegola("/"),
}
}