Merge branch 'style-foundation'
This commit is contained in:
commit
a9a7461aad
12 changed files with 727 additions and 78 deletions
527
public/css/app.css
Normal file
527
public/css/app.css
Normal file
|
|
@ -0,0 +1,527 @@
|
|||
/* =========================================================================
|
||||
Daily Goals - app.css
|
||||
Single shared stylesheet. Sectioned for readability.
|
||||
========================================================================= */
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
1. Reset
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
img,
|
||||
svg {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
button {
|
||||
font: inherit;
|
||||
color: inherit;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
input,
|
||||
textarea,
|
||||
select {
|
||||
font: inherit;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
2. Design tokens
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
:root {
|
||||
/* Color: warm, readable palette */
|
||||
--color-bg: #faf7f2;
|
||||
--color-surface: #ffffff;
|
||||
--color-surface-alt: #f3ede2;
|
||||
--color-text: #2b2622;
|
||||
--color-text-muted: #6b5d52;
|
||||
--color-primary: #5a7a4f;
|
||||
--color-primary-hover: #486340;
|
||||
--color-accent: #8a5a3b;
|
||||
--color-accent-hover: #6f4730;
|
||||
--color-border: #e3dccf;
|
||||
--color-border-strong: #c9bfae;
|
||||
--color-danger: #a94442;
|
||||
--color-success: #4f7a5a;
|
||||
|
||||
/* Typography */
|
||||
--font-serif: Georgia, "Iowan Old Style", "Source Serif Pro", serif;
|
||||
--font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui,
|
||||
sans-serif;
|
||||
--font-size-base: 1rem;
|
||||
--font-size-sm: 0.875rem;
|
||||
--font-size-lg: 1.125rem;
|
||||
--font-size-h1: 2rem;
|
||||
--font-size-h2: 1.5rem;
|
||||
--font-size-h3: 1.25rem;
|
||||
--line-height-base: 1.6;
|
||||
--line-height-tight: 1.25;
|
||||
|
||||
/* Spacing scale */
|
||||
--space-1: 0.25rem;
|
||||
--space-2: 0.5rem;
|
||||
--space-3: 0.75rem;
|
||||
--space-4: 1rem;
|
||||
--space-5: 1.5rem;
|
||||
--space-6: 2rem;
|
||||
--space-7: 3rem;
|
||||
|
||||
/* Layout */
|
||||
--max-width: 42rem;
|
||||
--max-width-wide: 60rem;
|
||||
|
||||
/* Radii */
|
||||
--radius-sm: 4px;
|
||||
--radius-md: 8px;
|
||||
--radius-lg: 12px;
|
||||
|
||||
/* Shadows */
|
||||
--shadow-sm: 0 1px 2px rgba(43, 38, 34, 0.06);
|
||||
--shadow-md: 0 4px 12px rgba(43, 38, 34, 0.1);
|
||||
--shadow-lg: 0 12px 32px rgba(43, 38, 34, 0.18);
|
||||
|
||||
/* Transitions */
|
||||
--transition-fast: 120ms ease;
|
||||
--transition-base: 200ms ease;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
3. Base elements
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
body {
|
||||
background-color: var(--color-bg);
|
||||
color: var(--color-text);
|
||||
font-family: var(--font-sans);
|
||||
font-size: var(--font-size-base);
|
||||
line-height: var(--line-height-base);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-rendering: optimizeLegibility;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-family: var(--font-serif);
|
||||
font-weight: 600;
|
||||
line-height: var(--line-height-tight);
|
||||
margin: 0;
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: var(--font-size-h1);
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: var(--font-size-h2);
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: var(--font-size-h3);
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--color-accent);
|
||||
text-decoration: none;
|
||||
transition: color var(--transition-fast);
|
||||
}
|
||||
|
||||
a:hover,
|
||||
a:focus {
|
||||
color: var(--color-accent-hover);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
font-size: var(--font-size-sm);
|
||||
color: var(--color-text-muted);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
input[type="text"],
|
||||
input[type="email"],
|
||||
input[type="password"],
|
||||
input[type="date"],
|
||||
input[type="number"],
|
||||
textarea,
|
||||
select {
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin-top: var(--space-1);
|
||||
padding: var(--space-2) var(--space-3);
|
||||
background-color: var(--color-surface);
|
||||
color: var(--color-text);
|
||||
border: 1px solid var(--color-border-strong);
|
||||
border-radius: var(--radius-sm);
|
||||
transition: border-color var(--transition-fast),
|
||||
box-shadow var(--transition-fast);
|
||||
}
|
||||
|
||||
input:focus,
|
||||
textarea:focus,
|
||||
select:focus {
|
||||
outline: none;
|
||||
border-color: var(--color-primary);
|
||||
box-shadow: 0 0 0 3px rgba(90, 122, 79, 0.15);
|
||||
}
|
||||
|
||||
button {
|
||||
display: inline-block;
|
||||
padding: var(--space-2) var(--space-4);
|
||||
background-color: var(--color-surface);
|
||||
color: var(--color-text);
|
||||
border: 1px solid var(--color-border-strong);
|
||||
border-radius: var(--radius-sm);
|
||||
font-weight: 500;
|
||||
transition: background-color var(--transition-fast),
|
||||
border-color var(--transition-fast), color var(--transition-fast);
|
||||
}
|
||||
|
||||
button:hover,
|
||||
button:focus {
|
||||
background-color: var(--color-surface-alt);
|
||||
border-color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
form {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
4. Layout primitives
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
max-width: var(--max-width);
|
||||
margin-inline: auto;
|
||||
padding: var(--space-5) var(--space-4);
|
||||
}
|
||||
|
||||
.container-wide {
|
||||
max-width: var(--max-width-wide);
|
||||
}
|
||||
|
||||
.stack > * + * {
|
||||
margin-top: var(--space-4);
|
||||
}
|
||||
|
||||
.stack-sm > * + * {
|
||||
margin-top: var(--space-2);
|
||||
}
|
||||
|
||||
.stack-lg > * + * {
|
||||
margin-top: var(--space-6);
|
||||
}
|
||||
|
||||
.cluster {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
|
||||
.cluster-end {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.cluster-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
5. Components
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
.site-header {
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
padding: var(--space-3) var(--space-4);
|
||||
background-color: var(--color-surface);
|
||||
}
|
||||
|
||||
.site-header .site-header-inner {
|
||||
width: 100%;
|
||||
max-width: var(--max-width);
|
||||
margin-inline: auto;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: inline-block;
|
||||
padding: var(--space-2) var(--space-4);
|
||||
border-radius: var(--radius-sm);
|
||||
border: 1px solid var(--color-border-strong);
|
||||
background-color: var(--color-surface);
|
||||
color: var(--color-text);
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
transition: background-color var(--transition-fast),
|
||||
border-color var(--transition-fast), color var(--transition-fast);
|
||||
}
|
||||
|
||||
.btn:hover,
|
||||
.btn:focus {
|
||||
background-color: var(--color-surface-alt);
|
||||
border-color: var(--color-text-muted);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: var(--color-primary);
|
||||
border-color: var(--color-primary);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.btn-primary:hover,
|
||||
.btn-primary:focus {
|
||||
background-color: var(--color-primary-hover);
|
||||
border-color: var(--color-primary-hover);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background-color: transparent;
|
||||
border-color: var(--color-border-strong);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.btn-danger {
|
||||
background-color: transparent;
|
||||
border-color: var(--color-danger);
|
||||
color: var(--color-danger);
|
||||
}
|
||||
|
||||
.btn-danger:hover,
|
||||
.btn-danger:focus {
|
||||
background-color: var(--color-danger);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.card {
|
||||
background-color: var(--color-surface);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-md);
|
||||
padding: var(--space-4);
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
.card-link {
|
||||
display: block;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
transition: border-color var(--transition-fast),
|
||||
box-shadow var(--transition-fast),
|
||||
transform var(--transition-fast);
|
||||
}
|
||||
|
||||
.card-link:hover,
|
||||
.card-link:focus {
|
||||
border-color: var(--color-border-strong);
|
||||
box-shadow: var(--shadow-md);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.list-cards {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
|
||||
.modal {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 50;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: var(--space-4);
|
||||
background-color: rgba(43, 38, 34, 0.45);
|
||||
}
|
||||
|
||||
.modal[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
width: 100%;
|
||||
max-width: 28rem;
|
||||
background-color: var(--color-surface);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-md);
|
||||
box-shadow: var(--shadow-lg);
|
||||
padding: var(--space-5);
|
||||
}
|
||||
|
||||
.error {
|
||||
color: var(--color-danger);
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
|
||||
.auth-shell {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: var(--space-5) var(--space-4);
|
||||
}
|
||||
|
||||
.auth-card {
|
||||
width: 100%;
|
||||
max-width: 24rem;
|
||||
background-color: var(--color-surface);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-md);
|
||||
box-shadow: var(--shadow-md);
|
||||
padding: var(--space-6);
|
||||
}
|
||||
|
||||
.muted {
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
6. Utilities
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
.full-width {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
7. Page-specific: node tree (text detail)
|
||||
-------------------------------------------------------------------------
|
||||
The tree DOM is rendered as plain ul/li with buttons and inputs as
|
||||
direct children of each li. Cypress assertions rely on this exact
|
||||
structure, so we style it via descendant selectors only - no wrapper
|
||||
elements added.
|
||||
*/
|
||||
|
||||
.node-tree > ul {
|
||||
border-left: 2px solid var(--color-border);
|
||||
padding-left: var(--space-4);
|
||||
}
|
||||
|
||||
.node-tree ul ul {
|
||||
border-left: 1px solid var(--color-border);
|
||||
margin-top: var(--space-2);
|
||||
margin-left: var(--space-2);
|
||||
padding-left: var(--space-4);
|
||||
}
|
||||
|
||||
.node-tree li {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: var(--space-2);
|
||||
padding: var(--space-2) 0;
|
||||
}
|
||||
|
||||
.node-tree li > ul {
|
||||
flex-basis: 100%;
|
||||
margin-top: var(--space-2);
|
||||
}
|
||||
|
||||
.node-tree li > span {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.node-tree li > button {
|
||||
padding: var(--space-1) var(--space-3);
|
||||
font-size: var(--font-size-sm);
|
||||
background-color: var(--color-surface);
|
||||
border: 1px solid var(--color-border-strong);
|
||||
border-radius: var(--radius-sm);
|
||||
}
|
||||
|
||||
.node-tree li > button.toggle-children {
|
||||
padding: var(--space-1) var(--space-2);
|
||||
background-color: transparent;
|
||||
border-color: transparent;
|
||||
color: var(--color-text-muted);
|
||||
font-size: var(--font-size-base);
|
||||
}
|
||||
|
||||
.node-tree li > button.toggle-children:hover,
|
||||
.node-tree li > button.toggle-children:focus {
|
||||
color: var(--color-text);
|
||||
background-color: var(--color-surface-alt);
|
||||
}
|
||||
|
||||
.node-tree li > button.add-child {
|
||||
color: var(--color-primary);
|
||||
border-color: var(--color-primary);
|
||||
}
|
||||
|
||||
.node-tree li > button.add-child:hover,
|
||||
.node-tree li > button.add-child:focus {
|
||||
background-color: var(--color-primary);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.node-tree li > button.bulk-add-children {
|
||||
color: var(--color-accent);
|
||||
border-color: var(--color-accent);
|
||||
}
|
||||
|
||||
.node-tree li > button.bulk-add-children:hover,
|
||||
.node-tree li > button.bulk-add-children:focus {
|
||||
background-color: var(--color-accent);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.node-tree li > input {
|
||||
width: auto;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.node-tree li > input.bulk-count {
|
||||
max-width: 6rem;
|
||||
}
|
||||
|
|
@ -9,9 +9,11 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
const texts = await response.json();
|
||||
textsList.innerHTML = texts
|
||||
.map(text =>
|
||||
'<li>' + text.name +
|
||||
' <button class="create-plan" data-text-id="' +
|
||||
text.id + '">Create plan</button></li>'
|
||||
'<li class="card cluster cluster-between">' +
|
||||
'<span class="text-name">' + text.name + '</span>' +
|
||||
'<button class="create-plan btn btn-primary"' +
|
||||
' data-text-id="' + text.id + '">Create plan</button>' +
|
||||
'</li>'
|
||||
)
|
||||
.join('');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
});
|
||||
const texts = await res.json();
|
||||
textsList.innerHTML = texts.map(text =>
|
||||
'<li><a href=/admin/texts/'
|
||||
'<li class="card"><a class="card-link"'
|
||||
+ ' href=/admin/texts/'
|
||||
+ text.id
|
||||
+ '>'
|
||||
+ text.name
|
||||
|
|
@ -26,7 +27,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
if (res.ok) {
|
||||
const text = await res.json();
|
||||
const li = document.createElement('li');
|
||||
li.className = 'card';
|
||||
const a = document.createElement('a');
|
||||
a.className = 'card-link';
|
||||
a.href = '/admin/texts/' + text.id;
|
||||
a.textContent = text.name;
|
||||
li.appendChild(a);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
const scheduledNodesList = document.getElementById(
|
||||
'scheduled-nodes-list'
|
||||
);
|
||||
const emptyMessage = document.getElementById('scheduled-nodes-empty');
|
||||
|
||||
function todayDateString() {
|
||||
const today = new Date();
|
||||
|
|
@ -23,10 +24,17 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
const scheduledNodes = await response.json();
|
||||
scheduledNodesList.innerHTML = scheduledNodes
|
||||
.map((scheduledNode) =>
|
||||
'<li>' + scheduledNode.planName + ': ' +
|
||||
scheduledNode.nodeTitle + '</li>'
|
||||
'<li class="card">' +
|
||||
'<span class="muted">' + scheduledNode.planName +
|
||||
'</span>: ' +
|
||||
'<span class="node-title">' + scheduledNode.nodeTitle +
|
||||
'</span>' +
|
||||
'</li>'
|
||||
)
|
||||
.join('');
|
||||
if (emptyMessage !== null) {
|
||||
emptyMessage.hidden = scheduledNodes.length > 0;
|
||||
}
|
||||
}
|
||||
|
||||
loadScheduledNodes();
|
||||
|
|
|
|||
|
|
@ -1,11 +1,29 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Daily Goals - Admin</title>
|
||||
<link rel="stylesheet" href="/css/app.css">
|
||||
</head>
|
||||
<body>
|
||||
<button id="logout">Logout</button>
|
||||
<a href="/admin/texts" id="texts">Texts</a>
|
||||
<header class="site-header">
|
||||
<div class="site-header-inner">
|
||||
<h1>Admin</h1>
|
||||
<div class="cluster">
|
||||
<button id="logout" class="btn btn-danger">Logout</button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<main class="container stack">
|
||||
<ul class="list-cards">
|
||||
<li class="card">
|
||||
<a id="texts" class="card-link" href="/admin/texts">
|
||||
Texts
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</main>
|
||||
<script src="/js/auth.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Daily Goals - Forbidden</title>
|
||||
<link rel="stylesheet" href="/css/app.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>403 Forbidden</h1>
|
||||
<p>You do not have permission to access this page.</p>
|
||||
<a href="/home">Back to Home</a>
|
||||
<main class="auth-shell">
|
||||
<div class="auth-card stack text-center">
|
||||
<h1>403 Forbidden</h1>
|
||||
<p class="muted">
|
||||
You do not have permission to access this page.
|
||||
</p>
|
||||
<a class="btn btn-primary" href="/home">Back to Home</a>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -1,27 +1,43 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Daily Goals - Home</title>
|
||||
<link rel="stylesheet" href="/css/app.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Home</h1>
|
||||
<button id="logout">Logout</button>
|
||||
<a href="/today">Today's schedule</a>
|
||||
<ul id="texts-list">
|
||||
</ul>
|
||||
<div id="create-plan-modal" hidden>
|
||||
<h2>Create plan</h2>
|
||||
<label>Name
|
||||
<input class="plan-name" type="text" />
|
||||
</label>
|
||||
<label>Start date
|
||||
<input class="plan-date-start" type="date" />
|
||||
</label>
|
||||
<label>End date
|
||||
<input class="plan-date-end" type="date" />
|
||||
</label>
|
||||
<button class="save-plan">Save</button>
|
||||
<button class="cancel-plan">Cancel</button>
|
||||
<header class="site-header">
|
||||
<div class="site-header-inner">
|
||||
<h1>Home</h1>
|
||||
<div class="cluster">
|
||||
<a class="btn btn-secondary" href="/today">
|
||||
Today's schedule
|
||||
</a>
|
||||
<button id="logout" class="btn btn-danger">Logout</button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<main class="container stack-lg">
|
||||
<ul id="texts-list" class="list-cards"></ul>
|
||||
</main>
|
||||
<div id="create-plan-modal" class="modal" hidden>
|
||||
<div class="modal-content stack">
|
||||
<h2>Create plan</h2>
|
||||
<label>Name
|
||||
<input class="plan-name" type="text" />
|
||||
</label>
|
||||
<label>Start date
|
||||
<input class="plan-date-start" type="date" />
|
||||
</label>
|
||||
<label>End date
|
||||
<input class="plan-date-end" type="date" />
|
||||
</label>
|
||||
<div class="cluster cluster-end">
|
||||
<button class="cancel-plan btn btn-secondary">Cancel</button>
|
||||
<button class="save-plan btn btn-primary">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/js/auth.js"></script>
|
||||
<script src="/js/home.js"></script>
|
||||
|
|
|
|||
|
|
@ -1,26 +1,37 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Daily Goals - Login</title>
|
||||
<link rel="stylesheet" href="/css/app.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Login</h1>
|
||||
<form id="login-form">
|
||||
<label>Email
|
||||
<input type="email" id="email" name="email" required />
|
||||
</label>
|
||||
<label>Password
|
||||
<input
|
||||
type="password"
|
||||
id="password"
|
||||
name="password"
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
<button type="submit">Login</button>
|
||||
</form>
|
||||
<p id="login-error" hidden></p>
|
||||
<p><a href="/register">Register</a></p>
|
||||
<main class="auth-shell">
|
||||
<div class="auth-card stack">
|
||||
<h1>Login</h1>
|
||||
<form id="login-form" class="stack">
|
||||
<label>Email
|
||||
<input type="email" id="email" name="email" required />
|
||||
</label>
|
||||
<label>Password
|
||||
<input
|
||||
type="password"
|
||||
id="password"
|
||||
name="password"
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
<button type="submit" class="btn btn-primary full-width">
|
||||
Login
|
||||
</button>
|
||||
</form>
|
||||
<p id="login-error" class="error" hidden></p>
|
||||
<p class="muted">
|
||||
<a href="/register">Need an account? Register</a>
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
<script src="/js/auth.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -1,27 +1,38 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Daily Goals - Register</title>
|
||||
<link rel="stylesheet" href="/css/app.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Register</h1>
|
||||
<form id="register-form">
|
||||
<label>Email
|
||||
<input type="email" id="email" name="email" required />
|
||||
</label>
|
||||
<label>Password (min 8 characters)
|
||||
<input
|
||||
type="password"
|
||||
id="password"
|
||||
name="password"
|
||||
minlength="8"
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
<button type="submit">Register</button>
|
||||
</form>
|
||||
<p id="register-error" hidden></p>
|
||||
<p><a href="/login">Already have an account? Login</a></p>
|
||||
<main class="auth-shell">
|
||||
<div class="auth-card stack">
|
||||
<h1>Register</h1>
|
||||
<form id="register-form" class="stack">
|
||||
<label>Email
|
||||
<input type="email" id="email" name="email" required />
|
||||
</label>
|
||||
<label>Password (min 8 characters)
|
||||
<input
|
||||
type="password"
|
||||
id="password"
|
||||
name="password"
|
||||
minlength="8"
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
<button type="submit" class="btn btn-primary full-width">
|
||||
Register
|
||||
</button>
|
||||
</form>
|
||||
<p id="register-error" class="error" hidden></p>
|
||||
<p class="muted">
|
||||
<a href="/login">Already have an account? Login</a>
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
<script src="/js/auth.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Daily Goals - Text</title>
|
||||
<link rel="stylesheet" href="/css/app.css">
|
||||
</head>
|
||||
<body>
|
||||
<a href="/admin/texts" id="back">Back to Texts</a>
|
||||
<div id="text-detail"></div>
|
||||
<header class="site-header">
|
||||
<div class="site-header-inner">
|
||||
<a class="btn btn-secondary" href="/admin/texts" id="back">
|
||||
Back to Texts
|
||||
</a>
|
||||
</div>
|
||||
</header>
|
||||
<main class="container container-wide stack">
|
||||
<div id="text-detail" class="node-tree stack"></div>
|
||||
</main>
|
||||
<script src="/js/text.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -1,17 +1,36 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Daily Goals - Texts</title>
|
||||
<link rel="stylesheet" href="/css/app.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Texts</h1>
|
||||
<a href="/admin" id="back">Back to Admin</a>
|
||||
<ul id="texts-list">
|
||||
</ul>
|
||||
<form id="texts-form" action="/api/texts" method="POST">
|
||||
<input id="newTextName" name="name"/>
|
||||
<button id="submit">submit</button>
|
||||
</form>
|
||||
<header class="site-header">
|
||||
<div class="site-header-inner">
|
||||
<h1>Texts</h1>
|
||||
<div class="cluster">
|
||||
<a class="btn btn-secondary" href="/admin" id="back">
|
||||
Back to Admin
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<main class="container stack-lg">
|
||||
<ul id="texts-list" class="list-cards"></ul>
|
||||
<form id="texts-form" action="/api/texts" method="POST"
|
||||
class="card stack">
|
||||
<label>New text name
|
||||
<input id="newTextName" name="name" type="text" />
|
||||
</label>
|
||||
<div class="cluster cluster-end">
|
||||
<button id="submit" class="btn btn-primary" type="submit">
|
||||
Add text
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</main>
|
||||
<script src="/js/texts.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,26 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Daily Goals - Today</title>
|
||||
<link rel="stylesheet" href="/css/app.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Today</h1>
|
||||
<ul id="scheduled-nodes-list">
|
||||
</ul>
|
||||
<header class="site-header">
|
||||
<div class="site-header-inner">
|
||||
<h1>Today</h1>
|
||||
<div class="cluster">
|
||||
<a class="btn btn-secondary" href="/home">Home</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<main class="container stack">
|
||||
<ul id="scheduled-nodes-list" class="list-cards"></ul>
|
||||
<p id="scheduled-nodes-empty" class="muted" hidden>
|
||||
Nothing scheduled for today.
|
||||
</p>
|
||||
</main>
|
||||
<script src="/js/auth.js"></script>
|
||||
<script src="/js/today.js"></script>
|
||||
</body>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue