Upload files to "templates"
This commit is contained in:
@ -1,35 +1,26 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>{{ title }}</title>
|
<title>{{ title }}</title>
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
|
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
|
||||||
{% if theme == 'dark' %}
|
<link id="theme-stylesheet" rel="stylesheet" href="{{ url_for('static', filename='css/' + theme + '_theme.css') }}">
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/dark_theme.css') }}">
|
</head>
|
||||||
{% elif theme == 'modern' %}
|
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/modern_theme.css') }}">
|
|
||||||
{% elif theme == 'vampire' %}
|
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/vampire_theme.css') }}">
|
|
||||||
{% elif theme == 'nordic' %}
|
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/nordic_theme.css') }}">
|
|
||||||
{% elif theme == 'halloween' %}
|
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/halloween_theme.css') }}">
|
|
||||||
{% else %}
|
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/light_theme.css') }}">
|
|
||||||
{% endif %}
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
<!-- Burger icon for smaller screens -->
|
|
||||||
<div class="burger" onclick="toggleMenu()">
|
|
||||||
<div></div>
|
|
||||||
<div></div>
|
|
||||||
<div></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Navigation menu -->
|
<!-- Navigation menu -->
|
||||||
<nav class="nav-links">
|
<nav class="nav-links">
|
||||||
|
<div class="nav-left">
|
||||||
|
<!-- Search Bar -->
|
||||||
|
<div class="search-bar">
|
||||||
|
<form action="/search" method="GET">
|
||||||
|
<input type="text" name="query" placeholder="Search..." aria-label="Search">
|
||||||
|
<button type="submit">🔍</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
<!-- Centered Links -->
|
<!-- Centered Links -->
|
||||||
<div class="nav-center">
|
<div class="nav-center">
|
||||||
<a href="/">Home</a>
|
<a href="/">Home</a>
|
||||||
@ -52,7 +43,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<a href="/rule_creation">Rule Creation</a>
|
<a href="/rule_creation">Rule Creation</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Right-Aligned Links -->
|
<!-- Right-Aligned Links -->
|
||||||
<div class="nav-right">
|
<div class="nav-right">
|
||||||
{% if current_user.is_authenticated %}
|
{% if current_user.is_authenticated %}
|
||||||
@ -64,15 +54,8 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Theme Toggle Slider -->
|
|
||||||
<label class="switch">
|
|
||||||
<input type="checkbox" id="theme-toggle">
|
|
||||||
<span class="slider"></span>
|
|
||||||
</label>
|
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|
||||||
<div class="tip">
|
<div class="tip">
|
||||||
{{ random_tip | safe }}
|
{{ random_tip | safe }}
|
||||||
@ -83,56 +66,40 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Theme toggle functionality
|
|
||||||
const themeToggle = document.getElementById('theme-toggle');
|
const themeToggle = document.getElementById('theme-toggle');
|
||||||
const themeStylesheet = document.getElementById('theme-stylesheet');
|
|
||||||
const body = document.body;
|
const body = document.body;
|
||||||
|
|
||||||
// Check for stored theme in localStorage
|
// Initialize theme on page load
|
||||||
if (localStorage.getItem('theme') === 'light') {
|
const currentTheme = localStorage.getItem('theme') || 'modern';
|
||||||
themeToggle.checked = true;
|
body.classList.add(`${currentTheme}-theme`);
|
||||||
body.classList.add('light-theme');
|
themeToggle.checked = currentTheme === 'light';
|
||||||
body.classList.remove('dark-theme');
|
|
||||||
themeStylesheet.href = '{{ url_for("static", filename="css/light_theme.css") }}';
|
|
||||||
} else {
|
|
||||||
themeToggle.checked = false;
|
|
||||||
body.classList.add('dark-theme');
|
|
||||||
body.classList.remove('light-theme');
|
|
||||||
themeStylesheet.href = '{{ url_for("static", filename="css/dark_theme.css") }}';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Event listener for theme toggle
|
// Event listener for theme toggle
|
||||||
themeToggle.addEventListener('change', function() {
|
themeToggle.addEventListener('change', async function () {
|
||||||
if (this.checked) {
|
const newTheme = this.checked ? 'light' : 'modern';
|
||||||
body.classList.remove('dark-theme');
|
|
||||||
body.classList.add('light-theme');
|
// Apply theme immediately
|
||||||
themeStylesheet.href = '{{ url_for("static", filename="css/light_theme.css") }}';
|
body.classList.remove('modern-theme', 'light-theme');
|
||||||
localStorage.setItem('theme', 'light');
|
body.classList.add(`${newTheme}-theme`);
|
||||||
} else {
|
|
||||||
body.classList.remove('light-theme');
|
// Save the new theme locally
|
||||||
body.classList.add('dark-theme');
|
localStorage.setItem('theme', newTheme);
|
||||||
themeStylesheet.href = '{{ url_for("static", filename="css/dark_theme.css") }}';
|
|
||||||
localStorage.setItem('theme', 'dark');
|
// Send the update to the backend asynchronously
|
||||||
|
try {
|
||||||
|
const response = await fetch('/set_theme', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ theme: newTheme }),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
console.error('Failed to update theme on the server:', response.statusText);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error updating theme on the backend:', error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
</script>
|
||||||
const navLinks = document.querySelectorAll('.nav-links a');
|
|
||||||
|
|
||||||
navLinks.forEach(link => {
|
|
||||||
link.addEventListener('click', function() {
|
|
||||||
// Remove active class from all links
|
|
||||||
navLinks.forEach(link => link.classList.remove('active'));
|
|
||||||
|
|
||||||
// Add active class to clicked link
|
|
||||||
this.classList.add('active');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Burger menu toggle function for mobile
|
|
||||||
function toggleMenu() {
|
|
||||||
const navLinks = document.querySelector('.nav-links');
|
|
||||||
navLinks.classList.toggle('active');
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,28 +1,33 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>Notebook</h1>
|
<h1>Notebook</h1>
|
||||||
|
|
||||||
|
<!-- Notebook Form -->
|
||||||
<form method="POST">
|
<form method="POST">
|
||||||
<label for="category">Category:</label>
|
<label for="category">Category:</label>
|
||||||
<select name="category" id="category">
|
<select name="category" id="category" required>
|
||||||
<option value="notes">Notes</option>
|
<option value="notes">Notes</option>
|
||||||
<option value="ips">IPs</option>
|
<option value="ips">IPs</option>
|
||||||
<option value="domains">Domains</option>
|
<option value="domains">Domains</option>
|
||||||
<option value="services">Services</option>
|
<option value="services">Services</option>
|
||||||
<option value="tasks">Scheduled Tasks</option>
|
<option value="tasks">Scheduled Tasks</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<label for="entry">Entry:</label>
|
<label for="entry">Entry:</label>
|
||||||
<input type="text" name="entry" id="entry" required>
|
<textarea name="entry" id="entry" rows="2" required></textarea>
|
||||||
<button type="submit">Add</button>
|
<button type="submit">Add</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
|
<!-- Display Notebook Entries -->
|
||||||
{% for category, entries in notebook.items() %}
|
{% for category, entries in notebook.items() %}
|
||||||
<h2>{{ category.capitalize() }}</h2>
|
<h2>{{ category.capitalize() }}</h2>
|
||||||
<ul>
|
<ul>
|
||||||
{% for entry in entries %}
|
{% for entry in entries %}
|
||||||
<li>
|
<li>
|
||||||
{{ entry }} <a href="{{ url_for('delete_entry', category=category, index=loop.index0) }}">Delete</a>
|
{{ entry }}
|
||||||
|
<a href="{{ url_for('delete_entry', category=category, index=loop.index0) }}">Delete</a>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -3,32 +3,7 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>Create an Account</h1>
|
<h1>Create an Account</h1>
|
||||||
|
|
||||||
<form method="POST">
|
<div id="password-requirements" class="hidden">
|
||||||
<div>
|
|
||||||
<label for="username">Username</label>
|
|
||||||
<input type="text" id="username" name="username" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<label for="email">Email</label>
|
|
||||||
<input type="email" id="email" name="email" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<label for="password">Password</label>
|
|
||||||
<input type="password" id="password" name="password" required>
|
|
||||||
<small>Password must be at least 10 characters, contain 1 uppercase letter, 1 special character, and 1 number.</small>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<label for="confirm_password">Confirm Password</label>
|
|
||||||
<input type="password" id="confirm_password" name="confirm_password" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button type="submit" id="submit" disabled>Create Account</button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<div id="password-requirements">
|
|
||||||
<ul>
|
<ul>
|
||||||
<li id="min-length">Minimum 10 characters: ❌</li>
|
<li id="min-length">Minimum 10 characters: ❌</li>
|
||||||
<li id="uppercase">At least 1 uppercase letter: ❌</li>
|
<li id="uppercase">At least 1 uppercase letter: ❌</li>
|
||||||
@ -38,45 +13,51 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<form method="POST">
|
||||||
|
<label for="username">Username:</label>
|
||||||
|
<input type="text" id="username" name="username" required>
|
||||||
|
|
||||||
|
<label for="email">Email:</label>
|
||||||
|
<input type="email" id="email" name="email" required>
|
||||||
|
|
||||||
|
<label for="password">Password:</label>
|
||||||
|
<input type="password" id="password" name="password" required>
|
||||||
|
|
||||||
|
<label for="confirm_password">Confirm Password:</label>
|
||||||
|
<input type="password" id="confirm_password" name="confirm_password" required>
|
||||||
|
|
||||||
|
<button type="submit">Register</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const passwordInput = document.getElementById('password');
|
const passwordField = document.getElementById('password');
|
||||||
const confirmPasswordInput = document.getElementById('confirm_password');
|
const confirmPasswordField = document.getElementById('confirm_password');
|
||||||
const submitButton = document.getElementById('submit');
|
const passwordRequirements = document.getElementById('password-requirements');
|
||||||
|
|
||||||
const minLengthRequirement = document.getElementById('min-length');
|
function showRequirements() {
|
||||||
const uppercaseRequirement = document.getElementById('uppercase');
|
passwordRequirements.classList.remove('hidden');
|
||||||
const specialCharRequirement = document.getElementById('special-char');
|
}
|
||||||
const numberRequirement = document.getElementById('number');
|
|
||||||
const matchRequirement = document.getElementById('match');
|
|
||||||
|
|
||||||
function validatePassword() {
|
function hideRequirements() {
|
||||||
const password = passwordInput.value;
|
if (!passwordField.value && !confirmPasswordField.value) {
|
||||||
const confirmPassword = confirmPasswordInput.value;
|
passwordRequirements.classList.add('hidden');
|
||||||
|
|
||||||
// Regex pattern for password validation
|
|
||||||
const passwordPattern = /^(?=.*[A-Z])(?=.*\d)(?=.*[\W_]).{10,}$/;
|
|
||||||
|
|
||||||
const passwordValid = passwordPattern.test(password);
|
|
||||||
const passwordsMatch = password === confirmPassword;
|
|
||||||
|
|
||||||
// Check each validation rule and update the corresponding list item
|
|
||||||
minLengthRequirement.textContent = password.length >= 10 ? "Minimum 10 characters: ✔" : "Minimum 10 characters: ❌";
|
|
||||||
uppercaseRequirement.textContent = /[A-Z]/.test(password) ? "At least 1 uppercase letter: ✔" : "At least 1 uppercase letter: ❌";
|
|
||||||
specialCharRequirement.textContent = /[\W_]/.test(password) ? "At least 1 special character: ✔" : "At least 1 special character: ❌";
|
|
||||||
numberRequirement.textContent = /\d/.test(password) ? "At least 1 number: ✔" : "At least 1 number: ❌";
|
|
||||||
matchRequirement.textContent = passwordsMatch ? "Passwords match: ✔" : "Passwords match: ❌";
|
|
||||||
|
|
||||||
// Enable submit button only if all conditions are met
|
|
||||||
if (passwordValid && passwordsMatch) {
|
|
||||||
submitButton.disabled = false;
|
|
||||||
} else {
|
|
||||||
submitButton.disabled = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Event listeners for password input and confirmation
|
// Event listeners for showing and hiding the requirements
|
||||||
passwordInput.addEventListener('input', validatePassword);
|
passwordField.addEventListener('focus', showRequirements);
|
||||||
confirmPasswordInput.addEventListener('input', validatePassword);
|
passwordField.addEventListener('blur', hideRequirements);
|
||||||
|
|
||||||
|
confirmPasswordField.addEventListener('focus', showRequirements);
|
||||||
|
confirmPasswordField.addEventListener('blur', hideRequirements);
|
||||||
|
|
||||||
|
// Prevent hiding on invalid form submission
|
||||||
|
document.querySelector('form').addEventListener('submit', (event) => {
|
||||||
|
if (!passwordField.value || !confirmPasswordField.value) {
|
||||||
|
passwordRequirements.classList.remove('hidden');
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
18
templates/search_results.html
Normal file
18
templates/search_results.html
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>Search Results for "{{ query }}"</h1>
|
||||||
|
|
||||||
|
{% if results %}
|
||||||
|
<ul>
|
||||||
|
{% for result in results %}
|
||||||
|
<li>
|
||||||
|
<strong>{{ result.title }}</strong><br>
|
||||||
|
<p>{{ result.snippet }}</p>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% else %}
|
||||||
|
<p>No results found.</p>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
Reference in New Issue
Block a user