cuori/index.html
Isaak dc1b2ecb08
🎨 Enhance UI and Refactor Backend for Email Configurations
- ✏️ Update HTML title to "Invoice Email Sender"
- 💄 Change font from 'Roboto' to 'Lora' and revise color scheme
- 🌈 Refine button and input styles with new colors, borders, and transitions
-  Implement tab functionality with CSS rules, HTML structure, and JS listeners
- 📑 Revamp status bar style and content

- 🔨 Refactor main.py:
  - 🗃️ Adapt read_yaml and write_yaml for enhanced 'email' and 'email_template' structure
  - 🔧 Modify handle_data for structure changes
2023-12-22 23:37:44 +01:00

272 lines
9.1 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Invoice Email Sender</title>
<link href="https://fonts.googleapis.com/css2?family=Lora:wght@400;700&display=swap" rel="stylesheet">
<style>
:root {
/* color scheme */
--primary-color: #007bff;
--primary-dark: #0056b3;
--secondary-color: #333;
--light-color: #f4f7fa;
--lighter-color: #f8f9fa;
--error-color: #ee5555;
/* Font and border styling */
--font-family: 'Lora', serif;
--border-radius: 10px;
--border-color: #ccc;
--border-focus-color: #007bff;
/* Shadow and transitions */
--box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
--transition-speed: 0.3s;
}
body {
font-family: var(--font-family);
background-color: var(--light-color);
color: var(--secondary-color);
margin: 0;
padding: 20px;
line-height: 1.6;
}
.container {
max-width: 850px;
margin: auto;
padding: 20px;
background: #fff;
border-radius: var(--border-radius);
box-shadow: var(--box-shadow);
text-align: center;
}
.nav-tab {
display: inline-block;
margin-right: 15px;
padding: 10px;
cursor: pointer;
color: var(--primary-color);
transition: color var(--transition-speed);
}
.nav-tab:hover, .nav-tab.active {
color: var(--primary-dark);
border-bottom: 3px solid var(--primary-color);
}
.tab-content {
display: none; /* Hide all tab content by default */
}
.tab-content.active {
display: block;
padding: 20px;
text-align: left;
border-top: 1px solid #eee;
}
.button {
background: var(--primary-color);
color: #fff;
border: none;
padding: 10px 20px;
margin: 10px 5px;
border-radius: var(--border-radius);
cursor: pointer;
transition: background-color var(--transition-speed);
font-weight: 500;
font-size: 1rem;
}
.button:hover {
background-color: var(--primary-dark);
}
input[type="text"], input[type="password"], textarea {
width: calc(100% - 20px);
padding: 10px;
border: 1px solid var(--border-color);
border-radius: var(--border-radius);
margin-top: 10px;
display: block;
margin-bottom: 20px;
line-height: 1.4;
background: var(--lighter-color);
}
input[type="text"]:focus, input[type="password"]:focus, textarea:focus {
border-color: var(--border-focus-color);
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
color: var(--secondary-color);
text-align: left;
}
.status-bar {
padding: 10px;
margin-top: 20px;
text-align: left;
font-size: .9rem;
}
</style>
</head>
<body>
<div class="container" id="appContainer">
<div>
<div class="nav-tab active" onclick="changeTab(event, 'config')">Configuration</div>
<div class="nav-tab" onclick="changeTab(event, 'csv')">CSV Management</div>
<div class="nav-tab" onclick="changeTab(event, 'email')">Email Operations</div>
</div>
<div id="config" class="tab-content active">
<label for="user">User:</label>
<input type="text" id="user" name="user">
<label for="password">Password:</label>
<input type="password" id="password" name="password">
<label for="ccEmail">CC Email:</label>
<input type="text" id="ccEmail" name="ccEmail">
<label for="bccEmail">BCC Email:</label>
<input type="text" id="bccEmail" name="bccEmail">
<label for="emailTemplate">Email Template:</label>
<textarea id="emailTemplate" rows="6"></textarea>
<button class="button" id="loadConfigBtn">Load Config</button>
<button class="button" id="saveConfigBtn">Save Config</button>
</div>
<div id="csv" class="tab-content">
<!-- CSV Management Content -->
<label for="csvPath">CSV Path:</label>
<input type="text" id="csvPath" name="csvPath">
<button class="button">Load CSV</button>
</div>
<div id="email" class="tab-content">
<!-- Email Operations Content -->
<button class="button">Send Emails</button>
<textarea rows="10">Log output here...</textarea>
</div>
<div class="status-bar" id="statusMessage">Status: Ready</div>
</div>
<script>
document.addEventListener("DOMContentLoaded", function () {
// Event listeners for buttons
document.getElementById('loadConfigBtn').addEventListener('click', loadConfig);
document.getElementById('saveConfigBtn').addEventListener('click', saveConfig);
});
function changeTab(event, tabId) {
const tabContents = document.getElementsByClassName("tab-content");
const tabs = document.getElementsByClassName("nav-tab");
// Hide all tab contents
for (let i = 0; i < tabContents.length; i++) {
tabContents[i].style.display = "none"; // Hide
tabContents[i].classList.remove("active");
}
// Remove 'active' class from all tabs
for (let i = 0; i < tabs.length; i++) {
tabs[i].classList.remove("active");
}
// Show the clicked tab content and add 'active' class
document.getElementById(tabId).style.display = "block";
document.getElementById(tabId).classList.add("active");
event.currentTarget.classList.add("active");
}
function loadConfig() {
fetch('/data')
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok: ' + response.statusText);
}
return response.json();
})
.then(data => {
if (!data.email || typeof data.email_template !== 'string') {
throw new Error('Incorrect data structure from server');
}
document.getElementById('user').value = data.email.user || '';
document.getElementById('password').value = data.email.password || '';
document.getElementById('ccEmail').value = data.email.cc_email || '';
document.getElementById('bccEmail').value = data.email.bcc_email || '';
document.getElementById('emailTemplate').textContent = data.email_template || '';
updateStatusBar("Configuration Loaded Successfully");
})
.catch(error => {
console.error('Error loading configuration:', error);
updateStatusBar(`Error loading configuration: ${error}`, true);
});
}
function saveConfig() {
const emailData = {
user: document.getElementById('user').value,
password: document.getElementById('password').value,
cc_email: document.getElementById('ccEmail').value,
bcc_email: document.getElementById('bccEmail').value
};
const emailTemplateData = document.getElementById('emailTemplate').value;
fetch('/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: emailData,
email_template: emailTemplateData
}),
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok: ' + response.statusText);
}
return response.json();
})
.then(data => {
if (data.success) {
alert("Configuration Saved Successfully");
updateStatusBar("Configuration Saved Successfully");
} else {
throw new Error("Failed to save configuration: " + data.message);
}
})
.catch(error => {
console.error('Error saving configuration:', error);
updateStatusBar(`Error saving configuration: ${error}`, true);
});
}
function updateStatusBar(message, isError = false) {
const statusBar = document.getElementById('statusMessage');
statusBar.textContent = message;
if (isError) {
statusBar.style.color = 'var(--error-color)';
} else {
statusBar.style.color = 'initial'; // or any other color for normal messages
}
}
</script>
</body>
</html>