初始化
This commit is contained in:
37
templates/base.html
Normal file
37
templates/base.html
Normal file
@@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>MoKeeText - Web 记事本</title>
|
||||
<link rel="stylesheet" href="/static/css/style.css">
|
||||
{% block head %}{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
<!-- 顶部导航 -->
|
||||
<nav class="topnav">
|
||||
<a href="/notes" class="topnav-brand">MoKeeText</a>
|
||||
<a href="/notes" class="topnav-link {% if active_page == 'notes' %}active{% endif %}">笔记</a>
|
||||
<a href="/websites" class="topnav-link {% if active_page == 'websites' %}active{% endif %}">网站管理</a>
|
||||
|
||||
<!-- 用户 Widget(后续接入) -->
|
||||
<div class="user-widget" title="用户">
|
||||
<span class="user-avatar">M</span>
|
||||
<span class="user-name">Admin</span>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- 主内容区 -->
|
||||
<div class="layout">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
|
||||
<!-- 底栏 -->
|
||||
<footer class="footer">
|
||||
<span>MoKeeText v1.0</span>
|
||||
<span class="footer-icp">ICP备案号:待接入</span>
|
||||
</footer>
|
||||
|
||||
{% block scripts %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
77
templates/notes.html
Normal file
77
templates/notes.html
Normal file
@@ -0,0 +1,77 @@
|
||||
{% extends "base.html" %}
|
||||
{% block head %}
|
||||
<script src="/static/js/vendor/tiptap-bundle.min.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<!-- 左侧边栏 -->
|
||||
<aside class="sidebar">
|
||||
<input class="input" type="text" placeholder="搜索笔记…" id="noteSearch">
|
||||
|
||||
<button class="btn btn-primary btn-block" onclick="createNote()">新建笔记</button>
|
||||
|
||||
<div class="sidebar-label">
|
||||
<span>文件夹</span>
|
||||
<span onclick="addFolder()" style="cursor:pointer; color:var(--brand); font-size:15px;" title="新建文件夹">+</span>
|
||||
</div>
|
||||
|
||||
<div style="overflow-y:auto; flex-shrink:1;">
|
||||
{% for folder in folders %}
|
||||
<div class="folder-item {% if loop.first %}active{% endif %}" data-folder-id="{{ folder.id }}"
|
||||
onclick="filterByFolder({{ folder.id }}, this)" style="position:relative;">
|
||||
<span>📂</span>
|
||||
<span style="flex:1;">{{ folder.name }}</span>
|
||||
<span class="count">{{ folder.notes|length }}</span>
|
||||
<span class="folder-more" onclick="event.stopPropagation();toggleFolderMenu(this)" title="更多">⋮</span>
|
||||
<div class="folder-menu hidden">
|
||||
<div class="folder-menu-item" onclick="renameFolder({{ folder.id }})">✏️ 重命名</div>
|
||||
<div class="folder-menu-item danger" onclick="deleteFolder({{ folder.id }})">🗑 删除</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<!-- 笔记列表 -->
|
||||
<div id="folderNoteList" class="hidden" style="flex:1; overflow-y:auto;"></div>
|
||||
|
||||
<div class="sidebar-label">标签</div>
|
||||
<div style="display:flex; flex-wrap:wrap; gap:4px;">
|
||||
{% for tag in tags %}
|
||||
<span class="tag-badge" onclick="filterByTag({{ tag.id }}, this)">{{ tag.name }}</span>
|
||||
{% endfor %}
|
||||
<span class="tag-badge tag-add" onclick="addTag()">+</span>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- 右侧编辑器 -->
|
||||
<section class="content">
|
||||
<div class="content-header">
|
||||
<input class="content-title" id="noteTitle" value="" placeholder="无标题笔记">
|
||||
<div class="toggle-group">
|
||||
<button class="active" data-mode="edit" onclick="setViewMode('edit')">编辑</button>
|
||||
<button data-mode="preview" onclick="setViewMode('preview')">预览</button>
|
||||
<button data-mode="split" onclick="setViewMode('split')">分屏</button>
|
||||
</div>
|
||||
<span class="save-badge" id="saveStatus">已保存</span>
|
||||
<button class="btn btn-danger-ghost btn-sm" onclick="deleteCurrentNote()">删除</button>
|
||||
</div>
|
||||
|
||||
<div class="editor-wrap" id="editorContainer">
|
||||
<div class="editor-pane" id="editPane">
|
||||
<div id="tiptapToolbar" class="tb-bar"></div>
|
||||
<div id="tiptapEditor"></div>
|
||||
</div>
|
||||
<div class="editor-pane hidden" id="previewPane">
|
||||
<div id="previewContent" style="font-size:14px; line-height:1.8;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<input type="hidden" id="currentNoteId" value="">
|
||||
{% if notes %}<input type="hidden" id="firstNoteId" value="{{ notes[0].id }}">{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script src="/static/js/editor.js"></script>
|
||||
<script src="/static/js/notes.js"></script>
|
||||
{% endblock %}
|
||||
198
templates/websites.html
Normal file
198
templates/websites.html
Normal file
@@ -0,0 +1,198 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<!-- 左侧边栏 -->
|
||||
<aside class="sidebar">
|
||||
<div class="stat-row">
|
||||
<div class="stat">
|
||||
<div class="stat-num" style="color:var(--brand);">{{ websites|length }}</div>
|
||||
<div class="stat-label">网站</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-num" style="color:var(--success);" id="accountCount">-</div>
|
||||
<div class="stat-label">账号</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-primary btn-block" onclick="showAddWebsite()">添加网站</button>
|
||||
<button class="btn btn-outline btn-block" onclick="showImportModal()">智能导入</button>
|
||||
|
||||
<div class="sidebar-label">
|
||||
<span>文件夹</span>
|
||||
<span onclick="showAddFolder()" style="cursor:pointer; color:var(--brand); font-size:15px;">+</span>
|
||||
</div>
|
||||
|
||||
<input class="input mb-sm" type="text" placeholder="搜索网站或网址…" id="siteSearch" oninput="filterSites()">
|
||||
|
||||
<div style="flex:1; overflow-y:auto;">
|
||||
{% for folder in folders %}
|
||||
<div class="folder-group" data-folder-id="{{ folder.id }}">
|
||||
<div class="folder-item" onclick="toggleFolder(this)" style="position:relative;">
|
||||
<span class="folder-arrow">▼</span>
|
||||
<span style="flex:1; font-weight:500;">📁 {{ folder.name }}</span>
|
||||
<span class="count">-</span>
|
||||
<span class="folder-more" onclick="event.stopPropagation();toggleFolderMenu(this)">⋮</span>
|
||||
<div class="folder-menu hidden">
|
||||
<div class="folder-menu-item" onclick="renameFolder({{ folder.id }})">✏️ 重命名</div>
|
||||
<div class="folder-menu-item danger" onclick="deleteFolder({{ folder.id }})">🗑 删除</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="folder-children">
|
||||
{% for site in websites if site.folder_id == folder.id %}
|
||||
<div class="site-item" data-site-id="{{ site.id }}" data-site-url="{{ site.url }}"
|
||||
onclick="selectWebsite({{ site.id }}, this)">
|
||||
<span>🌐</span>
|
||||
<span class="site-name">{{ site.name }}</span>
|
||||
<span class="site-count">{{ site.accounts|length }}个</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<!-- 未分类 -->
|
||||
<div class="sidebar-label">未分类</div>
|
||||
{% for site in websites if not site.folder_id %}
|
||||
<div class="site-item" data-site-id="{{ site.id }}" data-site-url="{{ site.url }}"
|
||||
onclick="selectWebsite({{ site.id }}, this)">
|
||||
<span>🌐</span>
|
||||
<span class="site-name">{{ site.name }}</span>
|
||||
<span class="site-count">{{ site.accounts|length }}个</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- 右侧网站详情 -->
|
||||
<section class="content">
|
||||
<div class="content-header">
|
||||
<div id="siteHeaderInfo" class="text-muted">选择左侧网站查看账号</div>
|
||||
<div style="display:flex; gap:6px;">
|
||||
<button class="btn btn-ghost btn-sm hidden" id="editSiteBtn" onclick="editWebsite()">✏️ 编辑</button>
|
||||
<button class="btn btn-outline btn-sm hidden" id="addAccountBtn" onclick="showAddAccount()">+ 添加账号</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="editor-pane" id="accountCards" style="flex:1;">
|
||||
<div style="text-align:center; padding:80px 20px; color:var(--text-placeholder);">
|
||||
<div style="font-size:48px; margin-bottom:16px; opacity:0.4;">🔐</div>
|
||||
<p>选择左侧网站查看账号密码</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ===== 智能导入弹窗 ===== -->
|
||||
<div class="modal-overlay hidden" id="importModal" onclick="if(event.target===this)hideImportModal()">
|
||||
<div class="modal" style="width:520px;">
|
||||
<div class="modal-header">
|
||||
<span class="modal-title">智能导入</span>
|
||||
<button class="modal-close" onclick="hideImportModal()">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label class="form-label">粘贴账号信息</label>
|
||||
<textarea class="import-textarea" id="importText"
|
||||
placeholder="https://github.com 代码网站 zhangsan@qq.com Abc123 个人开发账号"></textarea>
|
||||
<div class="import-hint">首行=网址+空格+网站名 | 第2行=账号 | 第3行=密码 | 第4行=备注</div>
|
||||
</div>
|
||||
<button class="btn btn-primary btn-block mb-md" onclick="parseImport()">🔍 自动识别</button>
|
||||
|
||||
<div class="result-box hidden" id="parseResult">
|
||||
<div style="font-weight:600; color:#166534; margin-bottom:10px;">识别结果</div>
|
||||
<div class="result-grid" id="parseGrid"></div>
|
||||
|
||||
<div class="form-group" style="margin-top:12px;">
|
||||
<label class="form-label">存放文件夹</label>
|
||||
<div class="form-row">
|
||||
<select class="select" id="importFolderSelect">
|
||||
<option value="">已有文件夹…</option>
|
||||
{% for folder in folders %}
|
||||
<option value="{{ folder.id }}">{{ folder.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<span class="text-muted">或</span>
|
||||
<input class="input" type="text" id="importNewFolder" placeholder="新建文件夹…">
|
||||
</div>
|
||||
</div>
|
||||
<div class="alert alert-warning hidden mb-md" id="duplicateAlert"></div>
|
||||
|
||||
<div class="modal-footer" style="padding:0; border:none;">
|
||||
<button class="btn btn-ghost" onclick="hideImportModal()">取消</button>
|
||||
<button class="btn btn-primary" onclick="confirmImport()">确认添加</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===== 网站弹窗 ===== -->
|
||||
<div class="modal-overlay hidden" id="websiteModal" onclick="if(event.target===this)hideWebsiteModal()">
|
||||
<div class="modal">
|
||||
<div class="modal-header">
|
||||
<span class="modal-title" id="websiteModalTitle">添加网站</span>
|
||||
<button class="modal-close" onclick="hideWebsiteModal()">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label class="form-label">网站名</label>
|
||||
<input class="input" id="websiteName" placeholder="例如:GitHub">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">网址</label>
|
||||
<input class="input" id="websiteUrl" placeholder="https://github.com">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">文件夹</label>
|
||||
<select class="select" id="websiteFolder">
|
||||
<option value="">未分类</option>
|
||||
{% for folder in folders %}
|
||||
<option value="{{ folder.id }}">{{ folder.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-ghost" onclick="hideWebsiteModal()">取消</button>
|
||||
<button class="btn btn-primary" onclick="saveWebsite()">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===== 账号弹窗 ===== -->
|
||||
<div class="modal-overlay hidden" id="accountModal" onclick="if(event.target===this)hideAccountModal()">
|
||||
<div class="modal">
|
||||
<div class="modal-header">
|
||||
<span class="modal-title" id="accountModalTitle">添加账号</span>
|
||||
<button class="modal-close" onclick="hideAccountModal()">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label class="form-label">账号 / 用户名</label>
|
||||
<input class="input" id="accountUsername" placeholder="user@example.com">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">密码</label>
|
||||
<div class="form-row">
|
||||
<input class="input" id="accountPassword" type="password" placeholder="输入密码" style="flex:1;">
|
||||
<button class="btn btn-ghost btn-sm" type="button" onclick="togglePwVisibility()">显示</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">备注</label>
|
||||
<textarea class="textarea" id="accountRemark" rows="2" placeholder="例如:主账号、小号…"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-ghost" onclick="hideAccountModal()">取消</button>
|
||||
<button class="btn btn-primary" onclick="saveAccount()">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" id="currentSiteId" value="">
|
||||
<input type="hidden" id="editWebsiteId" value="">
|
||||
<input type="hidden" id="editAccountId" value="">
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script src="/static/js/websites.js"></script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user