Spaces:
Sleeping
Sleeping
| {% extends "base.html" %} | |
| {% block title %}Settings - PrepMate{% endblock %} | |
| {% block head %} | |
| <style> | |
| .deprecated-warning { | |
| background-color: #fff3cd; | |
| border-left: 4px solid #ffc107; | |
| padding: 12px 16px; | |
| margin-bottom: 20px; | |
| border-radius: 4px; | |
| } | |
| .deprecated-warning .bi { | |
| font-size: 1.2em; | |
| margin-right: 8px; | |
| } | |
| .model-info { | |
| font-size: 0.875rem; | |
| color: #6c757d; | |
| margin-top: 4px; | |
| } | |
| .settings-card { | |
| box-shadow: 0 2px 4px rgba(0,0,0,0.1); | |
| } | |
| </style> | |
| {% endblock %} | |
| {% block content %} | |
| <div class="container mt-4"> | |
| <div class="row"> | |
| <div class="col-lg-8 mx-auto"> | |
| <h1 class="mb-4"> | |
| <i class="bi bi-gear"></i> Settings | |
| </h1> | |
| {% if settings %} | |
| <div class="card settings-card"> | |
| <div class="card-header bg-primary text-white"> | |
| <h5 class="mb-0"> | |
| <i class="bi bi-cpu"></i> AI Model Selection | |
| </h5> | |
| </div> | |
| <div class="card-body"> | |
| <p class="text-muted"> | |
| Configure which OpenAI models are used for different operations. | |
| Your selections will be used for all future AI interactions. | |
| </p> | |
| <form method="POST" action="{{ url_for('settings.update_settings') }}"> | |
| <!-- Reply Generation Model --> | |
| <div class="mb-4"> | |
| <label for="reply_generation_model" class="form-label fw-bold"> | |
| <i class="bi bi-chat-dots"></i> Reply Generation Model | |
| </label> | |
| <select | |
| class="form-select" | |
| id="reply_generation_model" | |
| name="reply_generation_model" | |
| required | |
| > | |
| {% for model in settings.valid_models %} | |
| <option value="{{ model }}" | |
| {% if model == settings.reply_generation_model %}selected{% endif %}> | |
| {{ model }} | |
| </option> | |
| {% endfor %} | |
| </select> | |
| <div class="model-info"> | |
| Used when generating AI responses to your questions and messages. | |
| </div> | |
| </div> | |
| <!-- Last Updated --> | |
| <div class="mb-3"> | |
| <small class="text-muted"> | |
| <i class="bi bi-clock"></i> Last updated: {{ settings.updated_at }} | |
| </small> | |
| </div> | |
| <!-- Submit Button --> | |
| <div class="d-grid gap-2"> | |
| <button type="submit" class="btn btn-primary"> | |
| <i class="bi bi-check-circle"></i> Save Settings | |
| </button> | |
| </div> | |
| </form> | |
| </div> | |
| </div> | |
| <!-- Available Models Reference --> | |
| <div class="card mt-4"> | |
| <div class="card-header"> | |
| <h6 class="mb-0"> | |
| <i class="bi bi-info-circle"></i> Available Model | |
| </h6> | |
| </div> | |
| <div class="card-body"> | |
| <p class="mb-0"><strong>gpt-4.1-mini:</strong> Cost-effective GPT-4 variant</p> | |
| </div> | |
| </div> | |
| <!-- Response Template Editor (US2) --> | |
| <div class="card settings-card mt-4"> | |
| <div class="card-header bg-success text-white"> | |
| <h5 class="mb-0"> | |
| <i class="bi bi-file-text"></i> Response Template | |
| </h5> | |
| </div> | |
| <div class="card-body"> | |
| <p class="text-muted"> | |
| Customize how AI responses are structured. Templates use Go template syntax with variables like {% raw %}{{.UserMessage}}{% endraw %}, {% raw %}{{.SessionProfile}}{% endraw %}, etc. | |
| </p> | |
| <form method="POST" action="{{ url_for('settings.create_template') }}" id="template-form"> | |
| <!-- Template Content Textarea --> | |
| <div class="mb-3"> | |
| <label for="template_content" class="form-label fw-bold"> | |
| <i class="bi bi-code-square"></i> Template Content | |
| </label> | |
| <textarea | |
| class="form-control font-monospace" | |
| id="template_content" | |
| name="template_content" | |
| rows="15" | |
| maxlength="10000" | |
| required | |
| style="font-size: 0.875rem;" | |
| >{% if active_template %}{{ active_template.template_content }}{% endif %}</textarea> | |
| <div class="form-text"> | |
| <span id="char-count">0</span> / 10000 characters | |
| </div> | |
| </div> | |
| <!-- Version History Dropdown --> | |
| {% if template_versions and template_versions|length > 0 %} | |
| <div class="mb-3"> | |
| <label for="version_selector" class="form-label fw-bold"> | |
| <i class="bi bi-clock-history"></i> Version History | |
| </label> | |
| <select class="form-select" id="version_selector"> | |
| {% for version in template_versions %} | |
| <option | |
| value="{{ version.version_id }}" | |
| data-content="{{ version.template_content }}" | |
| {% if version.is_active %}selected{% endif %} | |
| > | |
| {{ version.created_at }} {% if version.is_active %}(Active){% endif %} | |
| </option> | |
| {% endfor %} | |
| </select> | |
| <div class="form-text"> | |
| Select a previous version to view or activate it. | |
| </div> | |
| </div> | |
| <div class="d-flex gap-2"> | |
| <button type="submit" class="btn btn-success"> | |
| <i class="bi bi-save"></i> Save New Version | |
| </button> | |
| <button type="button" class="btn btn-outline-primary" id="activate-btn"> | |
| <i class="bi bi-check-circle"></i> Activate Selected Version | |
| </button> | |
| </div> | |
| {% else %} | |
| <div class="mb-3"> | |
| <p class="text-muted"> | |
| <i class="bi bi-info-circle"></i> No version history yet. Save your first template version above. | |
| </p> | |
| </div> | |
| <button type="submit" class="btn btn-success"> | |
| <i class="bi bi-save"></i> Save New Version | |
| </button> | |
| {% endif %} | |
| </form> | |
| </div> | |
| </div> | |
| {% else %} | |
| <div class="alert alert-warning"> | |
| <i class="bi bi-exclamation-triangle"></i> | |
| Unable to load settings. Please try again later. | |
| </div> | |
| {% endif %} | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Character counter | |
| const templateTextarea = document.getElementById('template_content'); | |
| const charCount = document.getElementById('char-count'); | |
| function updateCharCount() { | |
| if (templateTextarea && charCount) { | |
| charCount.textContent = templateTextarea.value.length; | |
| } | |
| } | |
| if (templateTextarea) { | |
| templateTextarea.addEventListener('input', updateCharCount); | |
| updateCharCount(); // Initial count | |
| } | |
| // Version selector - load template content when selecting a version | |
| const versionSelector = document.getElementById('version_selector'); | |
| if (versionSelector) { | |
| versionSelector.addEventListener('change', function() { | |
| const selectedOption = this.options[this.selectedIndex]; | |
| const content = selectedOption.getAttribute('data-content'); | |
| if (content && templateTextarea) { | |
| templateTextarea.value = content; | |
| updateCharCount(); | |
| } | |
| }); | |
| } | |
| // Activate selected version button | |
| const activateBtn = document.getElementById('activate-btn'); | |
| if (activateBtn) { | |
| activateBtn.addEventListener('click', function() { | |
| if (!versionSelector) return; | |
| const versionId = versionSelector.value; | |
| if (!versionId) { | |
| alert('Please select a version to activate'); | |
| return; | |
| } | |
| // Send POST request to activate endpoint | |
| fetch(`{{ url_for('settings.activate_template', version_id='__VERSION_ID__') }}`.replace('__VERSION_ID__', versionId), { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| 'X-Requested-With': 'XMLHttpRequest' | |
| } | |
| }) | |
| .then(response => response.json()) | |
| .then(data => { | |
| if (data.success) { | |
| window.location.reload(); | |
| } else { | |
| alert('Error activating template: ' + (data.error || 'Unknown error')); | |
| } | |
| }) | |
| .catch(error => { | |
| console.error('Error:', error); | |
| alert('Error activating template. Please try again.'); | |
| }); | |
| }); | |
| } | |
| </script> | |
| {% endblock %} | |