1
0

refactor: refactor for modern layout

- split frontend and backend.
- update backend with modern Python dev strategies.
This commit is contained in:
2026-04-28 13:17:54 +08:00
parent 8e72e75a15
commit a0e3385670
65 changed files with 479 additions and 139 deletions

View File

@@ -0,0 +1,16 @@
{{for start=0 end=6 step=1 itemVar="~row"}}
<div>
{{for start=0 end=7 step=1 itemVar="~column"}}
<div id="ccn-calendarItem-{{:~row}}-{{:~column}}">
<p><b id="ccn-calendarItem-title-{{:~row}}-{{:~column}}">&nbsp;</b>
<span id="ccn-calendarItem-desc-{{:~row}}-{{:~column}}"></span>
</p>
<div id="ccn-calendarItem-eventBox1-{{:~row}}-{{:~column}}" class="calendarItem-eventBox" enableDisplay="false"></div>
<div id="ccn-calendarItem-eventBox2-{{:~row}}-{{:~column}}" class="calendarItem-eventBox" enableDisplay="false"></div>
<div id="ccn-calendarItem-eventBox3-{{:~row}}-{{:~column}}" class="calendarItem-eventBox" enableDisplay="false"></div>
<div id="ccn-calendarItem-eventBox4-{{:~row}}-{{:~column}}" class="calendarItem-eventBox" enableDisplay="false"></div>
<p id="ccn-calendarItem-task-{{:~row}}-{{:~column}}">&nbsp;</p>
</div>
{{/for}}
</div>
{{/for}}

View File

