|
|
|
@@ -0,0 +1,776 @@ |
|
|
|
<!doctype html> |
|
|
|
<html lang="en"> |
|
|
|
<head> |
|
|
|
<meta charset="utf-8"> |
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1"> |
|
|
|
<title>Time Management Planner</title> |
|
|
|
<style> |
|
|
|
:root { |
|
|
|
--ink: #202124; |
|
|
|
--muted: #5f6368; |
|
|
|
--line: #d8dde3; |
|
|
|
--page: #f6f7f9; |
|
|
|
--panel: #ffffff; |
|
|
|
--teal: #176b5d; |
|
|
|
--blue: #2f5f98; |
|
|
|
--coral: #b75542; |
|
|
|
--gold: #8a6500; |
|
|
|
--green: #4d7653; |
|
|
|
--violet: #7b5aa6; |
|
|
|
--shadow: 0 10px 28px rgba(32, 33, 36, 0.08); |
|
|
|
--radius: 8px; |
|
|
|
--space: clamp(14px, 2vw, 22px); |
|
|
|
font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; |
|
|
|
color: var(--ink); |
|
|
|
background: var(--page); |
|
|
|
} |
|
|
|
|
|
|
|
* { |
|
|
|
box-sizing: border-box; |
|
|
|
} |
|
|
|
|
|
|
|
body { |
|
|
|
margin: 0; |
|
|
|
min-width: 320px; |
|
|
|
background: |
|
|
|
linear-gradient(180deg, rgba(237, 244, 242, 0.9), rgba(246, 247, 249, 0.2) 280px), |
|
|
|
var(--page); |
|
|
|
} |
|
|
|
|
|
|
|
button, |
|
|
|
input, |
|
|
|
textarea { |
|
|
|
font: inherit; |
|
|
|
} |
|
|
|
|
|
|
|
.shell { |
|
|
|
max-width: 1180px; |
|
|
|
margin: 0 auto; |
|
|
|
padding: 24px var(--space) 48px; |
|
|
|
} |
|
|
|
|
|
|
|
.topbar { |
|
|
|
display: flex; |
|
|
|
align-items: flex-start; |
|
|
|
justify-content: space-between; |
|
|
|
gap: 16px; |
|
|
|
margin-bottom: 20px; |
|
|
|
} |
|
|
|
|
|
|
|
h1 { |
|
|
|
margin: 0 0 6px; |
|
|
|
font-size: 2rem; |
|
|
|
line-height: 1.08; |
|
|
|
letter-spacing: 0; |
|
|
|
} |
|
|
|
|
|
|
|
.subtitle { |
|
|
|
margin: 0; |
|
|
|
max-width: 780px; |
|
|
|
color: var(--muted); |
|
|
|
line-height: 1.45; |
|
|
|
} |
|
|
|
|
|
|
|
.toolbar { |
|
|
|
display: flex; |
|
|
|
gap: 8px; |
|
|
|
flex-wrap: wrap; |
|
|
|
justify-content: flex-end; |
|
|
|
min-width: 220px; |
|
|
|
} |
|
|
|
|
|
|
|
.button { |
|
|
|
min-height: 38px; |
|
|
|
border: 1px solid var(--line); |
|
|
|
border-radius: 6px; |
|
|
|
padding: 8px 12px; |
|
|
|
background: var(--panel); |
|
|
|
color: var(--ink); |
|
|
|
cursor: pointer; |
|
|
|
box-shadow: 0 1px 0 rgba(32, 33, 36, 0.04); |
|
|
|
} |
|
|
|
|
|
|
|
.button.primary { |
|
|
|
border-color: var(--teal); |
|
|
|
background: var(--teal); |
|
|
|
color: #fff; |
|
|
|
} |
|
|
|
|
|
|
|
.button:hover { |
|
|
|
filter: brightness(0.98); |
|
|
|
} |
|
|
|
|
|
|
|
.summary { |
|
|
|
display: grid; |
|
|
|
grid-template-columns: repeat(4, minmax(0, 1fr)); |
|
|
|
gap: 12px; |
|
|
|
margin: 18px 0 22px; |
|
|
|
} |
|
|
|
|
|
|
|
.metric { |
|
|
|
background: var(--panel); |
|
|
|
border: 1px solid var(--line); |
|
|
|
border-radius: var(--radius); |
|
|
|
padding: 14px; |
|
|
|
box-shadow: var(--shadow); |
|
|
|
min-height: 108px; |
|
|
|
} |
|
|
|
|
|
|
|
.metric strong { |
|
|
|
display: block; |
|
|
|
font-size: 1.55rem; |
|
|
|
line-height: 1.05; |
|
|
|
margin-bottom: 6px; |
|
|
|
} |
|
|
|
|
|
|
|
.metric span { |
|
|
|
color: var(--muted); |
|
|
|
line-height: 1.35; |
|
|
|
display: block; |
|
|
|
} |
|
|
|
|
|
|
|
.layout { |
|
|
|
display: grid; |
|
|
|
grid-template-columns: minmax(0, 1fr) 330px; |
|
|
|
gap: 18px; |
|
|
|
align-items: start; |
|
|
|
} |
|
|
|
|
|
|
|
.section { |
|
|
|
margin-bottom: 18px; |
|
|
|
} |
|
|
|
|
|
|
|
.section-head { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
justify-content: space-between; |
|
|
|
gap: 12px; |
|
|
|
margin-bottom: 10px; |
|
|
|
} |
|
|
|
|
|
|
|
h2 { |
|
|
|
margin: 0; |
|
|
|
font-size: 1.08rem; |
|
|
|
letter-spacing: 0; |
|
|
|
} |
|
|
|
|
|
|
|
.hint { |
|
|
|
color: var(--muted); |
|
|
|
font-size: 0.92rem; |
|
|
|
line-height: 1.35; |
|
|
|
margin: 0; |
|
|
|
} |
|
|
|
|
|
|
|
.week { |
|
|
|
display: grid; |
|
|
|
grid-template-columns: repeat(7, minmax(140px, 1fr)); |
|
|
|
gap: 10px; |
|
|
|
overflow-x: auto; |
|
|
|
padding-bottom: 4px; |
|
|
|
} |
|
|
|
|
|
|
|
.day { |
|
|
|
background: var(--panel); |
|
|
|
border: 1px solid var(--line); |
|
|
|
border-radius: var(--radius); |
|
|
|
min-height: 460px; |
|
|
|
box-shadow: var(--shadow); |
|
|
|
display: flex; |
|
|
|
flex-direction: column; |
|
|
|
} |
|
|
|
|
|
|
|
.day header { |
|
|
|
padding: 12px 12px 8px; |
|
|
|
border-bottom: 1px solid var(--line); |
|
|
|
min-height: 62px; |
|
|
|
} |
|
|
|
|
|
|
|
.day h3 { |
|
|
|
margin: 0 0 4px; |
|
|
|
font-size: 1rem; |
|
|
|
letter-spacing: 0; |
|
|
|
} |
|
|
|
|
|
|
|
.day .tone { |
|
|
|
color: var(--muted); |
|
|
|
font-size: 0.8rem; |
|
|
|
line-height: 1.25; |
|
|
|
} |
|
|
|
|
|
|
|
.items { |
|
|
|
display: flex; |
|
|
|
flex-direction: column; |
|
|
|
gap: 8px; |
|
|
|
padding: 10px; |
|
|
|
} |
|
|
|
|
|
|
|
.block { |
|
|
|
border-left: 4px solid var(--line); |
|
|
|
background: #fafbfc; |
|
|
|
border-radius: 6px; |
|
|
|
padding: 9px 9px 9px 10px; |
|
|
|
min-height: 58px; |
|
|
|
} |
|
|
|
|
|
|
|
.block.work { border-left-color: var(--blue); } |
|
|
|
.block.spiritual { border-left-color: var(--teal); } |
|
|
|
.block.health { border-left-color: var(--green); } |
|
|
|
.block.home { border-left-color: var(--gold); } |
|
|
|
.block.creative { border-left-color: var(--coral); } |
|
|
|
.block.relationship { border-left-color: var(--violet); } |
|
|
|
.block.rest { border-left-color: #6c737f; } |
|
|
|
|
|
|
|
.time { |
|
|
|
display: block; |
|
|
|
color: var(--muted); |
|
|
|
font-size: 0.78rem; |
|
|
|
line-height: 1.3; |
|
|
|
margin-bottom: 4px; |
|
|
|
} |
|
|
|
|
|
|
|
.task { |
|
|
|
display: block; |
|
|
|
font-weight: 650; |
|
|
|
line-height: 1.25; |
|
|
|
overflow-wrap: anywhere; |
|
|
|
} |
|
|
|
|
|
|
|
.note { |
|
|
|
display: block; |
|
|
|
color: var(--muted); |
|
|
|
font-size: 0.82rem; |
|
|
|
line-height: 1.35; |
|
|
|
margin-top: 3px; |
|
|
|
overflow-wrap: anywhere; |
|
|
|
} |
|
|
|
|
|
|
|
.panel { |
|
|
|
background: var(--panel); |
|
|
|
border: 1px solid var(--line); |
|
|
|
border-radius: var(--radius); |
|
|
|
box-shadow: var(--shadow); |
|
|
|
padding: 14px; |
|
|
|
} |
|
|
|
|
|
|
|
.panel + .panel { |
|
|
|
margin-top: 14px; |
|
|
|
} |
|
|
|
|
|
|
|
.checklist { |
|
|
|
display: grid; |
|
|
|
gap: 8px; |
|
|
|
margin-top: 10px; |
|
|
|
} |
|
|
|
|
|
|
|
.check { |
|
|
|
display: grid; |
|
|
|
grid-template-columns: 22px minmax(0, 1fr); |
|
|
|
gap: 8px; |
|
|
|
align-items: start; |
|
|
|
padding: 8px; |
|
|
|
border: 1px solid var(--line); |
|
|
|
border-radius: 6px; |
|
|
|
background: #fbfcfd; |
|
|
|
min-height: 42px; |
|
|
|
} |
|
|
|
|
|
|
|
.check input { |
|
|
|
width: 18px; |
|
|
|
height: 18px; |
|
|
|
margin: 1px 0 0; |
|
|
|
accent-color: var(--teal); |
|
|
|
} |
|
|
|
|
|
|
|
.check span { |
|
|
|
line-height: 1.35; |
|
|
|
overflow-wrap: anywhere; |
|
|
|
} |
|
|
|
|
|
|
|
.check small { |
|
|
|
display: block; |
|
|
|
color: var(--muted); |
|
|
|
margin-top: 2px; |
|
|
|
line-height: 1.3; |
|
|
|
} |
|
|
|
|
|
|
|
.tags { |
|
|
|
display: flex; |
|
|
|
flex-wrap: wrap; |
|
|
|
gap: 7px; |
|
|
|
margin-top: 10px; |
|
|
|
} |
|
|
|
|
|
|
|
.tag { |
|
|
|
border-radius: 999px; |
|
|
|
padding: 5px 8px; |
|
|
|
border: 1px solid var(--line); |
|
|
|
background: #fbfcfd; |
|
|
|
color: var(--muted); |
|
|
|
font-size: 0.82rem; |
|
|
|
white-space: nowrap; |
|
|
|
} |
|
|
|
|
|
|
|
textarea { |
|
|
|
width: 100%; |
|
|
|
min-height: 120px; |
|
|
|
resize: vertical; |
|
|
|
border: 1px solid var(--line); |
|
|
|
border-radius: 6px; |
|
|
|
padding: 10px; |
|
|
|
color: var(--ink); |
|
|
|
background: #fbfcfd; |
|
|
|
line-height: 1.4; |
|
|
|
} |
|
|
|
|
|
|
|
.export-box { |
|
|
|
margin-top: 10px; |
|
|
|
min-height: 180px; |
|
|
|
white-space: pre-wrap; |
|
|
|
} |
|
|
|
|
|
|
|
.legend { |
|
|
|
display: grid; |
|
|
|
grid-template-columns: repeat(2, minmax(0, 1fr)); |
|
|
|
gap: 8px; |
|
|
|
margin-top: 10px; |
|
|
|
} |
|
|
|
|
|
|
|
.legend-item { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
gap: 8px; |
|
|
|
color: var(--muted); |
|
|
|
font-size: 0.88rem; |
|
|
|
min-width: 0; |
|
|
|
} |
|
|
|
|
|
|
|
.swatch { |
|
|
|
width: 12px; |
|
|
|
height: 12px; |
|
|
|
border-radius: 3px; |
|
|
|
flex: 0 0 12px; |
|
|
|
} |
|
|
|
|
|
|
|
.footer { |
|
|
|
margin-top: 18px; |
|
|
|
color: var(--muted); |
|
|
|
font-size: 0.9rem; |
|
|
|
line-height: 1.4; |
|
|
|
} |
|
|
|
|
|
|
|
@media (max-width: 980px) { |
|
|
|
.layout { |
|
|
|
grid-template-columns: 1fr; |
|
|
|
} |
|
|
|
|
|
|
|
.summary { |
|
|
|
grid-template-columns: repeat(2, minmax(0, 1fr)); |
|
|
|
} |
|
|
|
|
|
|
|
.topbar { |
|
|
|
flex-direction: column; |
|
|
|
} |
|
|
|
|
|
|
|
.toolbar { |
|
|
|
justify-content: flex-start; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@media (max-width: 560px) { |
|
|
|
.shell { |
|
|
|
padding-top: 18px; |
|
|
|
} |
|
|
|
|
|
|
|
h1 { |
|
|
|
font-size: 1.55rem; |
|
|
|
} |
|
|
|
|
|
|
|
.summary { |
|
|
|
grid-template-columns: 1fr; |
|
|
|
} |
|
|
|
|
|
|
|
.toolbar, |
|
|
|
.button { |
|
|
|
width: 100%; |
|
|
|
} |
|
|
|
|
|
|
|
.week { |
|
|
|
grid-template-columns: repeat(7, minmax(230px, 78vw)); |
|
|
|
} |
|
|
|
|
|
|
|
.legend { |
|
|
|
grid-template-columns: 1fr; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@media print { |
|
|
|
body { |
|
|
|
background: #fff; |
|
|
|
} |
|
|
|
|
|
|
|
.toolbar, |
|
|
|
.export-box, |
|
|
|
#exportText, |
|
|
|
.footer { |
|
|
|
display: none; |
|
|
|
} |
|
|
|
|
|
|
|
.shell { |
|
|
|
max-width: none; |
|
|
|
padding: 0; |
|
|
|
} |
|
|
|
|
|
|
|
.layout { |
|
|
|
grid-template-columns: 1fr; |
|
|
|
} |
|
|
|
|
|
|
|
.week { |
|
|
|
overflow: visible; |
|
|
|
grid-template-columns: repeat(2, 1fr); |
|
|
|
} |
|
|
|
|
|
|
|
.day, |
|
|
|
.metric, |
|
|
|
.panel { |
|
|
|
box-shadow: none; |
|
|
|
break-inside: avoid; |
|
|
|
} |
|
|
|
} |
|
|
|
</style> |
|
|
|
</head> |
|
|
|
<body> |
|
|
|
<main class="shell"> |
|
|
|
<div class="topbar"> |
|
|
|
<div> |
|
|
|
<h1>Time Management Planner</h1> |
|
|
|
<p class="subtitle">A first working rhythm for work, congregation care, marriage, home responsibilities, exercise, dance, guitar, Bible study, and flexible creative time.</p> |
|
|
|
</div> |
|
|
|
<div class="toolbar" aria-label="Planner actions"> |
|
|
|
<button class="button primary" id="exportBtn" type="button">Export</button> |
|
|
|
<button class="button" id="printBtn" type="button">Print</button> |
|
|
|
<button class="button" id="resetBtn" type="button">Reset Checks</button> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<section class="summary" aria-label="Weekly time summary"> |
|
|
|
<div class="metric"> |
|
|
|
<strong>45 min</strong> |
|
|
|
<span>Daily morning workout target.</span> |
|
|
|
</div> |
|
|
|
<div class="metric"> |
|
|
|
<strong>10:00 PM</strong> |
|
|
|
<span>Hard stop for bedtime. No planned block ends after this.</span> |
|
|
|
</div> |
|
|
|
<div class="metric"> |
|
|
|
<strong>90 min</strong> |
|
|
|
<span>Saturday elder and congregation care block.</span> |
|
|
|
</div> |
|
|
|
<div class="metric"> |
|
|
|
<strong>Sunday</strong> |
|
|
|
<span>Lowest-pressure day: meeting, cleaning, rest, and light planning.</span> |
|
|
|
</div> |
|
|
|
</section> |
|
|
|
|
|
|
|
<div class="layout"> |
|
|
|
<section class="section" aria-labelledby="weekTitle"> |
|
|
|
<div class="section-head"> |
|
|
|
<h2 id="weekTitle">Weekly Skeleton</h2> |
|
|
|
<p class="hint">Travel is built in as 15 minutes each way. Flexible blocks use first-draft times.</p> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="week" id="weekGrid"></div> |
|
|
|
</section> |
|
|
|
|
|
|
|
<aside aria-label="Daily and weekly checklists"> |
|
|
|
<section class="panel"> |
|
|
|
<h2>Daily Anchors</h2> |
|
|
|
<div class="checklist" id="dailyChecks"></div> |
|
|
|
</section> |
|
|
|
|
|
|
|
<section class="panel"> |
|
|
|
<h2>Weekly Responsibilities</h2> |
|
|
|
<div class="checklist" id="weeklyChecks"></div> |
|
|
|
</section> |
|
|
|
|
|
|
|
<section class="panel"> |
|
|
|
<h2>Protected Roles</h2> |
|
|
|
<div class="tags"> |
|
|
|
<span class="tag">IT Director</span> |
|
|
|
<span class="tag">Programmer</span> |
|
|
|
<span class="tag">Congregation elder</span> |
|
|
|
<span class="tag">Husband</span> |
|
|
|
<span class="tag">Homeowner/renter</span> |
|
|
|
</div> |
|
|
|
</section> |
|
|
|
|
|
|
|
<section class="panel"> |
|
|
|
<h2>Color Key</h2> |
|
|
|
<div class="legend"> |
|
|
|
<div class="legend-item"><span class="swatch" style="background: var(--blue)"></span>Work</div> |
|
|
|
<div class="legend-item"><span class="swatch" style="background: var(--teal)"></span>Spiritual</div> |
|
|
|
<div class="legend-item"><span class="swatch" style="background: var(--green)"></span>Health</div> |
|
|
|
<div class="legend-item"><span class="swatch" style="background: var(--gold)"></span>Home</div> |
|
|
|
<div class="legend-item"><span class="swatch" style="background: var(--coral)"></span>Creative</div> |
|
|
|
<div class="legend-item"><span class="swatch" style="background: var(--violet)"></span>Marriage</div> |
|
|
|
</div> |
|
|
|
</section> |
|
|
|
|
|
|
|
<section class="panel"> |
|
|
|
<h2>Notes</h2> |
|
|
|
<textarea id="notes" aria-label="Planner notes">Saturday bills. Sunday light. Painting and writing are bonus creative blocks.</textarea> |
|
|
|
</section> |
|
|
|
|
|
|
|
<section class="panel"> |
|
|
|
<h2>Export</h2> |
|
|
|
<textarea class="export-box" id="exportText" aria-label="Exported Markdown"></textarea> |
|
|
|
</section> |
|
|
|
</aside> |
|
|
|
</div> |
|
|
|
|
|
|
|
<p class="footer">Source: interview answers gathered for the time_managment project folder. This page saves checklist state and notes in this browser.</p> |
|
|
|
</main> |
|
|
|
|
|
|
|
<script> |
|
|
|
const planner = { |
|
|
|
days: [ |
|
|
|
{ |
|
|
|
name: "Monday", |
|
|
|
tone: "Best normal build day", |
|
|
|
blocks: [ |
|
|
|
["6:00-6:45 AM", "Workout", "45 minutes before work", "health"], |
|
|
|
["8:30 AM-5:30 PM", "Work", "IT Director/programmer block", "work"], |
|
|
|
["6:00-6:30 PM", "Wife connection", "Target 30 minutes", "relationship"], |
|
|
|
["7:00-7:45 PM", "Bible study / meeting prep", "Use this as the main weekday study block", "spiritual"], |
|
|
|
["9:15-10:00 PM", "Guitar", "30-45 minutes before hard stop", "creative"], |
|
|
|
["10:00 PM", "Bedtime hard stop", "Stop the day here", "rest"] |
|
|
|
] |
|
|
|
}, |
|
|
|
{ |
|
|
|
name: "Tuesday", |
|
|
|
tone: "Meeting night", |
|
|
|
blocks: [ |
|
|
|
["6:00-6:45 AM", "Workout", "45 minutes before work", "health"], |
|
|
|
["8:30 AM-5:30 PM", "Work", "IT Director/programmer block", "work"], |
|
|
|
["6:45-9:00 PM", "Kingdom Hall", "15-minute travel each way plus 7:00-8:45 meeting", "spiritual"], |
|
|
|
["9:15-9:35 PM", "Wife connection", "Short version after meeting", "relationship"], |
|
|
|
["9:35-9:50 PM", "Guitar minimum", "15 minutes counts", "creative"], |
|
|
|
["9:50-10:00 PM", "Light reset only", "Keep this simple", "home"], |
|
|
|
["10:00 PM", "Bedtime hard stop", "Stop the day here", "rest"] |
|
|
|
] |
|
|
|
}, |
|
|
|
{ |
|
|
|
name: "Wednesday", |
|
|
|
tone: "Dance night", |
|
|
|
blocks: [ |
|
|
|
["6:00-6:45 AM", "Workout", "45 minutes before work", "health"], |
|
|
|
["8:30 AM-5:30 PM", "Work", "IT Director/programmer block", "work"], |
|
|
|
["5:45-7:45 PM", "Dance", "15-minute travel each way plus 6:00-7:30 class", "health"], |
|
|
|
["8:00-8:30 PM", "Wife connection", "Target 30 minutes", "relationship"], |
|
|
|
["9:15-9:45 PM", "Guitar minimum", "15-30 minutes", "creative"], |
|
|
|
["10:00 PM", "Bedtime hard stop", "Stop the day here", "rest"] |
|
|
|
] |
|
|
|
}, |
|
|
|
{ |
|
|
|
name: "Thursday", |
|
|
|
tone: "Late dance night", |
|
|
|
blocks: [ |
|
|
|
["6:00-6:45 AM", "Workout", "45 minutes before work", "health"], |
|
|
|
["8:30 AM-5:30 PM", "Work", "IT Director/programmer block", "work"], |
|
|
|
["5:45-6:05 PM", "Quick elder check", "Messages, calls, urgent follow-up", "spiritual"], |
|
|
|
["6:05-6:35 PM", "Wife connection", "Target 30 minutes before dance", "relationship"], |
|
|
|
["7:45-9:30 PM", "Dance", "Travel plus 8:15-9:15 class", "health"], |
|
|
|
["9:40-9:55 PM", "Guitar minimum", "15 minutes if energy is low", "creative"], |
|
|
|
["10:00 PM", "Bedtime hard stop", "Stop the day here", "rest"] |
|
|
|
] |
|
|
|
}, |
|
|
|
{ |
|
|
|
name: "Friday", |
|
|
|
tone: "Lighter landing", |
|
|
|
blocks: [ |
|
|
|
["6:00-6:45 AM", "Workout", "45 minutes before work", "health"], |
|
|
|
["8:30 AM-12:45 PM", "Work", "Morning work block", "work"], |
|
|
|
["1:00-2:15 PM", "Dance", "Travel plus 1:15-2:00 class", "health"], |
|
|
|
["2:15-5:30 PM", "Work", "Afternoon work block", "work"], |
|
|
|
["6:00-6:30 PM", "Wife connection", "Keep the evening lighter", "relationship"], |
|
|
|
["9:15-10:00 PM", "Guitar", "30-45 minutes if recovered", "creative"], |
|
|
|
["10:00 PM", "Bedtime hard stop", "Stop the day here", "rest"] |
|
|
|
] |
|
|
|
}, |
|
|
|
{ |
|
|
|
name: "Saturday", |
|
|
|
tone: "Admin, service, and home", |
|
|
|
blocks: [ |
|
|
|
["7:00-7:45 AM", "Workout", "45 minutes", "health"], |
|
|
|
["9:00-10:30 AM", "Elder/congregation block", "90 minutes for calls, shepherding, talks, prep, texts, organizing, ministry", "spiritual"], |
|
|
|
["10:45-11:15 AM", "Bills", "Weekly money/admin pass", "home"], |
|
|
|
["11:15 AM-12:45 PM", "Honey-do list and repairs", "Small weekly tasks", "home"], |
|
|
|
["3:30-4:15 PM", "Bible study / family worship", "Use as needed for all-of-the-above study", "spiritual"], |
|
|
|
["4:30-5:30 PM", "Painting or writing", "Optional creative block", "creative"], |
|
|
|
["9:15-10:00 PM", "Guitar", "30-45 minutes", "creative"], |
|
|
|
["10:00 PM", "Bedtime hard stop", "Stop the day here", "rest"] |
|
|
|
] |
|
|
|
}, |
|
|
|
{ |
|
|
|
name: "Sunday", |
|
|
|
tone: "Lowest-pressure day", |
|
|
|
blocks: [ |
|
|
|
["7:00-7:45 AM", "Workout", "45 minutes, easier pace if needed", "health"], |
|
|
|
["9:30-11:30 AM", "Cleaning", "2 hours: kitchen floor, vacuum, master bath", "home"], |
|
|
|
["12:45-3:15 PM", "Sunday meeting", "15-minute travel each way plus 1:00-3:00 meeting", "spiritual"], |
|
|
|
["3:30-5:30 PM", "Wife/rest time", "Keep this protected", "relationship"], |
|
|
|
["6:30-6:45 PM", "Light weekly planning", "Look at the week without loading the day", "rest"], |
|
|
|
["9:15-9:30 PM", "Guitar minimum", "15 minutes only if it feels good", "creative"], |
|
|
|
["10:00 PM", "Bedtime hard stop", "Stop the day here", "rest"] |
|
|
|
] |
|
|
|
} |
|
|
|
], |
|
|
|
daily: [ |
|
|
|
["Workout", "45 minutes, preferably morning"], |
|
|
|
["Wife connection", "Target 30 minutes"], |
|
|
|
["Guitar", "30-45 minutes late evening; 15-minute minimum; always end by 10:00 PM"], |
|
|
|
["Quick elder check", "Messages, calls, urgent follow-up"], |
|
|
|
["Basic reset", "Trash, small cleanup, next-day planning"], |
|
|
|
["Spiritual minimum", "10-15 minutes on full days"], |
|
|
|
["Bedtime", "10:00 PM hard stop"] |
|
|
|
], |
|
|
|
weekly: [ |
|
|
|
["Bible study", "Personal study, meeting prep, talk/elder prep, family worship"], |
|
|
|
["Saturday elder block", "90 minutes"], |
|
|
|
["Bills", "Saturday"], |
|
|
|
["House repairs", "Small weekly tasks"], |
|
|
|
["Trash", "Weekly and as needed"], |
|
|
|
["Honey-do list", "Small weekly tasks"], |
|
|
|
["General cleaning", "Sunday cleaning plus small resets"], |
|
|
|
["Watercolor painting", "Nice if possible"], |
|
|
|
["Writing", "Nice if possible"] |
|
|
|
] |
|
|
|
}; |
|
|
|
|
|
|
|
const stateKey = "time-management-planner-state-v1"; |
|
|
|
const state = loadState(); |
|
|
|
|
|
|
|
function loadState() { |
|
|
|
try { |
|
|
|
return JSON.parse(localStorage.getItem(stateKey)) || { checks: {}, notes: "" }; |
|
|
|
} catch (error) { |
|
|
|
return { checks: {}, notes: "" }; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
function saveState() { |
|
|
|
localStorage.setItem(stateKey, JSON.stringify(state)); |
|
|
|
} |
|
|
|
|
|
|
|
function blockMarkup(block) { |
|
|
|
const [time, task, note, type] = block; |
|
|
|
return ` |
|
|
|
<div class="block ${type}"> |
|
|
|
<span class="time">${time}</span> |
|
|
|
<span class="task">${task}</span> |
|
|
|
<span class="note">${note}</span> |
|
|
|
</div> |
|
|
|
`; |
|
|
|
} |
|
|
|
|
|
|
|
function renderWeek() { |
|
|
|
const grid = document.getElementById("weekGrid"); |
|
|
|
grid.innerHTML = planner.days.map(day => ` |
|
|
|
<article class="day"> |
|
|
|
<header> |
|
|
|
<h3>${day.name}</h3> |
|
|
|
<span class="tone">${day.tone}</span> |
|
|
|
</header> |
|
|
|
<div class="items"> |
|
|
|
${day.blocks.map(blockMarkup).join("")} |
|
|
|
</div> |
|
|
|
</article> |
|
|
|
`).join(""); |
|
|
|
} |
|
|
|
|
|
|
|
function renderChecks(list, id, prefix) { |
|
|
|
const target = document.getElementById(id); |
|
|
|
target.innerHTML = list.map(([label, detail], index) => { |
|
|
|
const key = `${prefix}-${index}`; |
|
|
|
const checked = state.checks[key] ? "checked" : ""; |
|
|
|
return ` |
|
|
|
<label class="check"> |
|
|
|
<input type="checkbox" data-check-key="${key}" ${checked}> |
|
|
|
<span>${label}<small>${detail}</small></span> |
|
|
|
</label> |
|
|
|
`; |
|
|
|
}).join(""); |
|
|
|
} |
|
|
|
|
|
|
|
function markdownExport() { |
|
|
|
const checks = [...document.querySelectorAll("[data-check-key]")].map(input => { |
|
|
|
const text = input.closest("label").innerText.trim().replace(/\n+/g, " - "); |
|
|
|
return `- [${input.checked ? "x" : " "}] ${text}`; |
|
|
|
}).join("\n"); |
|
|
|
|
|
|
|
const days = planner.days.map(day => { |
|
|
|
const blocks = day.blocks.map(([time, task, note]) => `- ${time}: ${task} (${note})`).join("\n"); |
|
|
|
return `## ${day.name}\n${blocks}`; |
|
|
|
}).join("\n\n"); |
|
|
|
|
|
|
|
return `# Time Management Planner\n\n## Weekly Skeleton\n\n${days}\n\n## Checklists\n\n${checks}\n\n## Notes\n\n${document.getElementById("notes").value.trim()}`; |
|
|
|
} |
|
|
|
|
|
|
|
function updateExport() { |
|
|
|
document.getElementById("exportText").value = markdownExport(); |
|
|
|
} |
|
|
|
|
|
|
|
function init() { |
|
|
|
renderWeek(); |
|
|
|
renderChecks(planner.daily, "dailyChecks", "daily"); |
|
|
|
renderChecks(planner.weekly, "weeklyChecks", "weekly"); |
|
|
|
|
|
|
|
const notes = document.getElementById("notes"); |
|
|
|
if (state.notes) { |
|
|
|
notes.value = state.notes; |
|
|
|
} |
|
|
|
|
|
|
|
document.addEventListener("change", event => { |
|
|
|
if (event.target.matches("[data-check-key]")) { |
|
|
|
state.checks[event.target.dataset.checkKey] = event.target.checked; |
|
|
|
saveState(); |
|
|
|
updateExport(); |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
notes.addEventListener("input", () => { |
|
|
|
state.notes = notes.value; |
|
|
|
saveState(); |
|
|
|
updateExport(); |
|
|
|
}); |
|
|
|
|
|
|
|
document.getElementById("exportBtn").addEventListener("click", async () => { |
|
|
|
updateExport(); |
|
|
|
const text = document.getElementById("exportText").value; |
|
|
|
try { |
|
|
|
await navigator.clipboard.writeText(text); |
|
|
|
document.getElementById("exportBtn").textContent = "Copied"; |
|
|
|
setTimeout(() => document.getElementById("exportBtn").textContent = "Export", 1200); |
|
|
|
} catch (error) { |
|
|
|
document.getElementById("exportText").focus(); |
|
|
|
document.getElementById("exportText").select(); |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
document.getElementById("printBtn").addEventListener("click", () => window.print()); |
|
|
|
|
|
|
|
document.getElementById("resetBtn").addEventListener("click", () => { |
|
|
|
state.checks = {}; |
|
|
|
saveState(); |
|
|
|
document.querySelectorAll("[data-check-key]").forEach(input => { |
|
|
|
input.checked = false; |
|
|
|
}); |
|
|
|
updateExport(); |
|
|
|
}); |
|
|
|
|
|
|
|
updateExport(); |
|
|
|
} |
|
|
|
|
|
|
|
init(); |
|
|
|
</script> |
|
|
|
</body> |
|
|
|
</html> |