Files
2025-07-07 01:44:12 +02:00

361 lines
13 KiB
Plaintext

package pages
import (
"tankstopp/internal/currency"
"tankstopp/internal/models"
"tankstopp/internal/views/components"
)
templ SettingsPage(user *models.User, username string, currencies []currency.Currency, successMessage, errorMessage string) {
@components.BaseLayout("Settings", user, username) {
@components.PageHeader("Manage your account", "Settings")
<div class="page-body">
<div class="container-xl">
if successMessage != "" {
<div class="row mb-3">
<div class="col-12">
@components.Alert("success", successMessage)
</div>
</div>
}
if errorMessage != "" {
<div class="row mb-3">
<div class="col-12">
@components.Alert("danger", errorMessage)
</div>
</div>
}
<div class="row">
<div class="col-12 col-lg-8">
<!-- Profile Settings -->
<div class="row mb-4">
<div class="col-12">
@components.Card("Profile Settings", "user") {
@components.Form("post", "/settings/profile") {
<div class="row">
<div class="col-md-6">
@components.FormGroup("Username", "Your unique username") {
@components.Input("username", "text", "Enter username", username, true)
}
</div>
<div class="col-md-6">
@components.FormGroup("Email", "Your email address") {
@components.Input("email", "email", "Enter email", user.Email, true)
}
</div>
</div>
<div class="row">
<div class="col-md-6">
@components.FormGroup("Base Currency", "Default currency for fuel prices") {
@components.CurrencySelect("base_currency", user.BaseCurrency, currencies)
}
</div>
</div>
<div class="row">
<div class="col-12">
@components.ButtonGroup() {
@components.PrimaryButton("Save Profile", "save")
}
</div>
</div>
}
}
</div>
</div>
<!-- Application Preferences -->
<div class="row mb-4">
<div class="col-12">
@components.Card("Application Preferences", "settings") {
@components.Form("post", "/settings/preferences") {
<div class="row">
<div class="col-md-6">
@components.FormGroup("Distance Unit", "Unit for distance measurements") {
@components.Select("distance_unit", false) {
@components.Option("km", "Kilometers (km)", true)
@components.Option("mi", "Miles (mi)", false)
}
}
</div>
<div class="col-md-6">
@components.FormGroup("Volume Unit", "Unit for fuel volume measurements") {
@components.Select("volume_unit", false) {
@components.Option("L", "Liters (L)", true)
@components.Option("gal", "Gallons (gal)", false)
}
}
</div>
</div>
<div class="row">
<div class="col-md-6">
@components.FormGroup("Date Format", "How dates are displayed") {
@components.Select("date_format", false) {
@components.Option("DD/MM/YYYY", "DD/MM/YYYY", false)
@components.Option("MM/DD/YYYY", "MM/DD/YYYY", false)
@components.Option("YYYY-MM-DD", "YYYY-MM-DD", true)
}
}
</div>
<div class="col-md-6">
@components.FormGroup("Language", "Application language") {
@components.Select("language", false) {
@components.Option("en", "English", true)
@components.Option("de", "Deutsch", false)
@components.Option("fr", "Français", false)
@components.Option("es", "Español", false)
}
}
</div>
</div>
<div class="row">
<div class="col-12">
@components.FormGroup("Notifications", "Email notification preferences") {
@components.Switch("email_notifications", "Send email notifications", false)
}
</div>
</div>
<div class="row">
<div class="col-12">
@components.ButtonGroup() {
@components.PrimaryButton("Save Preferences", "save")
}
</div>
</div>
}
}
</div>
</div>
<!-- Security Settings -->
<div class="row mb-4">
<div class="col-12">
@components.Card("Security Settings", "lock") {
@components.Form("post", "/settings/password") {
<div class="row">
<div class="col-md-6">
@components.FormGroup("Current Password", "Enter your current password") {
@components.PasswordInput("current_password", "Current password", true)
}
</div>
<div class="col-md-6">
@components.FormGroup("New Password", "Choose a new password") {
@components.PasswordInput("new_password", "New password", true)
}
</div>
</div>
<div class="row">
<div class="col-md-6">
@components.FormGroup("Confirm New Password", "Confirm your new password") {
@components.PasswordInput("confirm_password", "Confirm new password", true)
}
</div>
</div>
<div class="row">
<div class="col-12">
@components.ButtonGroup() {
@components.PrimaryButton("Change Password", "lock")
}
</div>
</div>
}
}
</div>
</div>
<!-- Data Management -->
<div class="row mb-4">
<div class="col-12">
@components.Card("Data Management", "database") {
<div class="row">
<div class="col-md-6">
<h5>Export Data</h5>
<p class="text-muted">Download your fuel stop data in various formats</p>
@components.ButtonGroup() {
<a href="/export/csv" class="btn btn-outline-primary">
@components.Icon("download", 24)
Export CSV
</a>
<a href="/export/json" class="btn btn-outline-primary">
@components.Icon("download", 24)
Export JSON
</a>
}
</div>
<div class="col-md-6">
<h5>Import Data</h5>
<p class="text-muted">Import fuel stop data from a CSV file</p>
@components.Form("post", "/import/csv") {
<div class="mb-3">
<input type="file" class="form-control" name="csv_file" accept=".csv" required/>
</div>
@components.PrimaryButton("Import CSV", "upload")
}
</div>
</div>
<hr class="my-4"/>
<div class="row">
<div class="col-12">
<h5 class="text-danger">Danger Zone</h5>
<p class="text-muted">These actions cannot be undone</p>
@components.ButtonGroup() {
<button type="button" class="btn btn-outline-danger" onclick="confirmClearData()">
@components.Icon("trash", 24)
Clear All Data
</button>
}
</div>
</div>
}
</div>
</div>
<!-- Account Management -->
<div class="row mb-4">
<div class="col-12">
@components.Card("Account Management", "user") {
<div class="row">
<div class="col-12">
<h5 class="text-danger">Delete Account</h5>
<p class="text-muted">
Permanently delete your account and all associated data. This action cannot be undone.
</p>
<div class="alert alert-danger" role="alert">
<div class="d-flex">
<div>
@components.Icon("alert-triangle", 24)
</div>
<div>
<strong>Warning:</strong> This will permanently delete your account, all vehicles, and all fuel stop records.
</div>
</div>
</div>
<button type="button" class="btn btn-danger" onclick="confirmDeleteAccount()">
@components.Icon("trash", 24)
Delete Account
</button>
</div>
</div>
}
</div>
</div>
</div>
<!-- Sidebar with Quick Stats -->
<div class="col-12 col-lg-4">
<div class="row">
<div class="col-12">
@components.Card("Account Summary", "info-circle") {
<div class="list-group list-group-flush">
<div class="list-group-item">
<div class="d-flex justify-content-between">
<span>Member since</span>
<span class="text-muted">{ user.CreatedAt.Format("Jan 2006") }</span>
</div>
</div>
<div class="list-group-item">
<div class="d-flex justify-content-between">
<span>Email</span>
<span class="text-muted">{ user.Email }</span>
</div>
</div>
<div class="list-group-item">
<div class="d-flex justify-content-between">
<span>Base currency</span>
<span class="text-muted">{ user.BaseCurrency }</span>
</div>
</div>
<div class="list-group-item">
<div class="d-flex justify-content-between">
<span>Account status</span>
<span class="text-muted">
<span class="badge bg-success">Active</span>
</span>
</div>
</div>
</div>
}
</div>
</div>
<div class="row mt-4">
<div class="col-12">
@components.Card("Quick Actions", "zap") {
<div class="list-group list-group-flush">
<a href="/add" class="list-group-item list-group-item-action d-flex align-items-center">
<span class="me-2">
@components.Icon("plus", 24)
</span>
Add Fuel Stop
</a>
<a href="/vehicles" class="list-group-item list-group-item-action d-flex align-items-center">
<span class="me-2">
@components.Icon("car", 24)
</span>
Manage Vehicles
</a>
<a href="/dashboard" class="list-group-item list-group-item-action d-flex align-items-center">
<span class="me-2">
@components.Icon("home", 24)
</span>
Go to Dashboard
</a>
</div>
}
</div>
</div>
</div>
</div>
</div>
</div>
@SettingsScript()
}
}
script SettingsScript() {
function confirmClearData() {
if (confirm('Are you sure you want to clear all your data? This will delete all fuel stops and vehicles permanently.')) {
if (confirm('This action cannot be undone. Are you absolutely sure?')) {
// Create a form to submit the clear data request
const form = document.createElement('form');
form.method = 'POST';
form.action = '/settings/clear-data';
document.body.appendChild(form);
form.submit();
}
}
}
function confirmDeleteAccount() {
if (confirm('Are you sure you want to delete your account? This will permanently delete all your data.')) {
if (confirm('This action cannot be undone. Type "DELETE" to confirm:')) {
const confirmation = prompt('Please type "DELETE" to confirm account deletion:');
if (confirmation === 'DELETE') {
// Create a form to submit the delete account request
const form = document.createElement('form');
form.method = 'POST';
form.action = '/settings/delete-account';
document.body.appendChild(form);
form.submit();
} else {
alert('Account deletion cancelled. The confirmation text did not match.');
}
}
}
}
// Initialize settings page
document.addEventListener('DOMContentLoaded', function() {
// Initialize tooltips
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
return new bootstrap.Tooltip(tooltipTriggerEl);
});
// Handle file input styling
const fileInputs = document.querySelectorAll('input[type="file"]');
fileInputs.forEach(function(input) {
input.addEventListener('change', function(e) {
const fileName = e.target.files[0] ? e.target.files[0].name : 'No file chosen';
const label = e.target.parentNode.querySelector('.file-label');
if (label) {
label.textContent = fileName;
}
});
});
});
}