@@ -0,0 +1,200 @@
<div id="ccn-datetimepicker-modal" class="modal" style="float: left; position: fixed; top: 0; bottom: 0; left: 0; right: 0;">
<div class="modal-background"></div>
<div class="modal-card" style="height: 70%;">
<header class="modal-card-head pickerHeader">
<div type="year"><small i18n-name="ccn-i18n-universal-text-year"></small><span id="ccn-datetimepicker-datetime-year">&nbsp;</span></div>
<div type="month"><small i18n-name="ccn-i18n-universal-text-month"></small><span id="ccn-datetimepicker-datetime-month">&nbsp;</span></div>
<div type="day"><small i18n-name="ccn-i18n-universal-text-day"></small><span id="ccn-datetimepicker-datetime-day">&nbsp;</span></div>
<div type="hour"><small i18n-name="ccn-i18n-universal-text-hour"></small><span id="ccn-datetimepicker-datetime-hour">&nbsp;</span></div>
<div type="minute"><small i18n-name="ccn-i18n-universal-text-minute"></small><span id="ccn-datetimepicker-datetime-minute">&nbsp;</span></div>
</header>
<div class="modal-card-body pickerContainer">
<div id="ccn-datetimepicker-panelYear">
<nav class="level is-mobile">
<div class="level-left">
<div class="level-item control">
<a id="ccn-datetimepiacker-panelYear-prevBtn" class="button">
<span class="icon is-small"><i class="fas fa-chevron-circle-left"></i></span>
</a>
</div>
</div>
<div id="ccn-datetimepiacker-panelYear-title" class="level-item"></div>
<div class="level-right">
<div class="level-item control">
<a id="ccn-datetimepiacker-panelYear-nextBtn" class="button">
<span class="icon is-small"><i class="fas fa-chevron-circle-right"></i></span>
</a>
</div>
</div>
</nav>
<div id="ccn-datetimepiacker-panelYear-table" class="perfectTable">
<div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
</div>
<div id="ccn-datetimepicker-panelMonth">
<nav class="level is-mobile">
<div class="level-left">
<div class="level-item control">
<a id="ccn-datetimepiacker-panelMonth-prevBtn" class="button">
<span class="icon is-small"><i class="fas fa-chevron-circle-left"></i></span>
</a>
</div>
</div>
<div id="ccn-datetimepiacker-panelMonth-title" class="level-item"></div>
<div class="level-right">
<div class="level-item control">
<a id="ccn-datetimepiacker-panelMonth-nextBtn" class="button">
<span class="icon is-small"><i class="fas fa-chevron-circle-right"></i></span>
</a>
</div>
</div>
</nav>
<div id="ccn-datetimepiacker-panelMonth-table" class="perfectTable">
<div>
<div i18n-name="ccn-i18n-universal-month-1"></div>
<div i18n-name="ccn-i18n-universal-month-2"></div>
<div i18n-name="ccn-i18n-universal-month-3"></div>
<div i18n-name="ccn-i18n-universal-month-4"></div>
</div>
<div>
<div i18n-name="ccn-i18n-universal-month-5"></div>
<div i18n-name="ccn-i18n-universal-month-6"></div>
<div i18n-name="ccn-i18n-universal-month-7"></div>
<div i18n-name="ccn-i18n-universal-month-8"></div>
</div>
<div>
<div i18n-name="ccn-i18n-universal-month-9"></div>
<div i18n-name="ccn-i18n-universal-month-10"></div>
<div i18n-name="ccn-i18n-universal-month-11"></div>
<div i18n-name="ccn-i18n-universal-month-12"></div>
</div>
</div>
</div>
<div id="ccn-datetimepicker-panelDay">
<nav class="level is-mobile">
<div class="level-left">
<div class="level-item control">
<a id="ccn-datetimepiacker-panelDay-prevBtn" class="button">
<span class="icon is-small"><i class="fas fa-chevron-circle-left"></i></span>
</a>
</div>
</div>
<div id="ccn-datetimepiacker-panelDay-title" class="level-item"></div>
<div class="level-right">
<div class="level-item control">
<a id="ccn-datetimepiacker-panelDay-nextBtn" class="button">
<span class="icon is-small"><i class="fas fa-chevron-circle-right"></i></span>
</a>
</div>
</div>
</nav>
<div id="ccn-datetimepiacker-panelDay-table" class="perfectTable">
<div>
<div i18n-name="ccn-i18n-universal-week-1"></div>
<div i18n-name="ccn-i18n-universal-week-2"></div>
<div i18n-name="ccn-i18n-universal-week-3"></div>
<div i18n-name="ccn-i18n-universal-week-4"></div>
<div i18n-name="ccn-i18n-universal-week-5"></div>
<div i18n-name="ccn-i18n-universal-week-6"></div>
<div i18n-name="ccn-i18n-universal-week-7"></div>
</div>
<div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</div>
<div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</div>
<div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</div>
<div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</div>
<div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</div>
<div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</div>
</div>
</div>
<svg id="ccn-datetimepicker-panelHour" xmlns="http://www.w3.org/2000/svg" version="1.1" preserveAspectRatio="xMidYMid" viewBox="0 0 200 200">
<circle cx="100.000000" cy="100.000000" r="100.000000" type="background"></circle>
<line x1="100" y1="100" x2="100.000000" y2="20.000000"></line>
<circle cx="100.000000" cy="20.000000" r="1em" type="symbol"></circle>
<text x="100.000000" y="20.000000">0</text>
<text x="140.000000" y="30.717968">1</text>
<text x="169.282032" y="60.000000">2</text>
<text x="180.000000" y="100.000000">3</text>
<text x="169.282032" y="140.000000">4</text>
<text x="140.000000" y="169.282032">5</text>
<text x="100.000000" y="180.000000">6</text>
<text x="60.000000" y="169.282032">7</text>
<text x="30.717968" y="140.000000">8</text>
<text x="20.000000" y="100.000000">9</text>
<text x="30.717968" y="60.000000">10</text>
<text x="60.000000" y="30.717968">11</text>
<text x="100.000000" y="40.000000">12</text>
<text x="130.000000" y="48.038476">13</text>
<text x="151.961524" y="70.000000">14</text>
<text x="160.000000" y="100.000000">15</text>
<text x="151.961524" y="130.000000">16</text>
<text x="130.000000" y="151.961524">17</text>
<text x="100.000000" y="160.000000">18</text>
<text x="70.000000" y="151.961524">19</text>
<text x="48.038476" y="130.000000">20</text>
<text x="40.000000" y="100.000000">21</text>
<text x="48.038476" y="70.000000">22</text>
<text x="70.000000" y="48.038476">23</text>
</svg>
<svg id="ccn-datetimepicker-panelMinute" xmlns="http://www.w3.org/2000/svg" version="1.1" preserveAspectRatio="xMidYMid" viewBox="0 0 200 200">
<circle cx="100.000000" cy="100.000000" r="100.000000" type="background"></circle>
<line x1="100" y1="100" x2="100.000000" y2="20.000000"></line>
<circle cx="100.000000" cy="20.000000" r="1em" type="symbol"></circle>
<text x="100.000000" y="20.000000">0</text>
<text x="140.000000" y="30.717968">5</text>
<text x="169.282032" y="60.000000">10</text>
<text x="180.000000" y="100.000000">15</text>
<text x="169.282032" y="140.000000">20</text>
<text x="140.000000" y="169.282032">25</text>
<text x="100.000000" y="180.000000">30</text>
<text x="60.000000" y="169.282032">35</text>
<text x="30.717968" y="140.000000">40</text>
<text x="20.000000" y="100.000000">45</text>
<text x="30.717968" y="60.000000">50</text>
<text x="60.000000" y="30.717968">55</text>
</svg>
</div>
<footer class="modal-card-foot">
<a id="ccn-datetimepicker-btnConfirm" class="button is-success">
<span i18n-name="ccn-i18n-datetimepicker-confirm"></span>
</a>
<a id="ccn-datetimepicker-btnCancel" class="button">
<span i18n-name="ccn-i18n-datetimepicker-cancel"></span>
</a>
</footer>
</div>
</div>

