feat: Add Projects and Folders UI (SimpleNote v2)

- New Projects view (projects.js): Lists all projects with cards
- New ProjectView (projectView.js): Project dashboard with folder tree
- Updated API client: Projects and Folders CRUD methods
- New modals: NewProjectModal, NewFolderModal, MoveToFolderModal
- Edit/Delete project functionality
- Updated navigation: ProjectList -> ProjectView -> FolderView
- Consistent dark theme styling

Changes:
- public/js/views/projects.js (NEW)
- public/js/views/projectView.js (NEW)
- public/js/api.js (added Projects/Folders API methods)
- public/js/app.js (added navigation routes)
- public/js/components/sidebar.js (added Projects link)
- public/css/style.css (added project/folder styles)
This commit is contained in:
Hiro
2026-03-28 13:03:23 +00:00
parent d7bb018c83
commit 9496fc8e36
6 changed files with 995 additions and 6 deletions

View File

@@ -2,6 +2,8 @@
import { api } from './api.js';
import { renderLogin, initLoginHandlers } from './views/login.js';
import { renderProjects } from './views/projects.js';
import { renderProjectView } from './views/projectView.js';
import { renderDashboard } from './views/dashboard.js';
import { renderDocument } from './views/document.js';
import { renderEditor } from './views/editor.js';
@@ -11,7 +13,7 @@ class App {
this.currentView = null;
this.state = {
token: localStorage.getItem('sn_token'),
view: 'dashboard',
view: 'projects', // Default to projects view
params: {}
};
}
@@ -41,7 +43,7 @@ class App {
try {
await api.login(token);
this.state.token = token;
this.state.view = 'dashboard';
this.state.view = 'projects';
this.render();
} catch (e) {
return 'Invalid token';
@@ -53,6 +55,12 @@ class App {
const app = document.getElementById('app');
switch (this.state.view) {
case 'projects':
await renderProjects(this);
break;
case 'project':
await renderProjectView(this);
break;
case 'dashboard':
await renderDashboard(this);
break;
@@ -63,7 +71,7 @@ class App {
renderEditor(this);
break;
default:
await renderDashboard(this);
await renderProjects(this);
}
}
@@ -139,10 +147,14 @@ app.init();
// Keyboard shortcuts
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && window.app.state.view === 'editor') {
window.app.navigate('dashboard');
window.app.navigate('project', { id: window.app.state.params.projectId });
}
if ((e.ctrlKey || e.metaKey) && e.key === 'n' && window.app.state.view === 'dashboard') {
if ((e.ctrlKey || e.metaKey) && e.key === 'n' && (window.app.state.view === 'projects' || window.app.state.view === 'project')) {
e.preventDefault();
window.showNewDocModal();
if (window.app.state.view === 'project') {
window.showNewDocModal(window.app.state.params.id, '');
} else {
window.showNewProjectModal();
}
}
});