anycoder-287351b8 / index.html
Multimedix's picture
Upload folder using huggingface_hub
30ee50f verified
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Notizblock App</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
:root {
--primary-color: #4f46e5;
--primary-light: #818cf8;
--primary-dark: #3730a3;
--secondary-color: #f3f4f6;
--text-color: #1f2937;
--text-light: #6b7280;
--success-color: #10b981;
--warning-color: #f59e0b;
--danger-color: #ef4444;
--border-color: #e5e7eb;
--shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
--radius: 8px;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
color: var(--text-color);
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px 0;
margin-bottom: 30px;
border-bottom: 2px solid var(--border-color);
}
.header h1 {
font-size: 2.5rem;
background: linear-gradient(90deg, var(--primary-color), var(--primary-light));
-webkit-background-clip: text;
background-clip: text;
color: transparent;
display: flex;
align-items: center;
gap: 10px;
}
.header h1 i {
font-size: 2.2rem;
}
.header .anycoder {
color: var(--text-light);
font-size: 0.9rem;
text-decoration: none;
transition: color 0.3s;
}
.header .anycoder:hover {
color: var(--primary-color);
}
.app-container {
display: grid;
grid-template-columns: 300px 1fr;
gap: 30px;
}
@media (max-width: 768px) {
.app-container {
grid-template-columns: 1fr;
}
}
.sidebar {
background: white;
border-radius: var(--radius);
padding: 25px;
box-shadow: var(--shadow);
height: fit-content;
}
.note-form {
margin-bottom: 30px;
}
.note-form h2 {
margin-bottom: 15px;
font-size: 1.3rem;
color: var(--primary-color);
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
font-weight: 500;
}
.form-group input,
.form-group textarea,
.form-group select {
width: 100%;
padding: 10px;
border: 1px solid var(--border-color);
border-radius: var(--radius);
font-size: 1rem;
transition: border-color 0.3s;
}
.form-group input:focus,
.form-group textarea:focus,
.form-group select:focus {
outline: none;
border-color: var(--primary-color);
}
.form-group textarea {
min-height: 120px;
resize: vertical;
}
.btn {
padding: 10px 20px;
border: none;
border-radius: var(--radius);
cursor: pointer;
font-weight: 600;
transition: all 0.3s;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 8px;
}
.btn-primary {
background: var(--primary-color);
color: white;
}
.btn-primary:hover {
background: var(--primary-dark);
}
.btn-danger {
background: var(--danger-color);
color: white;
}
.btn-danger:hover {
background: #dc2626;
}
.btn-success {
background: var(--success-color);
color: white;
}
.btn-success:hover {
background: #059669;
}
.btn-full {
width: 100%;
}
.filter-section {
margin-top: 25px;
}
.filter-section h3 {
margin-bottom: 15px;
font-size: 1.1rem;
color: var(--primary-color);
}
.filter-options {
display: flex;
flex-direction: column;
gap: 10px;
}
.filter-option {
display: flex;
align-items: center;
gap: 10px;
padding: 8px 12px;
border-radius: var(--radius);
cursor: pointer;
transition: background 0.3s;
}
.filter-option:hover {
background: var(--secondary-color);
}
.filter-option.active {
background: var(--primary-light);
color: white;
}
.notes-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 20px;
}
.note-card {
background: white;
border-radius: var(--radius);
padding: 20px;
box-shadow: var(--shadow);
transition: transform 0.3s, box-shadow 0.3s;
position: relative;
overflow: hidden;
}
.note-card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
}
.note-card.pinned::before {
content: '';
position: absolute;
top: 10px;
right: 10px;
width: 20px;
height: 20px;
background: var(--warning-color);
border-radius: 50%;
}
.note-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 10px;
}
.note-title {
font-size: 1.2rem;
font-weight: 600;
color: var(--primary-color);
margin-right: 10px;
word-break: break-word;
}
.note-category {
display: inline-block;
padding: 4px 8px;
border-radius: 20px;
font-size: 0.8rem;
font-weight: 500;
background: var(--secondary-color);
}
.note-content {
margin-bottom: 15px;
color: var(--text-color);
line-height: 1.5;
word-break: break-word;
}
.note-footer {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 15px;
padding-top: 15px;
border-top: 1px solid var(--border-color);
}
.note-date {
font-size: 0.8rem;
color: var(--text-light);
}
.note-actions {
display: flex;
gap: 8px;
}
.note-actions button {
background: none;
border: none;
cursor: pointer;
font-size: 1rem;
color: var(--text-light);
transition: color 0.3s;
padding: 5px;
}
.note-actions button:hover {
color: var(--primary-color);
}
.empty-state {
grid-column: 1 / -1;
text-align: center;
padding: 60px 20px;
color: var(--text-light);
}
.empty-state i {
font-size: 4rem;
margin-bottom: 20px;
color: var(--border-color);
}
.empty-state h3 {
font-size: 1.5rem;
margin-bottom: 10px;
}
.search-bar {
margin-bottom: 20px;
position: relative;
}
.search-bar input {
width: 100%;
padding: 12px 15px 12px 45px;
border: 1px solid var(--border-color);
border-radius: var(--radius);
font-size: 1rem;
transition: border-color 0.3s;
}
.search-bar input:focus {
outline: none;
border-color: var(--primary-color);
}
.search-bar i {
position: absolute;
left: 15px;
top: 50%;
transform: translateY(-50%);
color: var(--text-light);
}
.category-work { background: #e0f2fe; color: #0369a1; }
.category-personal { background: #f0fdf4; color: #15803d; }
.category-ideas { background: #fef7cd; color: #a16207; }
.category-todo { background: #fef2f2; color: #dc2626; }
.category-other { background: #f3f4f6; color: #4b5563; }
.stats {
display: flex;
justify-content: space-between;
margin-bottom: 20px;
padding: 15px;
background: white;
border-radius: var(--radius);
box-shadow: var(--shadow);
}
.stat-item {
text-align: center;
}
.stat-number {
font-size: 1.8rem;
font-weight: 700;
color: var(--primary-color);
}
.stat-label {
font-size: 0.9rem;
color: var(--text-light);
}
@media (max-width: 480px) {
.header {
flex-direction: column;
align-items: flex-start;
gap: 10px;
}
.notes-grid {
grid-template-columns: 1fr;
}
.stats {
flex-direction: column;
gap: 15px;
}
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1><i class="fas fa-sticky-note"></i> Notizblock App</h1>
<a href="https://huggingface.co/spaces/akhaliq/anycoder" class="anycoder">Built with anycoder</a>
</div>
<div class="app-container">
<div class="sidebar">
<div class="note-form">
<h2>Neue Notiz</h2>
<div class="form-group">
<label for="note-title">Titel</label>
<input type="text" id="note-title" placeholder="Titel der Notiz">
</div>
<div class="form-group">
<label for="note-content">Inhalt</label>
<textarea id="note-content" placeholder="Notizinhalt..."></textarea>
</div>
<div class="form-group">
<label for="note-category">Kategorie</label>
<select id="note-category">
<option value="personal">Persönlich</option>
<option value="work">Arbeit</option>
<option value="ideas">Ideen</option>
<option value="todo">Aufgaben</option>
<option value="other">Sonstiges</option>
</select>
</div>
<div class="form-group">
<label>
<input type="checkbox" id="note-pinned">
Notiz anheften
</label>
</div>
<button class="btn btn-primary btn-full" id="save-note">
<i class="fas fa-save"></i> Notiz speichern
</button>
</div>
<div class="filter-section">
<h3>Filter</h3>
<div class="filter-options">
<div class="filter-option active" data-filter="all">
<i class="fas fa-list"></i> Alle Notizen
</div>
<div class="filter-option" data-filter="personal">
<i class="fas fa-user"></i> Persönlich
</div>
<div class="filter-option" data-filter="work">
<i class="fas fa-briefcase"></i> Arbeit
</div>
<div class="filter-option" data-filter="ideas">
<i class="fas fa-lightbulb"></i> Ideen
</div>
<div class="filter-option" data-filter="todo">
<i class="fas fa-tasks"></i> Aufgaben
</div>
<div class="filter-option" data-filter="pinned">
<i class="fas fa-thumbtack"></i> Angeheftet
</div>
</div>
</div>
</div>
<div class="main-content">
<div class="search-bar">
<i class="fas fa-search"></i>
<input type="text" id="search-input" placeholder="Notizen durchsuchen...">
</div>
<div class="stats">
<div class="stat-item">
<div class="stat-number" id="total-notes">0</div>
<div class="stat-label">Notizen</div>
</div>
<div class="stat-item">
<div class="stat-number" id="pinned-notes">0</div>
<div class="stat-label">Angeheftet</div>
</div>
<div class="stat-item">
<div class="stat-number" id="categories-count">0</div>
<div class="stat-label">Kategorien</div>
</div>
</div>
<div class="notes-grid" id="notes-container">
<!-- Notizen werden hier dynamisch eingefügt -->
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Elemente referenzieren
const noteTitleInput = document.getElementById('note-title');
const noteContentInput = document.getElementById('note-content');
const noteCategorySelect = document.getElementById('note-category');
const notePinnedCheckbox = document.getElementById('note-pinned');
const saveNoteButton = document.getElementById('save-note');
const searchInput = document.getElementById('search-input');
const notesContainer = document.getElementById('notes-container');
const filterOptions = document.querySelectorAll('.filter-option');
const totalNotesElement = document.getElementById('total-notes');
const pinnedNotesElement = document.getElementById('pinned-notes');
const categoriesCountElement = document.getElementById('categories-count');
// Notizen aus dem localStorage laden oder leeres Array erstellen
let notes = JSON.parse(localStorage.getItem('notes')) || [];
let currentFilter = 'all';
let searchQuery = '';
// Funktion zum Speichern der Notizen im localStorage
function saveNotesToStorage() {
localStorage.setItem('notes', JSON.stringify(notes));
}
// Funktion zum Hinzufügen einer neuen Notiz
function addNote() {
const title = noteTitleInput.value.trim();
const content = noteContentInput.value.trim();
const category = noteCategorySelect.value;
const pinned = notePinnedCheckbox.checked;
const date = new Date().toLocaleDateString('de-DE');
if (title === '' || content === '') {
alert('Bitte geben Sie einen Titel und Inhalt für die Notiz ein.');
return;
}
const newNote = {
id: Date.now(),
title,
content,
category,
pinned,
date
};
notes.unshift(newNote);
saveNotesToStorage();
renderNotes();
// Formular zurücksetzen
noteTitleInput.value = '';
noteContentInput.value = '';
notePinnedCheckbox.checked = false;
}
// Funktion zum Löschen einer Notiz
function deleteNote(id) {
if (confirm('Möchten Sie diese Notiz wirklich löschen?')) {
notes = notes.filter(note => note.id !== id);
saveNotesToStorage();
renderNotes();
}
}
// Funktion zum Bearbeiten einer Notiz
function editNote(id) {
const note = notes.find(note => note.id === id);
if (note) {
noteTitleInput.value = note.title;
noteContentInput.value = note.content;
noteCategorySelect.value = note.category;
notePinnedCheckbox.checked = note.pinned;
// Nach dem Bearbeiten die Notiz löschen
deleteNote(id);
}
// Funktion zum Anheften/Abheften einer Notiz
function togglePin(id) {
const note = notes.find(note => note.id === id);
if (note) {
note.pinned = !note.pinned;
saveNotesToStorage();
renderNotes();
}
}
// Funktion zum Rendern der Notizen
function renderNotes() {
let filteredNotes = notes;
// Filter anwenden
if (currentFilter !== 'all') {
if (currentFilter === 'pinned') {
filteredNotes = notes.filter(note => note.pinned);
} else {
filteredNotes = notes.filter(note => note.category === currentFilter);
}
// Suche anwenden
if (searchQuery) {
const query = searchQuery.toLowerCase();
filteredNotes = filteredNotes.filter(note =>
note.title.toLowerCase().includes(query) ||
note.content.toLowerCase().includes(query)
);
}
// Statistik aktualisieren
updateStats();
// Notizen in den Container rendern
if (filteredNotes.length === 0) {
notesContainer.innerHTML = `
<div class="empty-state">
<i class="fas fa-sticky-note"></i>
<h3>Keine Notizen gefunden</h3>
<p>Erstellen Sie Ihre erste Notiz oder ändern Sie Ihre Filtereinstellungen.</p>
</div>
`;
return;
}
// Sortieren: Angeheftete Notizen zuerst, dann nach Datum (neueste zuerst)
filteredNotes.sort((a, b) => {
if (a.pinned && !b.pinned) return -1;
if (!a.pinned && b.pinned) return 1;
return b.id - a.id;
});
notesContainer.innerHTML = filteredNotes.map(note => `
<div class="note-card ${note.pinned ? 'pinned' : ''}">
<div class="note-header">
<div class="note-title">${note.title}</div>
<span class="note-category category-${note.category}">
${getCategoryLabel(note.category)}
</span>
</div>
<div class="note-content">${note.content}</div>
<div class="note-footer">
<div class="note-date">${note.date}</div>
<div class="note-actions">
<button onclick="togglePin(${note.id})" title="${note.pinned ? 'Abheften' : 'Anheften'}">
<i class="fas fa-thumbtack"></i>
</button>
<button onclick="editNote(${note.id})" title="Bearbeiten">
<i class="fas fa-edit"></i>
</button>
<button onclick="deleteNote(${note.id})" title="Löschen">
<i class="fas fa-trash"></i>
</button>
</div>
</div>
</div>
`).join('');
}
// Funktion zum Aktualisieren der Statistik
function updateStats() {
totalNotesElement.textContent = notes.length;
pinnedNotesElement.textContent = notes.filter(note => note.pinned).length;
const uniqueCategories = new Set(notes.map(note => note.category));
categoriesCountElement.textContent = uniqueCategories.size;
}
// Kategorielabel basierend auf Wert abrufen
function getCategoryLabel(category) {
const labels = {
'personal': 'Persönlich',
'work': 'Arbeit',
'ideas': 'Ideen',
'todo': 'Aufgaben',
'other': 'Sonstiges'
};
return labels[category] || 'Sonstiges';
}
// Event-Listener für das Speichern einer Notiz
saveNoteButton.addEventListener('click', addNote);
// Event-Listener für die Filteroptionen
filterOptions.forEach(option => {
option.addEventListener('click', function() {
// Aktive Klasse entfernen
filterOptions.forEach(opt => opt.classList.remove('active'));
// Aktive Klasse zur ausgewählten Option hinzufügen
this.classList.add('active');
// Filter aktualisieren
currentFilter = this.getAttribute('data-filter');
renderNotes();
});
});
// Event-Listener für die Suche
searchInput.addEventListener('input', function() {
searchQuery = this.value;
renderNotes();
});
// Funktionen global verfügbar machen
window.deleteNote = deleteNote;
window.editNote = editNote;
window.togglePin = togglePin;
// Beim Laden der Seite Notizen rendern
renderNotes();
});
</script>
</body>
</html>