View File

@@ -0,0 +1,12 @@
<div id="ccn-displayOwnedItem-{{:uuid}}" class="collection-item card">
<div class="collection-item-words">
<p>{{>name}}</p>
</div>
<div id="ccn-displayOwnedItem-btnHide-{{:uuid}}" uuid="{{:uuid}}" class="collection-item-icon control">
<a class="button"><span class="icon is-small"><i class="fas fa-eye"></i></span></a>
</div>
<div id="ccn-displayOwnedItem-btnShow-{{:uuid}}" uuid="{{:uuid}}" class="collection-item-icon control">
<a class="button"><span class="icon is-small"><i class="fas fa-eye-slash"></i></span></a>
</div>
</div>

View File

@@ -0,0 +1,16 @@
<div id="ccn-displaySharedItem-{{:uuid}}" class="collection-item card">
<div class="collection-item-words">
<b>{{>name}}</b>
<p>
<span i18n-name="ccn-i18n-sharedItem-sharedBy"></span>
<span>{{>username}}</span>
</p>
</div>
<div id="ccn-displaySharedItem-btnHide-{{:uuid}}" uuid="{{:uuid}}" class="collection-item-icon control">
<a class="button"><span class="icon is-small"><i class="fas fa-eye"></i></span></a>
</div>
<div id="ccn-displaySharedItem-btnShow-{{:uuid}}" uuid="{{:uuid}}" class="collection-item-icon control">
<a class="button"><span class="icon is-small"><i class="fas fa-eye-slash"></i></span></a>
</div>
</div>

View File

@@ -0,0 +1,42 @@
<nav class="navbar has-shadow is-spaced bd-navbar" role="navigation" aria-label="main navigation">
<div class="navbar-brand">
<a class="navbar-item" href="home">
<img src="/static/image/icon.png"><b style="margin:0 0 0 14px;">coconut-leaf</b>
</a>
<a role="button" class="navbar-burger burger" aria-label="menu" aria-expanded="false"
data-target="navbarBasicExample">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div>
<div id="navbarBasicExample" class="navbar-menu">
<div class="navbar-start">
<a i18n-name="ccn-i18n-header-nav-home" id="ccn-header-nav-home" class="navbar-item" href="/web/home"></a>
<a i18n-name="ccn-i18n-header-nav-collection" id="ccn-header-nav-collection" class="navbar-item" href="/web/collection"></a>
<a i18n-name="ccn-i18n-header-nav-calendar" id="ccn-header-nav-calendar" class="navbar-item" href="/web/calendar"></a>
<a i18n-name="ccn-i18n-header-nav-todo" id="ccn-header-nav-todo" class="navbar-item" href="/web/todo"></a>
<a i18n-name="ccn-i18n-header-nav-admin" id="ccn-header-nav-admin" class="navbar-item" href="/web/admin"></a>
</div>
<div class="navbar-end">
<p id="ccn-header-user-login" class="navbar-item">
<a class="button is-primary" i18n-name="ccn-i18n-header-user-login" href="/web/login"></a>
</p>
<p id="ccn-header-user-logout" class="navbar-item">
<a class="button is-primary" i18n-name="ccn-i18n-header-user-logout"></a>
</p>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" i18n-name="ccn-i18n-header-language"></a>
<div id="ccn-header-language" class="navbar-dropdown">
<a language="en-US" class="navbar-item">English</a>
<a language="zh-CN" class="navbar-item">简体中文</a>
</div>
</div>
</div>
</div>
</nav>

