mirror of
https://github.com/rudy3333/eversync.git
synced 2025-07-01 08:36:02 +00:00
252 lines
No EOL
8.5 KiB
HTML
252 lines
No EOL
8.5 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Eversync</title>
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">
|
|
{% load static %}
|
|
<link rel="icon" href="{% static 'favicon.ico' %}">
|
|
<link rel="stylesheet" href="{% static 'index-style.css' %}" ">
|
|
<script src="https://cdn.jsdelivr.net/npm/tesseract.js@4/dist/tesseract.min.js"></script>
|
|
</head>
|
|
|
|
</head>
|
|
<body>
|
|
<div class="header">
|
|
<div class="header-content">
|
|
<a href="/"><img src="{% static 'eversync2.png' %}" alt="Eversync Logo" style="height: 80px; margin-right: 10px; display: flex; align-items: center; gap: 5px;"></a>
|
|
<a href="/" class="logo" >eversync</a>
|
|
<div class="nav-links" style="position: relative;">
|
|
<div class="dropdown">
|
|
<button class="dropdown-toggle" style="background: none; border: none; color: white; font-size: 16px; cursor: pointer;">
|
|
Welcome, {{ user.username }} <i class="fas fa-caret-down"></i>
|
|
</button>
|
|
<div class="dropdown-menu" style="display: none; position: absolute; right: 0; background-color: #333; border: 1px solid #444; border-radius: 4px; padding: 10px; width: 184px;">
|
|
|
|
<form action="{% url 'manage' %}" method="post" style="margin: 0;">
|
|
{% csrf_token %}
|
|
<button type="submit" class="logout-button" style="background-color: transparent; color: white; border: none; cursor: pointer;">Manage Account</button>
|
|
</form>
|
|
|
|
<form action="{% url 'logoutz' %}" method="post" style="margin: 0;">
|
|
{% csrf_token %}
|
|
<button type="submit" class="logout-button" style="background-color: transparent; color: white; border: none; cursor: pointer;">Log Out</button>
|
|
</form>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
async function fetchNotes() {
|
|
const response = await fetch("/note_list");
|
|
const notes = await response.json();
|
|
const container = document.getElementById("notes-container");
|
|
container.innerHTML = "";
|
|
|
|
notes.forEach(note => {
|
|
const noteDiv = document.createElement("div");
|
|
noteDiv.innerHTML = `<h3>${note.title}</h3><p>${note.content}</p><small>Created at: ${note.time}</small>`;
|
|
container.appendChild(noteDiv);
|
|
});
|
|
}
|
|
|
|
async function addNote(event) {
|
|
event.preventDefault();
|
|
const title = document.getElementById("title").value;
|
|
const content = document.getElementById("content").value;
|
|
|
|
const response = await fetch("/note_add/", {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/x-www-form-urlencoded",
|
|
"X-CSRFToken": getCSRFToken()
|
|
},
|
|
body: `title=${encodeURIComponent(title)}&content=${encodeURIComponent(content)}`
|
|
});
|
|
|
|
if (response.status === 201) {
|
|
document.getElementById("note-form").reset();
|
|
fetchNotes();
|
|
} else {
|
|
alert("Failed to create note");
|
|
}
|
|
}
|
|
|
|
function getCSRFToken() {
|
|
const name = "csrftoken=";
|
|
const decodedCookie = decodeURIComponent(document.cookie);
|
|
const cookies = decodedCookie.split(";");
|
|
for (let cookie of cookies) {
|
|
cookie = cookie.trim();
|
|
if (cookie.indexOf(name) === 0) {
|
|
return cookie.substring(name.length, cookie.length);
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
|
|
let recognition;
|
|
|
|
function startVoiceRecognition() {
|
|
if (!('webkitSpeechRecognition' in window || 'SpeechRecognition' in window)) {
|
|
alert("Your browser does not support speech recognition.");
|
|
return;
|
|
}
|
|
|
|
document.getElementById('voiceModal').style.display = 'block';
|
|
|
|
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
|
|
recognition = new SpeechRecognition();
|
|
recognition.lang = 'en-US';
|
|
recognition.interimResults = false;
|
|
recognition.maxAlternatives = 1;
|
|
|
|
recognition.onresult = function(event) {
|
|
const transcript = event.results[0][0].transcript;
|
|
document.getElementById('content').value += transcript;
|
|
closeVoiceModal();
|
|
};
|
|
|
|
recognition.onerror = function(event) {
|
|
console.error("Speech recognition error", event.error);
|
|
alert("Speech recognition error: " + event.error);
|
|
closeVoiceModal();
|
|
};
|
|
|
|
recognition.start();
|
|
}
|
|
|
|
function stopVoiceRecognition() {
|
|
if (recognition) {
|
|
recognition.stop();
|
|
closeVoiceModal();
|
|
}
|
|
}
|
|
|
|
async function performOCR() {
|
|
const fileInput = document.getElementById('ocrImageInput');
|
|
if (!fileInput.files.length) {
|
|
alert("Please select an image first.");
|
|
return;
|
|
}
|
|
|
|
const image = fileInput.files[0];
|
|
const reader = new FileReader();
|
|
|
|
reader.onload = async function () {
|
|
const result = await Tesseract.recognize(reader.result, 'eng');
|
|
document.getElementById('content').value += result.data.text;
|
|
closeOCRModal();
|
|
};
|
|
|
|
reader.readAsDataURL(image);
|
|
}
|
|
|
|
function closeVoiceModal() {
|
|
document.getElementById('voiceModal').style.display = 'none';
|
|
}
|
|
|
|
function showOCRModal() {
|
|
document.getElementById('ocrModal').style.display = 'block';
|
|
}
|
|
|
|
function closeOCRModal() {
|
|
document.getElementById('ocrModal').style.display = 'none';
|
|
}
|
|
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|
fetchNotes();
|
|
document.getElementById("note-form").addEventListener("submit", addNote);
|
|
});
|
|
</script>
|
|
<style>
|
|
|
|
h1 {
|
|
text-align: center;
|
|
color: #333;
|
|
}
|
|
|
|
form {
|
|
margin-bottom: 30px;
|
|
text-align: center;
|
|
}
|
|
|
|
input, textarea {
|
|
width: 80%;
|
|
padding: 10px;
|
|
margin-bottom: 10px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 5px;
|
|
font-size: 1em;
|
|
}
|
|
|
|
button {
|
|
padding: 10px 20px;
|
|
font-size: 1em;
|
|
background-color: #ffec99;
|
|
border: 1px solid #e0c97f;
|
|
border-radius: 5px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
#notes-container > div {
|
|
background-color: #fff6cc;
|
|
border: 2px solid #ffe066;
|
|
border-radius: 10px;
|
|
padding: 15px;
|
|
box-shadow: 2px 2px 5px rgba(0,0,0,0.1);
|
|
max-width: 500px;
|
|
margin: 0 auto 10px auto;
|
|
}
|
|
|
|
#notes-container h3 {
|
|
margin-top: 0;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1>Your Notes</h1>
|
|
|
|
<form id="note-form">
|
|
<input type="text" id="title" name="title" placeholder="Note Title" required><br>
|
|
<textarea id="content" name="content" placeholder="Note Content" required></textarea><br>
|
|
<button type="button" onclick="startVoiceRecognition()">🎤 Speak</button>
|
|
<button type="button" onclick="showOCRModal()">🧠 Extract text from image</button>
|
|
<button type="submit">Add Note</button>
|
|
</form>
|
|
|
|
<div id="ocrModal" style="display:none; position: fixed; z-index: 1000; left: 0; top: 0; width: 100%; height: 100%; overflow: auto; background-color: rgba(0,0,0,0.4);">
|
|
<div style="background-color: #fff; margin: 15% auto; padding: 20px; border: 1px solid #888; width: 300px; text-align: center; border-radius: 10px;">
|
|
<h3>Select an Image</h3>
|
|
<input type="file" id="ocrImageInput" accept="image/*"><br><br>
|
|
<button onclick="performOCR()">Extract</button>
|
|
<button onclick="closeOCRModal()">Cancel</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="notes-container"> </div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
const toggle = document.querySelector('.dropdown-toggle');
|
|
const menu = document.querySelector('.dropdown-menu');
|
|
toggle.addEventListener('click', function () {
|
|
menu.style.display = menu.style.display === 'block' ? 'none' : 'block';
|
|
});
|
|
});
|
|
</script>
|
|
</body>
|
|
<div id="voiceModal" style="display:none; position: fixed; z-index: 1000; left: 0; top: 0; width: 100%; height: 100%; overflow: auto; background-color: rgba(0,0,0,0.4);">
|
|
<div style="background-color: #fff; margin: 15% auto; padding: 20px; border: 1px solid #888; width: 300px; text-align: center; border-radius: 10px;">
|
|
<h3>Speak now...</h3>
|
|
<button onclick="stopVoiceRecognition()">❌ Cancel</button>
|
|
</div>
|
|
</div>
|
|
</html> |