Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

867 řádky
25KB

  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1">
  6. <title>Time Management Planner</title>
  7. <style>
  8. :root {
  9. --ink: #202124;
  10. --muted: #5f6368;
  11. --line: #d8dde3;
  12. --page: #f6f7f9;
  13. --panel: #ffffff;
  14. --teal: #176b5d;
  15. --blue: #2f5f98;
  16. --coral: #b75542;
  17. --gold: #8a6500;
  18. --green: #4d7653;
  19. --violet: #7b5aa6;
  20. --shadow: 0 10px 28px rgba(32, 33, 36, 0.08);
  21. --radius: 8px;
  22. --space: clamp(14px, 2vw, 22px);
  23. font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  24. color: var(--ink);
  25. background: var(--page);
  26. }
  27. * {
  28. box-sizing: border-box;
  29. }
  30. body {
  31. margin: 0;
  32. min-width: 320px;
  33. background:
  34. linear-gradient(180deg, rgba(237, 244, 242, 0.9), rgba(246, 247, 249, 0.2) 280px),
  35. var(--page);
  36. }
  37. button,
  38. input,
  39. textarea {
  40. font: inherit;
  41. }
  42. .shell {
  43. max-width: 1180px;
  44. margin: 0 auto;
  45. padding: 24px var(--space) 48px;
  46. }
  47. .topbar {
  48. display: flex;
  49. align-items: flex-start;
  50. justify-content: space-between;
  51. gap: 16px;
  52. margin-bottom: 20px;
  53. }
  54. h1 {
  55. margin: 0 0 6px;
  56. font-size: 2rem;
  57. line-height: 1.08;
  58. letter-spacing: 0;
  59. }
  60. .subtitle {
  61. margin: 0;
  62. max-width: 780px;
  63. color: var(--muted);
  64. line-height: 1.45;
  65. }
  66. .toolbar {
  67. display: flex;
  68. gap: 8px;
  69. flex-wrap: wrap;
  70. justify-content: flex-end;
  71. min-width: 220px;
  72. }
  73. .button {
  74. min-height: 38px;
  75. border: 1px solid var(--line);
  76. border-radius: 6px;
  77. padding: 8px 12px;
  78. background: var(--panel);
  79. color: var(--ink);
  80. cursor: pointer;
  81. box-shadow: 0 1px 0 rgba(32, 33, 36, 0.04);
  82. }
  83. .button.primary {
  84. border-color: var(--teal);
  85. background: var(--teal);
  86. color: #fff;
  87. }
  88. .button:hover {
  89. filter: brightness(0.98);
  90. }
  91. .summary {
  92. display: grid;
  93. grid-template-columns: repeat(4, minmax(0, 1fr));
  94. gap: 12px;
  95. margin: 18px 0 22px;
  96. }
  97. .metric {
  98. background: var(--panel);
  99. border: 1px solid var(--line);
  100. border-radius: var(--radius);
  101. padding: 14px;
  102. box-shadow: var(--shadow);
  103. min-height: 108px;
  104. }
  105. .metric strong {
  106. display: block;
  107. font-size: 1.55rem;
  108. line-height: 1.05;
  109. margin-bottom: 6px;
  110. }
  111. .metric span {
  112. color: var(--muted);
  113. line-height: 1.35;
  114. display: block;
  115. }
  116. .layout {
  117. display: grid;
  118. grid-template-columns: minmax(0, 1fr) 330px;
  119. gap: 18px;
  120. align-items: start;
  121. }
  122. .section {
  123. margin-bottom: 18px;
  124. }
  125. .section-head {
  126. display: flex;
  127. align-items: center;
  128. justify-content: space-between;
  129. gap: 12px;
  130. margin-bottom: 10px;
  131. }
  132. h2 {
  133. margin: 0;
  134. font-size: 1.08rem;
  135. letter-spacing: 0;
  136. }
  137. .hint {
  138. color: var(--muted);
  139. font-size: 0.92rem;
  140. line-height: 1.35;
  141. margin: 0;
  142. }
  143. .week {
  144. display: grid;
  145. grid-template-columns: repeat(7, minmax(140px, 1fr));
  146. gap: 10px;
  147. overflow-x: auto;
  148. padding-bottom: 4px;
  149. }
  150. .day {
  151. background: var(--panel);
  152. border: 1px solid var(--line);
  153. border-radius: var(--radius);
  154. min-height: 460px;
  155. box-shadow: var(--shadow);
  156. display: flex;
  157. flex-direction: column;
  158. }
  159. .day header {
  160. padding: 12px 12px 8px;
  161. border-bottom: 1px solid var(--line);
  162. min-height: 62px;
  163. }
  164. .day h3 {
  165. margin: 0 0 4px;
  166. font-size: 1rem;
  167. letter-spacing: 0;
  168. }
  169. .day .tone {
  170. color: var(--muted);
  171. font-size: 0.8rem;
  172. line-height: 1.25;
  173. }
  174. .items {
  175. display: flex;
  176. flex-direction: column;
  177. gap: 8px;
  178. padding: 10px;
  179. }
  180. .block {
  181. border-left: 4px solid var(--line);
  182. background: #fafbfc;
  183. border-radius: 6px;
  184. padding: 9px 9px 9px 10px;
  185. min-height: 58px;
  186. }
  187. .block.work { border-left-color: var(--blue); }
  188. .block.spiritual { border-left-color: var(--teal); }
  189. .block.health { border-left-color: var(--green); }
  190. .block.home { border-left-color: var(--gold); }
  191. .block.creative { border-left-color: var(--coral); }
  192. .block.relationship { border-left-color: var(--violet); }
  193. .block.rest { border-left-color: #6c737f; }
  194. .time {
  195. display: block;
  196. color: var(--muted);
  197. font-size: 0.78rem;
  198. line-height: 1.3;
  199. margin-bottom: 4px;
  200. }
  201. .task {
  202. display: block;
  203. font-weight: 650;
  204. line-height: 1.25;
  205. overflow-wrap: anywhere;
  206. }
  207. .note {
  208. display: block;
  209. color: var(--muted);
  210. font-size: 0.82rem;
  211. line-height: 1.35;
  212. margin-top: 3px;
  213. overflow-wrap: anywhere;
  214. }
  215. .panel {
  216. background: var(--panel);
  217. border: 1px solid var(--line);
  218. border-radius: var(--radius);
  219. box-shadow: var(--shadow);
  220. padding: 14px;
  221. }
  222. .panel + .panel {
  223. margin-top: 14px;
  224. }
  225. .checklist {
  226. display: grid;
  227. gap: 8px;
  228. margin-top: 10px;
  229. }
  230. .check {
  231. display: grid;
  232. grid-template-columns: 22px minmax(0, 1fr);
  233. gap: 8px;
  234. align-items: start;
  235. padding: 8px;
  236. border: 1px solid var(--line);
  237. border-radius: 6px;
  238. background: #fbfcfd;
  239. min-height: 42px;
  240. }
  241. .check input {
  242. width: 18px;
  243. height: 18px;
  244. margin: 1px 0 0;
  245. accent-color: var(--teal);
  246. }
  247. .check span {
  248. line-height: 1.35;
  249. overflow-wrap: anywhere;
  250. }
  251. .check small {
  252. display: block;
  253. color: var(--muted);
  254. margin-top: 2px;
  255. line-height: 1.3;
  256. }
  257. .tags {
  258. display: flex;
  259. flex-wrap: wrap;
  260. gap: 7px;
  261. margin-top: 10px;
  262. }
  263. .tag {
  264. border-radius: 999px;
  265. padding: 5px 8px;
  266. border: 1px solid var(--line);
  267. background: #fbfcfd;
  268. color: var(--muted);
  269. font-size: 0.82rem;
  270. white-space: nowrap;
  271. }
  272. textarea {
  273. width: 100%;
  274. min-height: 120px;
  275. resize: vertical;
  276. border: 1px solid var(--line);
  277. border-radius: 6px;
  278. padding: 10px;
  279. color: var(--ink);
  280. background: #fbfcfd;
  281. line-height: 1.4;
  282. }
  283. .reflection-grid {
  284. display: grid;
  285. gap: 10px;
  286. margin-top: 10px;
  287. }
  288. .field-label {
  289. display: grid;
  290. gap: 5px;
  291. color: var(--muted);
  292. font-size: 0.84rem;
  293. line-height: 1.3;
  294. }
  295. .field-label textarea {
  296. min-height: 74px;
  297. color: var(--ink);
  298. font-size: 0.95rem;
  299. }
  300. .field-label.compact textarea {
  301. min-height: 52px;
  302. }
  303. .export-box {
  304. margin-top: 10px;
  305. min-height: 180px;
  306. white-space: pre-wrap;
  307. }
  308. .legend {
  309. display: grid;
  310. grid-template-columns: repeat(2, minmax(0, 1fr));
  311. gap: 8px;
  312. margin-top: 10px;
  313. }
  314. .legend-item {
  315. display: flex;
  316. align-items: center;
  317. gap: 8px;
  318. color: var(--muted);
  319. font-size: 0.88rem;
  320. min-width: 0;
  321. }
  322. .swatch {
  323. width: 12px;
  324. height: 12px;
  325. border-radius: 3px;
  326. flex: 0 0 12px;
  327. }
  328. .footer {
  329. margin-top: 18px;
  330. color: var(--muted);
  331. font-size: 0.9rem;
  332. line-height: 1.4;
  333. }
  334. @media (max-width: 980px) {
  335. .layout {
  336. grid-template-columns: 1fr;
  337. }
  338. .summary {
  339. grid-template-columns: repeat(2, minmax(0, 1fr));
  340. }
  341. .topbar {
  342. flex-direction: column;
  343. }
  344. .toolbar {
  345. justify-content: flex-start;
  346. }
  347. }
  348. @media (max-width: 560px) {
  349. .shell {
  350. padding-top: 18px;
  351. }
  352. h1 {
  353. font-size: 1.55rem;
  354. }
  355. .summary {
  356. grid-template-columns: 1fr;
  357. }
  358. .toolbar,
  359. .button {
  360. width: 100%;
  361. }
  362. .week {
  363. grid-template-columns: repeat(7, minmax(230px, 78vw));
  364. }
  365. .legend {
  366. grid-template-columns: 1fr;
  367. }
  368. }
  369. @media print {
  370. body {
  371. background: #fff;
  372. }
  373. .toolbar,
  374. .export-box,
  375. #exportText,
  376. .footer {
  377. display: none;
  378. }
  379. .shell {
  380. max-width: none;
  381. padding: 0;
  382. }
  383. .layout {
  384. grid-template-columns: 1fr;
  385. }
  386. .week {
  387. overflow: visible;
  388. grid-template-columns: repeat(2, 1fr);
  389. }
  390. .day,
  391. .metric,
  392. .panel {
  393. box-shadow: none;
  394. break-inside: avoid;
  395. }
  396. }
  397. </style>
  398. </head>
  399. <body>
  400. <main class="shell">
  401. <div class="topbar">
  402. <div>
  403. <h1>Time Management Planner</h1>
  404. <p class="subtitle">A first working rhythm for work, congregation care, marriage, home responsibilities, exercise, dance, guitar, Bible study, and flexible creative time.</p>
  405. </div>
  406. <div class="toolbar" aria-label="Planner actions">
  407. <button class="button primary" id="exportBtn" type="button">Export</button>
  408. <button class="button" id="printBtn" type="button">Print</button>
  409. <button class="button" id="resetBtn" type="button">Reset Checks</button>
  410. </div>
  411. </div>
  412. <section class="summary" aria-label="Weekly time summary">
  413. <div class="metric">
  414. <strong>45 min</strong>
  415. <span>Daily morning workout target.</span>
  416. </div>
  417. <div class="metric">
  418. <strong>10:00 PM</strong>
  419. <span>Hard stop for bedtime. No planned block ends after this.</span>
  420. </div>
  421. <div class="metric">
  422. <strong>90 min</strong>
  423. <span>Saturday elder and congregation care block.</span>
  424. </div>
  425. <div class="metric">
  426. <strong>Sunday</strong>
  427. <span>Lowest-pressure day: meeting, cleaning, rest, and light planning.</span>
  428. </div>
  429. </section>
  430. <div class="layout">
  431. <section class="section" aria-labelledby="weekTitle">
  432. <div class="section-head">
  433. <h2 id="weekTitle">Weekly Skeleton</h2>
  434. <p class="hint">Travel is built in as 15 minutes each way. Flexible blocks use first-draft times.</p>
  435. </div>
  436. <div class="week" id="weekGrid"></div>
  437. </section>
  438. <aside aria-label="Daily and weekly checklists">
  439. <section class="panel">
  440. <h2>Daily Anchors</h2>
  441. <div class="checklist" id="dailyChecks"></div>
  442. </section>
  443. <section class="panel">
  444. <h2>Weekly Responsibilities</h2>
  445. <div class="checklist" id="weeklyChecks"></div>
  446. </section>
  447. <section class="panel">
  448. <h2>Priorities & Motivation</h2>
  449. <p class="hint">Keep this small: what matters, why it matters, and the next visible move.</p>
  450. <div class="reflection-grid">
  451. <label class="field-label compact">
  452. Top priorities
  453. <textarea id="priorities" data-state-field="priorities" aria-label="Top priorities" placeholder="1.&#10;2.&#10;3."></textarea>
  454. </label>
  455. <label class="field-label">
  456. Thoughts to hold
  457. <textarea id="thoughts" data-state-field="thoughts" aria-label="Thoughts to hold" placeholder="Loose thoughts, concerns, ideas, things to remember."></textarea>
  458. </label>
  459. <label class="field-label compact">
  460. Why this matters
  461. <textarea id="motivation" data-state-field="motivation" aria-label="Why this matters" placeholder="Connect the work to people, peace, service, health, or growth."></textarea>
  462. </label>
  463. <label class="field-label compact">
  464. Wins
  465. <textarea id="wins" data-state-field="wins" aria-label="Wins" placeholder="What moved forward today? Small counts."></textarea>
  466. </label>
  467. <label class="field-label compact">
  468. Next tiny step
  469. <textarea id="nextStep" data-state-field="nextStep" aria-label="Next tiny step" placeholder="One action small enough to start."></textarea>
  470. </label>
  471. </div>
  472. </section>
  473. <section class="panel">
  474. <h2>Protected Roles</h2>
  475. <div class="tags">
  476. <span class="tag">IT Director</span>
  477. <span class="tag">Programmer</span>
  478. <span class="tag">Congregation elder</span>
  479. <span class="tag">Husband</span>
  480. <span class="tag">Homeowner/renter</span>
  481. </div>
  482. </section>
  483. <section class="panel">
  484. <h2>Color Key</h2>
  485. <div class="legend">
  486. <div class="legend-item"><span class="swatch" style="background: var(--blue)"></span>Work</div>
  487. <div class="legend-item"><span class="swatch" style="background: var(--teal)"></span>Spiritual</div>
  488. <div class="legend-item"><span class="swatch" style="background: var(--green)"></span>Health</div>
  489. <div class="legend-item"><span class="swatch" style="background: var(--gold)"></span>Home</div>
  490. <div class="legend-item"><span class="swatch" style="background: var(--coral)"></span>Creative</div>
  491. <div class="legend-item"><span class="swatch" style="background: var(--violet)"></span>Marriage</div>
  492. </div>
  493. </section>
  494. <section class="panel">
  495. <h2>Notes</h2>
  496. <textarea id="notes" aria-label="Planner notes">Saturday bills. Sunday light. Painting and writing are bonus creative blocks.</textarea>
  497. </section>
  498. <section class="panel">
  499. <h2>Export</h2>
  500. <textarea class="export-box" id="exportText" aria-label="Exported Markdown"></textarea>
  501. </section>
  502. </aside>
  503. </div>
  504. <p class="footer">Source: interview answers gathered for the time_managment project folder. This page saves checklist state and notes in this browser.</p>
  505. </main>
  506. <script>
  507. const planner = {
  508. days: [
  509. {
  510. name: "Monday",
  511. tone: "Best normal build day",
  512. blocks: [
  513. ["6:00-6:45 AM", "Workout", "45 minutes before work", "health"],
  514. ["8:30 AM-5:30 PM", "Work", "IT Director/programmer block", "work"],
  515. ["6:00-6:30 PM", "Wife connection", "Target 30 minutes", "relationship"],
  516. ["7:00-7:45 PM", "Bible study / meeting prep", "Use this as the main weekday study block", "spiritual"],
  517. ["9:15-10:00 PM", "Guitar", "30-45 minutes before hard stop", "creative"],
  518. ["10:00 PM", "Bedtime hard stop", "Stop the day here", "rest"]
  519. ]
  520. },
  521. {
  522. name: "Tuesday",
  523. tone: "Meeting night",
  524. blocks: [
  525. ["6:00-6:45 AM", "Workout", "45 minutes before work", "health"],
  526. ["8:30 AM-5:30 PM", "Work", "IT Director/programmer block", "work"],
  527. ["6:45-9:00 PM", "Kingdom Hall", "15-minute travel each way plus 7:00-8:45 meeting", "spiritual"],
  528. ["9:15-9:35 PM", "Wife connection", "Short version after meeting", "relationship"],
  529. ["9:35-9:50 PM", "Guitar minimum", "15 minutes counts", "creative"],
  530. ["9:50-10:00 PM", "Light reset only", "Keep this simple", "home"],
  531. ["10:00 PM", "Bedtime hard stop", "Stop the day here", "rest"]
  532. ]
  533. },
  534. {
  535. name: "Wednesday",
  536. tone: "Dance night",
  537. blocks: [
  538. ["6:00-6:45 AM", "Workout", "45 minutes before work", "health"],
  539. ["8:30 AM-5:30 PM", "Work", "IT Director/programmer block", "work"],
  540. ["5:45-7:45 PM", "Dance", "15-minute travel each way plus 6:00-7:30 class", "health"],
  541. ["8:00-8:30 PM", "Wife connection", "Target 30 minutes", "relationship"],
  542. ["9:15-9:45 PM", "Guitar minimum", "15-30 minutes", "creative"],
  543. ["10:00 PM", "Bedtime hard stop", "Stop the day here", "rest"]
  544. ]
  545. },
  546. {
  547. name: "Thursday",
  548. tone: "Late dance night",
  549. blocks: [
  550. ["6:00-6:45 AM", "Workout", "45 minutes before work", "health"],
  551. ["8:30 AM-5:30 PM", "Work", "IT Director/programmer block", "work"],
  552. ["5:45-6:05 PM", "Quick elder check", "Messages, calls, urgent follow-up", "spiritual"],
  553. ["6:05-6:35 PM", "Wife connection", "Target 30 minutes before dance", "relationship"],
  554. ["7:45-9:30 PM", "Dance", "Travel plus 8:15-9:15 class", "health"],
  555. ["9:40-9:55 PM", "Guitar minimum", "15 minutes if energy is low", "creative"],
  556. ["10:00 PM", "Bedtime hard stop", "Stop the day here", "rest"]
  557. ]
  558. },
  559. {
  560. name: "Friday",
  561. tone: "Lighter landing",
  562. blocks: [
  563. ["6:00-6:45 AM", "Workout", "45 minutes before work", "health"],
  564. ["8:30 AM-12:45 PM", "Work", "Morning work block", "work"],
  565. ["1:00-2:15 PM", "Dance", "Travel plus 1:15-2:00 class", "health"],
  566. ["2:15-5:30 PM", "Work", "Afternoon work block", "work"],
  567. ["6:00-6:30 PM", "Wife connection", "Keep the evening lighter", "relationship"],
  568. ["9:15-10:00 PM", "Guitar", "30-45 minutes if recovered", "creative"],
  569. ["10:00 PM", "Bedtime hard stop", "Stop the day here", "rest"]
  570. ]
  571. },
  572. {
  573. name: "Saturday",
  574. tone: "Admin, service, and home",
  575. blocks: [
  576. ["7:00-7:45 AM", "Workout", "45 minutes", "health"],
  577. ["9:00-10:30 AM", "Elder/congregation block", "90 minutes for calls, shepherding, talks, prep, texts, organizing, ministry", "spiritual"],
  578. ["10:45-11:15 AM", "Bills", "Weekly money/admin pass", "home"],
  579. ["11:15 AM-12:45 PM", "Honey-do list and repairs", "Small weekly tasks", "home"],
  580. ["3:30-4:15 PM", "Bible study / family worship", "Use as needed for all-of-the-above study", "spiritual"],
  581. ["4:30-5:30 PM", "Painting or writing", "Optional creative block", "creative"],
  582. ["9:15-10:00 PM", "Guitar", "30-45 minutes", "creative"],
  583. ["10:00 PM", "Bedtime hard stop", "Stop the day here", "rest"]
  584. ]
  585. },
  586. {
  587. name: "Sunday",
  588. tone: "Lowest-pressure day",
  589. blocks: [
  590. ["7:00-7:45 AM", "Workout", "45 minutes, easier pace if needed", "health"],
  591. ["9:30-11:30 AM", "Cleaning", "2 hours: kitchen floor, vacuum, master bath", "home"],
  592. ["12:45-3:15 PM", "Sunday meeting", "15-minute travel each way plus 1:00-3:00 meeting", "spiritual"],
  593. ["3:30-5:30 PM", "Wife/rest time", "Keep this protected", "relationship"],
  594. ["6:30-6:45 PM", "Light weekly planning", "Look at the week without loading the day", "rest"],
  595. ["9:15-9:30 PM", "Guitar minimum", "15 minutes only if it feels good", "creative"],
  596. ["10:00 PM", "Bedtime hard stop", "Stop the day here", "rest"]
  597. ]
  598. }
  599. ],
  600. daily: [
  601. ["Workout", "45 minutes, preferably morning"],
  602. ["Wife connection", "Target 30 minutes"],
  603. ["Guitar", "30-45 minutes late evening; 15-minute minimum; always end by 10:00 PM"],
  604. ["Quick elder check", "Messages, calls, urgent follow-up"],
  605. ["Basic reset", "Trash, small cleanup, next-day planning"],
  606. ["Spiritual minimum", "10-15 minutes on full days"],
  607. ["Bedtime", "10:00 PM hard stop"]
  608. ],
  609. weekly: [
  610. ["Bible study", "Personal study, meeting prep, talk/elder prep, family worship"],
  611. ["Saturday elder block", "90 minutes"],
  612. ["Bills", "Saturday"],
  613. ["House repairs", "Small weekly tasks"],
  614. ["Trash", "Weekly and as needed"],
  615. ["Honey-do list", "Small weekly tasks"],
  616. ["General cleaning", "Sunday cleaning plus small resets"],
  617. ["Watercolor painting", "Nice if possible"],
  618. ["Writing", "Nice if possible"]
  619. ]
  620. };
  621. const stateKey = "time-management-planner-state-v2";
  622. const state = loadState();
  623. function loadState() {
  624. try {
  625. const legacy = JSON.parse(localStorage.getItem("time-management-planner-state-v1")) || {};
  626. const saved = JSON.parse(localStorage.getItem(stateKey)) || {};
  627. return {
  628. checks: {},
  629. notes: "",
  630. priorities: "",
  631. thoughts: "",
  632. motivation: "",
  633. wins: "",
  634. nextStep: "",
  635. ...legacy,
  636. ...saved
  637. };
  638. } catch (error) {
  639. return {
  640. checks: {},
  641. notes: "",
  642. priorities: "",
  643. thoughts: "",
  644. motivation: "",
  645. wins: "",
  646. nextStep: ""
  647. };
  648. }
  649. }
  650. function saveState() {
  651. localStorage.setItem(stateKey, JSON.stringify(state));
  652. }
  653. function blockMarkup(block) {
  654. const [time, task, note, type] = block;
  655. return `
  656. <div class="block ${type}">
  657. <span class="time">${time}</span>
  658. <span class="task">${task}</span>
  659. <span class="note">${note}</span>
  660. </div>
  661. `;
  662. }
  663. function renderWeek() {
  664. const grid = document.getElementById("weekGrid");
  665. grid.innerHTML = planner.days.map(day => `
  666. <article class="day">
  667. <header>
  668. <h3>${day.name}</h3>
  669. <span class="tone">${day.tone}</span>
  670. </header>
  671. <div class="items">
  672. ${day.blocks.map(blockMarkup).join("")}
  673. </div>
  674. </article>
  675. `).join("");
  676. }
  677. function renderChecks(list, id, prefix) {
  678. const target = document.getElementById(id);
  679. target.innerHTML = list.map(([label, detail], index) => {
  680. const key = `${prefix}-${index}`;
  681. const checked = state.checks[key] ? "checked" : "";
  682. return `
  683. <label class="check">
  684. <input type="checkbox" data-check-key="${key}" ${checked}>
  685. <span>${label}<small>${detail}</small></span>
  686. </label>
  687. `;
  688. }).join("");
  689. }
  690. function markdownExport() {
  691. const checks = [...document.querySelectorAll("[data-check-key]")].map(input => {
  692. const text = input.closest("label").innerText.trim().replace(/\n+/g, " - ");
  693. return `- [${input.checked ? "x" : " "}] ${text}`;
  694. }).join("\n");
  695. const days = planner.days.map(day => {
  696. const blocks = day.blocks.map(([time, task, note]) => `- ${time}: ${task} (${note})`).join("\n");
  697. return `## ${day.name}\n${blocks}`;
  698. }).join("\n\n");
  699. const priorities = document.getElementById("priorities").value.trim();
  700. const thoughts = document.getElementById("thoughts").value.trim();
  701. const motivation = document.getElementById("motivation").value.trim();
  702. const wins = document.getElementById("wins").value.trim();
  703. const nextStep = document.getElementById("nextStep").value.trim();
  704. const notes = document.getElementById("notes").value.trim();
  705. return `# Time Management Planner\n\n## Priorities\n\n${priorities}\n\n## Thoughts To Hold\n\n${thoughts}\n\n## Why This Matters\n\n${motivation}\n\n## Wins\n\n${wins}\n\n## Next Tiny Step\n\n${nextStep}\n\n## Weekly Skeleton\n\n${days}\n\n## Checklists\n\n${checks}\n\n## Notes\n\n${notes}`;
  706. }
  707. function updateExport() {
  708. document.getElementById("exportText").value = markdownExport();
  709. }
  710. function init() {
  711. renderWeek();
  712. renderChecks(planner.daily, "dailyChecks", "daily");
  713. renderChecks(planner.weekly, "weeklyChecks", "weekly");
  714. const notes = document.getElementById("notes");
  715. if (state.notes) {
  716. notes.value = state.notes;
  717. }
  718. document.querySelectorAll("[data-state-field]").forEach(field => {
  719. if (state[field.dataset.stateField]) {
  720. field.value = state[field.dataset.stateField];
  721. }
  722. field.addEventListener("input", () => {
  723. state[field.dataset.stateField] = field.value;
  724. saveState();
  725. updateExport();
  726. });
  727. });
  728. document.addEventListener("change", event => {
  729. if (event.target.matches("[data-check-key]")) {
  730. state.checks[event.target.dataset.checkKey] = event.target.checked;
  731. saveState();
  732. updateExport();
  733. }
  734. });
  735. notes.addEventListener("input", () => {
  736. state.notes = notes.value;
  737. saveState();
  738. updateExport();
  739. });
  740. document.getElementById("exportBtn").addEventListener("click", async () => {
  741. updateExport();
  742. const text = document.getElementById("exportText").value;
  743. try {
  744. await navigator.clipboard.writeText(text);
  745. document.getElementById("exportBtn").textContent = "Copied";
  746. setTimeout(() => document.getElementById("exportBtn").textContent = "Export", 1200);
  747. } catch (error) {
  748. document.getElementById("exportText").focus();
  749. document.getElementById("exportText").select();
  750. }
  751. });
  752. document.getElementById("printBtn").addEventListener("click", () => window.print());
  753. document.getElementById("resetBtn").addEventListener("click", () => {
  754. state.checks = {};
  755. saveState();
  756. document.querySelectorAll("[data-check-key]").forEach(input => {
  757. input.checked = false;
  758. });
  759. updateExport();
  760. });
  761. updateExport();
  762. }
  763. init();
  764. </script>
  765. </body>
  766. </html>

Powered by TurnKey Linux.