View File

@@ -0,0 +1,15 @@
<div id="ccn-messagebox-modal" class="modal" style="float: left; position: fixed; top: 0; bottom: 0; left: 0; right: 0;">
<div class="modal-background"></div>
<div class="modal-card">
<header class="modal-card-head">
<p id="ccn-messagebox-title" class="modal-card-title" i18n-name="ccn-i18n-messagebox-title"></p>
<button id="ccn-messagebox-btnClose" class="delete" aria-label="close"></button>
</header>
<div class="modal-card-body">
<p id="ccn-messagebox-body"></p>
</div>
<footer class="modal-card-foot">
<button id="ccn-messagebox-btnConfirm" class="button is-success" i18n-name="ccn-i18n-messagebox-confirm"></button>
</footer>
</div>
</div>

View File

@@ -0,0 +1 @@
<option value="{{:val}}">{{>name}}</option>

View File

@@ -0,0 +1,24 @@
<div id="ccn-ownedItem-{{:uuid}}" class="collection-item card">
<div class="collection-item-words">
<p id="ccn-ownedItem-textName-{{:uuid}}">{{>name}}</p>
<div id="ccn-ownedItem-boxName-{{:uuid}}" class="control">
<input id="ccn-ownedItem-inputName-{{:uuid}}" class="input" type="text"></input>
</div>
</div>
<div id="ccn-ownedItem-btnEdit-{{:uuid}}" uuid="{{:uuid}}" class="collection-item-icon control">
<a class="button"><span class="icon is-small"><i class="fas fa-pen"></i></span></a>
</div>
<div id="ccn-ownedItem-btnShare-{{:uuid}}" uuid="{{:uuid}}" class="collection-item-icon control">
<a class="button"><span class="icon is-small"><i class="fas fa-share"></i></a>
</div>
<div id="ccn-ownedItem-btnDelete-{{:uuid}}" uuid="{{:uuid}}" class="collection-item-icon control">
<a class="button"><span class="icon is-small"><i class="fas fa-trash"></i></a>
</div>
<div id="ccn-ownedItem-btnUpdate-{{:uuid}}" uuid="{{:uuid}}" class="collection-item-icon control">
<button class="button"><span class="icon is-small"><i class="fas fa-check"></i></span></button>
</div>
<div id="ccn-ownedItem-btnCancelUpdate-{{:uuid}}" uuid="{{:uuid}}" class="collection-item-icon control">
<button class="button"><span class="icon is-small"><i class="fas fa-times"></i></button>
</div>
</div>

View File

@@ -0,0 +1,36 @@
{{for renderdata}}
<div class="schedule-day container">
<div class="schedule-day-words">
<b i18n-name="ccn-i18n-universal-month-{{:month}}"></b>
<b>{{>day}}</b>
<b i18n-name="ccn-i18n-universal-week-{{:dayOfWeek}}"></b>
</div>
<div class="schedule-event-list">
{{for events}}
{{if isVisible}}
<div class="schedule-event-outter card" uuid="{{:uuid}}">
<div class="schedule-event-color" style="background: {{:color}};"></div>
<div class="schedule-event-inner">
<div class="schedule-event-words">
<p class="level-item"><b>{{>title}}</b></p>
<p class="level-item">{{>description}}</p>
<p class="level-item"><span>{{>start}}</span>-<span>{{>end}}</span></p>
{{if loopText != ""}}
<p><span class="icon is-small"><i class="fas fa-retweet"></i></span><span>{{>loopText}}</span></p>
{{/if}}
</div>
<div class="schedule-event-icon">
{{if isLocked}}
<span class="icon is-small"><i class="fas fa-lock"></i></span>
{{/if}}
{{if timezoneWarning}}
<span class="icon is-small"><i class="fas fa-globe"></i></span>
{{/if}}
</div>
</div>
</div>
{{/if}}
{{/for}}
</div>
</div>
{{/for}}

View File

@@ -0,0 +1,9 @@
<div id="ccn-sharingItem-{{:uuid}}" class="collection-item card">
<div class="collection-item-words">
<p>{{>username}}</p>
</div>
<div id="ccn-sharingItem-btnDelete-{{:uuid}}" uuid="{{:uuid}}" class="collection-item-icon control">
<a class="button"><span class="icon is-small"><i class="fas fa-trash"></i></span></a>
</div>
</div>

View File

@@ -0,0 +1,20 @@
<div id="ccn-todoItem-{{:uuid}}" class="todo-item card">
<div class="todo-item-words">
<p id="ccn-todoItem-p-{{:uuid}}">{{:data}}</p>
<textarea id="ccn-todoItem-textarea-{{:uuid}}" class="textarea"></textarea>
</div>
<div id="ccn-todoItem-btnEdit-{{:uuid}}" uuid="{{:uuid}}" class="todo-item-icon control">
<button class="button"><span class="icon is-small"><i class="fas fa-pen"></i></span></button>
</div>
<div id="ccn-todoItem-btnDelete-{{:uuid}}" uuid="{{:uuid}}" class="todo-item-icon control">
<button class="button"><span class="icon is-small"><i class="fas fa-trash"></i></button>
</div>
<div id="ccn-todoItem-btnUpdate-{{:uuid}}" uuid="{{:uuid}}" class="todo-item-icon control">
<button class="button"><span class="icon is-small"><i class="fas fa-check"></i></span></button>
</div>
<div id="ccn-todoItem-btnCancelUpdate-{{:uuid}}" uuid="{{:uuid}}" class="todo-item-icon control">
<button class="button"><span class="icon is-small"><i class="fas fa-times"></i></button>
</div>
</div>

View File

@@ -0,0 +1,27 @@
<div id="ccn-tokenItem-{{:uuid}}" class="token-item card">
<div class="token-item-words">
<b>{{>uuid}}</b>
<p>
<span i18n-name="ccn-i18n-tokenItem-ua"></span>
<span>{{>ua}}</span>
</p>
<p>
<span i18n-name="ccn-i18n-tokenItem-ip"></span>
<span>{{>ip}}</span>
</p>
<p>
<span i18n-name="ccn-i18n-tokenItem-expireOn"></span>
<span>{{>expireOn}}</span>
</p>
{{if isMe}}
<p>
<span class="icon is-small"><i class="fas fa-exclamation-triangle"></i></span>
<span i18n-name="ccn-i18n-tokenItem-isMe"></span>
</p>
{{/if}}
</div>
<div id="ccn-tokenItem-btnLogout-{{:uuid}}" uuid="{{:uuid}}" class="token-item-icon control">
<a class="button"><span class="icon is-small"><i class="fas fa-sign-out-alt"></i></span></a>
</div>
</div>

View File

@@ -0,0 +1,35 @@
<div id="ccn-userItem-{{:uuid}}" class="user-item card">
<div class="user-item-words">
<div class="control" style="display: flex; flex-flow: row; align-items: center;">
<div id="ccn-userItem-iconIsAdmin-{{:uuid}}" class="icon is-small" style="margin-right: 1rem;">
<i class="fas fa-wrench"></i>
</div>
<div id="ccn-userItem-textName-{{:uuid}}">{{>username}}</div>
</div>
<div id="ccn-userItem-boxPassword-{{:uuid}}" class="field">
<label class="label" i18n-name="ccn-i18n-userItem-newPassword"></label>
<div class="control">
<input id="ccn-userItem-inputPassword-{{:uuid}}" class="input" type="password"></input>
</div>
</div>
<div id="ccn-userItem-boxIsAdmin-{{:uuid}}" class="field">
<label class="checkbox">
<input id="ccn-userItem-inputIsAdmin-{{:uuid}}" type="checkbox"><span i18n-name="ccn-i18n-userItem-isAdmin"></span>
</label>
</div>
</div>
<div id="ccn-userItem-btnEdit-{{:uuid}}" uuid="{{:uuid}}" class="user-item-icon control">
<a class="button"><span class="icon is-small"><i class="fas fa-pen"></i></span></a>
</div>
<div id="ccn-userItem-btnDelete-{{:uuid}}" uuid="{{:uuid}}" class="user-item-icon control">
<a class="button"><span class="icon is-small"><i class="fas fa-trash"></i></span></a>
</div>
<div id="ccn-userItem-btnUpdate-{{:uuid}}" uuid="{{:uuid}}" class="user-item-icon control">
<a class="button"><span class="icon is-small"><i class="fas fa-check"></i></span></a>
</div>
<div id="ccn-userItem-btnCancelUpdate-{{:uuid}}" uuid="{{:uuid}}" class="user-item-icon control">
<a class="button"><span class="icon is-small"><i class="fas fa-times"></i></span></a>
</div>
</div>