nickmf30

Untitled

Dec 14th, 2025
23
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 42.18 KB | None | 0 0
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <style>
  5.  
  6.  
  7. /* ============================== */
  8. /* ========= TASK TABLE ========= */
  9. /* ============================== */
  10. /* @task table @task @table */
  11.  
  12. /*==== @task table container ====*/
  13. .task-table-container { /* Table container with scroll */
  14. overflow-x: auto; /* Horizontal scroll if neede*/
  15. background: #16213e; /* Dark blue background */
  16. border-radius: 8px; /* Rounded corners */
  17. padding: 10px; /* Inner spacing */
  18. transition: background 0.3s ease; /* Smooth color transition */
  19. }
  20.  
  21. /*==== @task table container filter backgrounds ====*/
  22. /* Light tinted backgrounds when filter is active - tied to tab colors via CSS variables */
  23. .task-filter-btn[data-status="active"].active ~ .task-search-container ~ .task-count-display ~ .task-table-container,
  24. body:has(.task-filter-btn[data-status="active"].active) .task-table-container {
  25. background: var(--bg-active); /* Very light green tint */
  26. }
  27.  
  28. body:has(.task-filter-btn[data-status="all"].active) .task-table-container {
  29. background: var(--bg-all); /* Very light gray tint */
  30. }
  31.  
  32. body:has(.task-filter-btn[data-status="pinned"].active) .task-table-container {
  33. background: var(--bg-pinned); /* Very light orange tint */
  34. }
  35.  
  36. body:has(.task-filter-btn[data-status="favorite"].active) .task-table-container {
  37. background: var(--bg-favorite); /* Very light yellow tint */
  38. }
  39.  
  40. body:has(.task-filter-btn[data-status="moo"].active) .task-table-container {
  41. background: var(--bg-moo); /* Very light purple tint */
  42. }
  43.  
  44. body:has(.task-filter-btn[data-status="completed"].active) .task-table-container {
  45. background: var(--bg-completed); /* Very light bright green tint */
  46. }
  47.  
  48. body:has(.task-filter-btn[data-status="review"].active) .task-table-container {
  49. background: var(--bg-review); /* Very light blue tint */
  50. }
  51.  
  52. body:has(.task-filter-btn[data-status="future"].active) .task-table-container {
  53. background: var(--bg-future); /* Very light blue tint */
  54. }
  55.  
  56. body:has(.task-filter-btn[data-status="archived"].active) .task-table-container {
  57. background: var(--bg-archived); /* Very light gray tint */
  58. }
  59.  
  60. body:has(.task-filter-btn[data-status="dump"].active) .task-table-container {
  61. background: var(--bg-dump); /* Very light gray tint */
  62. }
  63.  
  64. body:has(.task-filter-btn[data-status="deleted"].active) .task-table-container {
  65. background: var(--bg-deleted); /* Very light red tint */
  66. }
  67.  
  68. /*==== @task table ====*/
  69. .task-table { /* Main task table */
  70. width: 100%; /* Full width */
  71. border-collapse: collapse; /* Remove cell spacing */
  72. color: #eee; /* Light text */
  73. table-layout: fixed; /* Force column widths to be respected */
  74. }
  75.  
  76. /*==== @task table header ====*/
  77. .task-table thead { /* Table header */
  78. background: #0f3460; /* Dark blue background */
  79. }
  80.  
  81. .task-table th { /* Table header cells */
  82. padding: 12px 8px; /* Cell padding */
  83. text-align: left; /* Left align text */
  84. font-size: 0.9rem; /* Text size */
  85. font-weight: 600; /* Semi-bold */
  86. color: #aaa; /* Gray text */
  87. border-bottom: 2px solid #1a1a2e; /* Bottom border */
  88. white-space: nowrap; /* Don't wrap text */
  89. }
  90.  
  91. /*==== @sortable columns ====*/
  92. .task-table th.sortable { /* Sortable column headers */
  93. cursor: pointer; /* Show pointer cursor */
  94. user-select: none; /* Prevent text selection */
  95. transition: color 0.2s ease, background 0.2s ease; /* Smooth transitions */
  96. }
  97.  
  98. .task-table th.sortable:hover { /* Sortable header hover */
  99. color: #4a90e2; /* Blue text on hover */
  100. background: rgba(74, 144, 226, 0.1); /* Light blue background */
  101. }
  102.  
  103. .task-table th.sortable.sorted-asc,
  104. .task-table th.sortable.sorted-desc { /* Active sorted column */
  105. color: #4a90e2; /* Blue text for sorted column */
  106. background: rgba(74, 144, 226, 0.15); /* Slightly darker blue background */
  107. }
  108.  
  109. /*==== @sort indicators ====*/
  110. .sort-indicator { /* Sort arrow container */
  111. display: inline-block; /* Inline block */
  112. width: 12px; /* Fixed width */
  113. margin-left: 4px; /* Space from text */
  114. opacity: 0.3; /* Dim by default */
  115. transition: opacity 0.2s ease; /* Smooth opacity change */
  116. }
  117.  
  118. .task-table th.sortable:hover .sort-indicator { /* Show indicator on hover */
  119. opacity: 0.6; /* More visible on hover */
  120. }
  121.  
  122. .task-table th.sortable.sorted-asc .sort-indicator::after { /* Ascending arrow */
  123. content: '▲'; /* Up arrow */
  124. opacity: 1; /* Fully visible */
  125. color: #4a90e2; /* Blue color */
  126. }
  127.  
  128. .task-table th.sortable.sorted-desc .sort-indicator::after { /* Descending arrow */
  129. content: '▼'; /* Down arrow */
  130. opacity: 1; /* Fully visible */
  131. color: #4a90e2; /* Blue color */
  132. }
  133.  
  134. /*==== @task table body ====*/
  135. .task-table tbody tr { /* Table body rows */
  136. border-bottom: 1px solid #1a1a2e; /* Row separator */
  137. transition: background 0.2s ease; /* Smooth hover */
  138. }
  139.  
  140. .task-table tbody tr:hover { /* Table row hover state */
  141. background: #0f3460; /* Darker background on hover */
  142. }
  143.  
  144. .task-table td { /* Table body cells */
  145. padding: 12px 8px; /* Cell padding */
  146. font-size: 0.9rem; /* Text size */
  147. vertical-align: middle; /* Center vertically */
  148. /* DIAGNOSTIC: Show cell boundaries */
  149. border: 2px solid rgba(255, 0, 0, 0.3) !important;
  150. box-sizing: border-box;
  151. }
  152.  
  153. .task-table th { /* DIAGNOSTIC: Show header boundaries */
  154. border: 2px solid rgba(0, 255, 0, 0.3) !important;
  155. box-sizing: border-box;
  156. }
  157.  
  158. /* DIAGNOSTIC: Show column numbers */
  159. .task-table td[data-col]::before {
  160. content: "[" attr(data-col) "] ";
  161. color: #ff6b9d;
  162. font-weight: bold;
  163. font-size: 0.7rem;
  164. }
  165.  
  166. .task-table th {
  167. position: relative;
  168. }
  169.  
  170. .task-table th:nth-child(1)::before { content: "[1] "; color: #00ff00; font-weight: bold; }
  171. .task-table th:nth-child(2)::before { content: "[2] "; color: #00ff00; font-weight: bold; }
  172. .task-table th:nth-child(3)::before { content: "[3] "; color: #00ff00; font-weight: bold; }
  173. .task-table th:nth-child(4)::before { content: "[4] "; color: #00ff00; font-weight: bold; }
  174. .task-table th:nth-child(5)::before { content: "[5] "; color: #00ff00; font-weight: bold; }
  175. .task-table th:nth-child(6)::before { content: "[6] "; color: #00ff00; font-weight: bold; }
  176. .task-table th:nth-child(7)::before { content: "[7] "; color: #00ff00; font-weight: bold; }
  177. .task-table th:nth-child(8)::before { content: "[8] "; color: #00ff00; font-weight: bold; }
  178. .task-table th:nth-child(9)::before { content: "[9] "; color: #00ff00; font-weight: bold; }
  179. .task-table th:nth-child(10)::before { content: "[10] "; color: #00ff00; font-weight: bold; }
  180. .task-table th:nth-child(11)::before { content: "[11] "; color: #00ff00; font-weight: bold; }
  181. .task-table th:nth-child(12)::before { content: "[12] "; color: #00ff00; font-weight: bold; }
  182.  
  183. /*==== @no tasks message ====*/
  184. .no-tasks-message { /* Empty state message */
  185. text-align: center; /* Center text */
  186. color: #7f8c8d; /* Gray text */
  187. padding: 40px 20px; /* Large padding */
  188. font-style: italic; /* Italic text */
  189. }
  190.  
  191. /*==== @task score cell ====*/
  192. .task-score { /* Score column styling */
  193. font-weight: 600; /* Bold */
  194. font-size: 1rem; /* Larger text */
  195. }
  196.  
  197. /*==== @task name cell ====*/
  198. .task-name { /* Task name column */
  199. font-weight: 500; /* Medium weight */
  200. color: #fff; /* White text */
  201. }
  202.  
  203. /*==== @task bends values ====*/
  204. .task-bends-value { /* BENDS score cells (B, E, N, D, S) */
  205. font-size: 0.85rem; /* Smaller text */
  206. text-align: center; /* Center align */
  207. }
  208.  
  209. /* ================================================================= */
  210. /* ===================== TASK ACTION BUTTONS ======================= */
  211. /* ================================================================= */
  212. /* @task @action @buttons @move @status @view @edit */
  213.  
  214. /* ============================== */
  215. /* ======= BUTTON CONTAINER ===== */
  216. /* ============================== */
  217. /* @container @actions */
  218.  
  219. /*==== @task actions container ====*/
  220. .task-actions { /* Actions column container for task buttons */
  221. display: flex; /* Horizontal layout */
  222. flex-direction: row; /* Explicitly set to row (horizontal) */
  223. gap: 4px; /* Space between buttons */
  224. flex-wrap: wrap; /* Wrap into multiple rows */
  225. max-width: 600px; /* Wider to allow more buttons per row */
  226. align-items: flex-start; /* Align items to top of container */
  227. }
  228.  
  229. /* Star column (1st) - Combined pin + star */
  230. .task-table td:nth-child(1),
  231. .task-table th:nth-child(1) {
  232. min-width: 50px;
  233. width: 50px;
  234. max-width: 50px;
  235. text-align: center;
  236. vertical-align: top;
  237. }
  238.  
  239. /* Details column (2nd) */
  240. .task-table td:nth-child(2),
  241. .task-table th:nth-child(2) {
  242. min-width: 120px;
  243. width: 120px;
  244. max-width: 120px;
  245. vertical-align: top;
  246. }
  247.  
  248. /* Steps column (3rd) */
  249. .task-table td:nth-child(3),
  250. .task-table th:nth-child(3) {
  251. min-width: 95px;
  252. width: 95px;
  253. }
  254.  
  255. /* Score column (4th) */
  256. .task-table td:nth-child(4),
  257. .task-table th:nth-child(4) {
  258. min-width: 55px;
  259. width: 55px;
  260. text-align: center;
  261. }
  262.  
  263. /* Task Name column (5th) - Let it grow */
  264. .task-table td:nth-child(5),
  265. .task-table th:nth-child(5) {
  266. min-width: 250px;
  267. /* No max-width - allow to expand */
  268. }
  269.  
  270. /* Status column (6th) */
  271. .task-table td:nth-child(6),
  272. .task-table th:nth-child(6) {
  273. min-width: 85px;
  274. width: 85px;
  275. }
  276.  
  277. /* Category column (7th) */
  278. .task-table td:nth-child(7),
  279. .task-table th:nth-child(7) {
  280. min-width: 80px;
  281. width: 80px;
  282. }
  283.  
  284. /* Date Added column (8th) */
  285. .task-table td:nth-child(8),
  286. .task-table th:nth-child(8) {
  287. min-width: 75px;
  288. width: 75px;
  289. }
  290.  
  291. /* Due Date column (9th) */
  292. .task-table td:nth-child(9),
  293. .task-table th:nth-child(9) {
  294. min-width: 70px;
  295. width: 70px;
  296. }
  297.  
  298. /* Times Moved column (10th) */
  299. .task-table td:nth-child(10),
  300. .task-table th:nth-child(10) {
  301. min-width: 60px;
  302. width: 60px;
  303. text-align: center;
  304. }
  305.  
  306. /* Last Moved From column (11th) */
  307. .task-table td:nth-child(11),
  308. .task-table th:nth-child(11) {
  309. min-width: 80px;
  310. width: 80px;
  311. }
  312.  
  313. /* Actions column (12th) - Keep horizontal layout */
  314. .task-table td:nth-child(12),
  315. .task-table th:nth-child(12) {
  316. min-width: 400px;
  317. }
  318.  
  319. /* Ensure actions column stays horizontal */
  320. .task-table td:nth-child(12).task-actions {
  321. flex-wrap: wrap; /* Allow wrapping but keep horizontal first */
  322. }
  323.  
  324.  
  325. /* ============================== */
  326. /* ====== ICON BUTTON STYLE ===== */
  327. /* ============================== */
  328. /* @icon @buttons */
  329.  
  330. /*==== @task icon button base ====*/
  331. .task-icon-btn { /* Icon buttons for pin/star */
  332. padding: 6px 10px;
  333. background: rgba(255, 255, 255, 0.1);
  334. border: 2px solid rgba(255, 255, 255, 0.2);
  335. border-radius: 4px;
  336. font-size: 1.1rem;
  337. cursor: pointer;
  338. transition: all 0.2s ease;
  339. display: inline-block;
  340. }
  341.  
  342. /*==== @task icon button hover ====*/
  343. .task-icon-btn:hover {
  344. transform: scale(1.1);
  345. box-shadow: 0 2px 8px rgba(0,0,0,0.3);
  346. }
  347.  
  348. /*==== @pin button red box ====*/
  349. .pin-btn {
  350. background: rgba(231, 76, 60, 0.2); /* Red background */
  351. border-color: var(--color-deleted); /* Red border */
  352. }
  353.  
  354. .pin-btn:hover {
  355. background: var(--color-deleted); /* Solid red on hover */
  356. }
  357.  
  358. /*==== @star button ====*/
  359. .star-btn {
  360. background: rgba(255, 215, 0, 0.15); /* Subtle gold background */
  361. border-color: rgba(255, 215, 0, 0.3);
  362. }
  363.  
  364. .star-btn:hover {
  365. background: rgba(255, 215, 0, 0.25);
  366. border-color: gold;
  367. }
  368.  
  369. /*==== @star column stacked buttons ====*/
  370. .task-star-cell {
  371. display: flex;
  372. flex-direction: column;
  373. gap: 4px;
  374. align-items: center;
  375. overflow: hidden;
  376. }
  377.  
  378. .task-star-cell .task-icon-btn {
  379. box-sizing: border-box;
  380. }
  381.  
  382. /*==== @details column stacked buttons ====*/
  383. .task-details-cell {
  384. display: flex;
  385. flex-direction: column;
  386. gap: 4px;
  387. align-items: stretch;
  388. overflow: hidden;
  389. }
  390.  
  391. .task-details-cell .task-action-btn {
  392. width: 90px;
  393. padding: 2px 4px;
  394. font-size: 0.65rem;
  395. white-space: nowrap;
  396. overflow: hidden;
  397. text-overflow: ellipsis;
  398. box-sizing: border-box;
  399. }
  400.  
  401. /* ============================== */
  402. /* ====== BASE BUTTON STYLE ===== */
  403. /* ============================== */
  404. /* @button @base @style */
  405.  
  406. /*==== @task action button base ====*/
  407. .task-action-btn { /* Individual action button base style */
  408. padding: 3px; /* Small padding for compact buttons */
  409. width: 80px;
  410. background: transparent; /* Transparent background by default */
  411. border: 2px solid; /* Border color set by specific classes */
  412. border-radius: 4px; /* Rounded corners */
  413. font-size: 0.7rem; /* Small text size */
  414. font-weight: 600; /* Semi-bold text */
  415. cursor: pointer; /* Hand cursor on hover */
  416. transition: all 0.2s ease; /* Smooth animation for all properties */
  417. white-space: nowrap; /* Prevent text wrapping */
  418. }
  419.  
  420. /*==== @task action button hover ====*/
  421. .task-action-btn:hover { /* Action button hover state */
  422. transform: scale(1.05); /* Slightly larger on hover */
  423. box-shadow: 0 2px 8px rgba(0,0,0,0.3); /* Shadow on hover */
  424. }
  425.  
  426. /* ======================================= */
  427. /* ========= VIEW/EDIT BUTTONS =========== */
  428. /* ======================================= */
  429. /* @view @edit @buttons */
  430.  
  431. /*==== @view button ====*/
  432. .btn-view { /* View task details button */
  433. border-color: #3498db; /* Blue border */
  434. color: #3498db; /* Blue text */
  435. }
  436.  
  437. /*==== @view button hover ====*/
  438. .btn-view:hover { /* View button hover state */
  439. background: #3498db; /* Blue background */
  440. color: #fff; /* White text */
  441. }
  442.  
  443. /*==== @edit button ====*/
  444. .btn-edit { /* Edit task button */
  445. border-color: #9b59b6; /* Purple border */
  446. color: #9b59b6; /* Purple text */
  447. }
  448.  
  449. /*==== @edit button hover ====*/
  450. .btn-edit:hover { /* Edit button hover state */
  451. background: #9b59b6; /* Purple background */
  452. color: #fff; /* White text */
  453. }
  454.  
  455. /* ======================================= */
  456. /* ====== STATUS MOVEMENT BUTTONS ======== */
  457. /* ======================================= */
  458. /* @status @buttons @move @color-coded */
  459.  
  460. /*==== @active status button ====*/
  461. .btn-active { /* Move to Active status button */
  462. border-color: var(--color-active); /* Green border */
  463. color: var(--color-active); /* Green text */
  464. }
  465.  
  466. /*==== @active status button hover ====*/
  467. .btn-active:hover { /* Active button hover state */
  468. background: var(--color-active); /* Green background */
  469. color: #fff; /* White text */
  470. }
  471.  
  472. /*==== @review status button ====*/
  473. .btn-review { /* Move to Review status button */
  474. border-color: var(--color-review); /* Blue border */
  475. color: var(--color-review); /* Blue text */
  476. }
  477.  
  478. /*==== @review status button hover ====*/
  479. .btn-review:hover { /* Review button hover state */
  480. background: var(--color-review); /* Blue background */
  481. color: #fff; /* White text */
  482. }
  483.  
  484. /*==== @completed status button ====*/
  485. .btn-completed { /* Move to Completed status button */
  486. border-color: var(--color-completed); /* Bright green border */
  487. color: var(--color-completed); /* Bright green text */
  488. }
  489.  
  490. /*==== @completed status button hover ====*/
  491. .btn-completed:hover { /* Completed button hover state */
  492. background: var(--color-completed); /* Bright green background */
  493. color: #fff; /* White text */
  494. }
  495.  
  496. /*==== @future status button ====*/
  497. .btn-future { /* Move to Future status button */
  498. border-color: var(--color-future); /* Blue border (same as review) */
  499. color: var(--color-future); /* Blue text */
  500. }
  501.  
  502. /*==== @future status button hover ====*/
  503. .btn-future:hover { /* Future button hover state */
  504. background: var(--color-future); /* Blue background */
  505. color: #fff; /* White text */
  506. }
  507.  
  508. /*==== @archived status button ====*/
  509. .btn-archived { /* Move to Archived status button */
  510. border-color: var(--color-archived); /* Gray border */
  511. color: var(--color-archived); /* Gray text */
  512. }
  513.  
  514. /*==== @archived status button hover ====*/
  515. .btn-archived:hover { /* Archived button hover state */
  516. background: var(--color-archived); /* Gray background */
  517. color: #fff; /* White text */
  518. }
  519.  
  520. /*==== @dump status button ====*/
  521. .btn-dump { /* Move to Dump status button */
  522. border-color: var(--color-dump); /* Gray border (same as archive) */
  523. color: var(--color-dump); /* Gray text */
  524. }
  525.  
  526. /*==== @dump status button hover ====*/
  527. .btn-dump:hover { /* Dump button hover state */
  528. background: var(--color-dump); /* Gray background */
  529. color: #fff; /* White text */
  530. }
  531.  
  532. /*==== @deleted status button ====*/
  533. .btn-deleted { /* Move to Deleted status button */
  534. border-color: var(--color-deleted); /* Red border */
  535. color: var(--color-deleted); /* Red text */
  536. }
  537.  
  538. /*==== @deleted status button hover ====*/
  539. .btn-deleted:hover { /* Deleted button hover state */
  540. background: var(--color-deleted); /* Red background */
  541. color: #fff; /* White text */
  542. }
  543.  
  544. /*==== @permanent delete button ====*/
  545. .btn-permanent-delete { /* Permanent delete button (only on deleted tab) */
  546. border-color: #8b0000; /* Dark red border */
  547. color: #8b0000; /* Dark red text */
  548. font-weight: 600; /* Semi-bold */
  549. }
  550.  
  551. /*==== @permanent delete button hover ====*/
  552. .btn-permanent-delete:hover { /* Permanent delete button hover state */
  553. background: #8b0000; /* Dark red background */
  554. color: #fff; /* White text */
  555. font-weight: 600; /* Semi-bold */
  556. }
  557.  
  558. /*==== @moo status button ====*/
  559. .btn-moo { /* Move to Moo status button */
  560. border-color: var(--color-moo); /* Purple border (was future's color) */
  561. color: var(--color-moo); /* Purple text */
  562. }
  563.  
  564. /*==== @moo status button hover ====*/
  565. .btn-moo:hover { /* Moo button hover state */
  566. background: var(--color-moo); /* Purple background */
  567. color: #fff; /* White text */
  568. }
  569.  
  570. /* ======================================= */
  571. /* ======= PIN/FAVORITE BUTTONS ========== */
  572. /* ======================================= */
  573. /* @pin @favorite @toggle @buttons */
  574.  
  575. /*==== @pin button ====*/
  576. .btn-pin { /* Pin task button */
  577. width: 25px; /* Specific smaller fixed width */
  578. height: 25px; /* Specific smaller fixed height */
  579. padding: 0; /* Remove padding to fit the icon neatly */
  580. display: flex; /* Use flexbox to center the emoji */
  581. justify-content: center; /* Center horizontally */
  582. align-items: center; /* Center vertically */
  583. font-size: 0.9rem; /* Slightly larger emoji size */
  584. flex-shrink: 0; /* Prevents flexbox from squeezing these buttons border-color: var(--color-pinned); /* Orange border */
  585. color: var(--color-pinned); /* Orange text */
  586. }
  587.  
  588. /*==== @pin button hover ====*/
  589. .btn-pin:hover { /* Pin button hover state */
  590. background: var(--color-pinned); /* Orange background */
  591. color: #fff; /* White text */
  592. }
  593.  
  594. /*==== @unpin button ====*/
  595. .btn-unpin { /* Unpin task button */
  596. width: 25px; /* Specific smaller fixed width */
  597. height: 25px; /* Specific smaller fixed height */
  598. padding: 0; /* Remove padding to fit the icon neatly */
  599. display: flex; /* Use flexbox to center the emoji */
  600. justify-content: center; /* Center horizontally */
  601. align-items: center; /* Center vertically */
  602. font-size: 0.9rem; /* Slightly larger emoji size */
  603. flex-shrink: 0; /* Prevents flexbox from squeezing these buttons border-color: var(--color-pinned); /* Orange border */
  604. border-color: var(--color-pinned); /* Orange border (same as pin) */
  605. color: var(--color-pinned); /* Orange text */
  606. }
  607.  
  608. /*==== @unpin button hover ====*/
  609. .btn-unpin:hover { /* Unpin button hover state */
  610. background: var(--color-pinned); /* Orange background */
  611. color: #fff; /* White text */
  612. }
  613.  
  614. /*==== @favorite button ====*/
  615. .btn-favorite { /* Add to favorites button */
  616. width: 25px; /* Specific smaller fixed width */
  617. height: 25px; /* Specific smaller fixed height */
  618. padding: 0; /* Remove padding to fit the icon neatly */
  619. display: flex; /* Use flexbox to center the emoji */
  620. justify-content: center; /* Center horizontally */
  621. align-items: center; /* Center vertically */
  622. font-size: 0.9rem; /* Slightly larger emoji size */
  623. flex-shrink: 0; /* Prevents flexbox from squeezing these buttons border-color: var(--color-pinned); /* Orange border */
  624. border-color: var(--color-favorite); /* Yellow border */
  625. color: var(--color-favorite); /* Yellow text */
  626. }
  627.  
  628. /*==== @favorite button hover ====*/
  629. .btn-favorite:hover { /* Favorite button hover state */
  630. background: var(--color-favorite); /* Yellow background */
  631. color: #fff; /* White text */
  632. }
  633.  
  634. /*==== @unfavorite button ====*/
  635. .btn-unfavorite { /* Remove from favorites button */
  636. width: 25px; /* Specific smaller fixed width */
  637. height: 25px; /* Specific smaller fixed height */
  638. padding: 0; /* Remove padding to fit the icon neatly */
  639. display: flex; /* Use flexbox to center the emoji */
  640. justify-content: center; /* Center horizontally */
  641. align-items: center; /* Center vertically */
  642. font-size: 0.9rem; /* Slightly larger emoji size */
  643. flex-shrink: 0; /* Prevents flexbox from squeezing these buttons border-color: var(--color-pinned); /* Orange border */
  644. border-color: var(--color-favorite); /* Yellow border (same as favorite) */
  645. color: var(--color-favorite); /* Yellow text */
  646. }
  647.  
  648. /*==== @unfavorite button hover ====*/
  649. .btn-unfavorite:hover { /* Unfavorite button hover state */
  650. background: var(--color-favorite); /* Yellow background */
  651. color: #fff; /* White text */
  652. }
  653.  
  654. /*==== @task category badge ====*/
  655. .task-category-badge { /* Action Status (category) badge */
  656. display: inline-block; /* Inline block */
  657. padding: 4px 10px; /* Badge padding */
  658. border-radius: 12px; /* Rounded pill shape */
  659. font-size: 0.8rem; /* Small text */
  660. font-weight: 600; /* Semi-bold */
  661. color: #fff; /* White text */
  662. text-transform: capitalize; /* Capitalize status text */
  663. }
  664.  
  665. /* Status badge colors */
  666. .status-active { background: var(--color-active); } /* Green */
  667. .status-review { background: var(--color-review); } /* Blue */
  668. .status-completed { background: var(--color-completed); } /* Bright green */
  669. .status-future { background: var(--color-future); } /* Blue (same as review) */
  670. .status-archived { background: var(--color-archived); } /* Gray */
  671. .status-dump { background: var(--color-dump); } /* Gray (same as archive) */
  672. .status-deleted { background: var(--color-deleted); } /* Red */
  673. .status-moo { background: var(--color-moo); } /* Purple */
  674. .status-pinned { background: var(--color-pinned); } /* Orange */
  675. .status-favorite { background: var(--color-favorite); } /* Yellow */
  676. .status-default { background: #7f8c8d; } /* Dark gray for unknown */
  677.  
  678. </style>
  679. </head>
  680. <body>
  681.  
  682. <h1 style="color: #fff; padding: 20px;">BENDS Table Test</h1>
  683.  
  684. <div style="padding: 0 20px 20px 20px;">
  685. <button id="generate-test-data" style="padding: 10px 20px; background: #4a90e2; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 1rem; margin-right: 10px;">Generate Test Tasks</button>
  686. <button id="clear-tasks" style="padding: 10px 20px; background: #e74c3c; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 1rem;">Clear All</button>
  687. </div>
  688.  
  689. <!-- @task table -->
  690. <div class="task-table-container">
  691. <table class="task-table">
  692. <thead>
  693. <tr> <!-- @task list headers -->
  694. <th class="sortable" data-column="isPinned" data-type="boolean">⭐ <span class="sort-indicator"></span></th>
  695. <th>Details</th>
  696. <th class="sortable" data-column="steps" data-type="number">
  697. Steps <span class="sort-indicator"></span>
  698. </th>
  699. <th class="sortable" data-column="priority" data-type="number">
  700. Score <span class="sort-indicator"></span>
  701. </th>
  702. <th class="sortable" data-column="name" data-type="text">
  703. Task<br>Name <span class="sort-indicator"></span>
  704. </th>
  705. <th class="sortable" data-column="status" data-type="text">
  706. Status <span class="sort-indicator"></span>
  707. </th>
  708. <th class="sortable" data-column="category" data-type="text">
  709. Category <span class="sort-indicator"></span>
  710. </th>
  711. <th class="sortable" data-column="dateAdded" data-type="date">
  712. Date<br>Added <span class="sort-indicator"></span>
  713. </th>
  714. <th class="sortable" data-column="dateDue" data-type="date">
  715. Due<br>Date <span class="sort-indicator"></span>
  716. </th>
  717. <th class="sortable" data-column="timesMoved" data-type="number">
  718. Times<br>Moved <span class="sort-indicator"></span>
  719. </th>
  720. <th class="sortable" data-column="lastMovedFrom" data-type="text">
  721. Last Moved<br>From <span class="sort-indicator"></span>
  722. </th>
  723. <th>Actions</th>
  724. </tr>
  725. </thead>
  726. <tbody id="task-table-body">
  727.  
  728.  
  729. <!-- Tasks will be dynamically inserted here -->
  730.  
  731.  
  732. <tr>
  733. <td colspan="12" class="no-tasks-message">No tasks to display. Create a task to get started!</td>
  734. </tr>
  735. </tbody>
  736. </table>
  737.  
  738.  
  739. <script>
  740.  
  741. // Mock TaskManager
  742. const TaskManager = {
  743. tasks: []
  744. };
  745.  
  746. // Mock UI object
  747. const UI = {
  748. viewTask: (index) => {
  749. alert(`View task ${index}: ${TaskManager.tasks[index].name}`);
  750. },
  751. editTask: (index) => {
  752. alert(`Edit task ${index}: ${TaskManager.tasks[index].name}`);
  753. },
  754. permanentDelete: (index) => {
  755. if (confirm('Permanently delete this task?')) {
  756. TaskManager.tasks.splice(index, 1);
  757. UI.renderTaskTable(TaskManager.tasks);
  758. }
  759. },
  760.  
  761. /* ================================================================= */
  762. /* ===================== RENDER TASK TABLE ========================= */
  763. /* ================================================================= */
  764. /* @constant variable UI
  765. @function
  766. @render @task @table
  767. */
  768.  
  769. /*==== @render task table ====*/
  770. //render tasks in table
  771. renderTaskTable(tasks) {
  772.  
  773. /*==== @table body @tbody ====*/
  774. const tbody = document.getElementById('task-table-body');
  775.  
  776. //clear existing content
  777. tbody.innerHTML = '';
  778.  
  779. //if no tasks, show empty message
  780. if (!tasks || tasks.length === 0) {
  781. tbody.innerHTML =
  782. `<tr>
  783. <td colspan="12" class="no-tasks-message">No Tasks to display. Create a task to get started!</td>
  784. </tr>`;
  785. return;
  786. }
  787.  
  788. //render each task as a row
  789. tasks.forEach((task) => {
  790. /*==== @row ====*/
  791. // Find the actual index in TaskManager.tasks
  792. const actualIndex = TaskManager.tasks.indexOf(task);
  793. const row = this.createTaskRow(task, actualIndex);
  794. tbody.appendChild(row);
  795. });
  796. },
  797.  
  798.  
  799. /* ================================================================= */
  800. /* ===================== CREATE TASK ROW =========================== */
  801. /* ================================================================= */
  802. /* @constant variable UI
  803. @function
  804. @create @task @row
  805. */
  806.  
  807. /*==== @create task row ====*/
  808. //create a table row for tasks
  809. createTaskRow(task, index) {
  810.  
  811. /*==== @tr @table row ====*/
  812. const tr = document.createElement('tr');
  813.  
  814. //format date (handle different date formats)
  815. const dateAdded = task.dateCreated || task.created || 'N/A';
  816. const displayDate = dateAdded !== 'N/A' ? dateAdded.split('T')[0] : 'N/A';
  817.  
  818. //get status badge color
  819. const statusColors = {
  820. 'active': 'status-active',
  821. 'review': 'status-review',
  822. 'completed': 'status-completed',
  823. 'future': 'status-future',
  824. 'archived': 'status-archived',
  825. 'dump': 'status-dump',
  826. 'deleted': 'status-deleted',
  827. 'moo': 'status-moo',
  828. 'pinned': 'status-pinned',
  829. 'favorite': 'status-favorite'
  830. };
  831. const statusClass = statusColors[task.status] || 'status-default';
  832.  
  833. // Calculate steps progress
  834. const stepsTotal = task.stepsCount || 0;
  835. const stepsCompleted = task.stepsCompleted || 0;
  836. const stepsPercentage = stepsTotal > 0 ? (stepsCompleted / stepsTotal) * 100 : 0;
  837.  
  838. // Build entire row using innerHTML
  839. tr.innerHTML = `
  840. <td data-col="1" data-col-name="star" class="task-star-cell">
  841. <button class="task-icon-btn pin-btn ${task.isPinned ? 'btn-unpin' : 'btn-pin'}" onclick="ReasonModal.open(${index}, '${task.isPinned ? 'unpin' : 'pin'}')" title="${task.isPinned ? 'Unpin' : 'Pin'}">${task.isPinned ? '📍' : '⭕'}</button>
  842. <button class="task-icon-btn star-btn ${task.isFavorite ? 'btn-unfavorite' : 'btn-favorite'}" onclick="ReasonModal.open(${index}, '${task.isFavorite ? 'unfavorite' : 'favorite'}')" title="${task.isFavorite ? 'Remove from Favorites' : 'Add to Favorites'}">${task.isFavorite ? '⭐' : '✰'}</button>
  843. </td>
  844. <td data-col="2" data-col-name="details" class="task-details-cell">
  845. <button class="task-action-btn btn-view" onclick="UI.viewTask(${index})" title="View Task">👁️ View</button>
  846. <button class="task-action-btn btn-edit" onclick="UI.editTask(${index})" title="Edit Task">✏️ Edit</button>
  847. </td>
  848. <td data-col="3" data-col-name="steps">
  849. <div class="table-steps-progress">
  850. <div class="table-steps-count">${stepsCompleted}/${stepsTotal}</div>
  851. <div class="table-progress-bar-track">
  852. <div class="table-progress-bar-fill" style="width: ${stepsPercentage}%"></div>
  853. </div>
  854. </div>
  855. </td>
  856. <td data-col="4" data-col-name="score" class="task-score">${task.priority ? task.priority.toFixed(1) : '5.0'}</td>
  857. <td data-col="5" data-col-name="name" class="task-name">${task.isTestData ? '🧬 ' : ''}${task.name || 'Unnamed Task'}</td>
  858. <td data-col="6" data-col-name="status"><span class="task-category-badge ${statusClass}">${task.status || 'active'}</span></td>
  859. <td data-col="7" data-col-name="category"><span class="task-category-badge">${task.category || 'None'}</span></td>
  860. <td data-col="8" data-col-name="dateAdded">${displayDate}</td>
  861. <td data-col="9" data-col-name="dateDue">${task.dateDue || 'N/A'}</td>
  862. <td data-col="10" data-col-name="timesMoved">${task.timesMoved || 0}</td>
  863. <td data-col="11" data-col-name="lastMovedFrom">${task.lastMovedFrom || '-'}</td>
  864. <td data-col="12" data-col-name="actions" class="task-actions">
  865. ${task.status !== 'active' ? `<button class="task-action-btn btn-active" onclick="ReasonModal.open(${index}, 'active')" title="Move to Active">🟢 Active</button>` : ''}
  866. ${task.status !== 'review' ? `<button class="task-action-btn btn-review" onclick="ReasonModal.open(${index}, 'review')" title="Move to Review">🔍 Review</button>` : ''}
  867. ${task.status !== 'completed' ? `<button class="task-action-btn btn-completed" onclick="ReasonModal.open(${index}, 'completed')" title="Move to Completed">✅ Done</button>` : ''}
  868. ${task.status !== 'future' ? `<button class="task-action-btn btn-future" onclick="ReasonModal.open(${index}, 'future')" title="Move to Future">🔮 Future</button>` : ''}
  869. ${task.status !== 'archived' ? `<button class="task-action-btn btn-archived" onclick="ReasonModal.open(${index}, 'archived')" title="Archive">📦 Archive</button>` : ''}
  870. ${task.status !== 'dump' ? `<button class="task-action-btn btn-dump" onclick="ReasonModal.open(${index}, 'dump')" title="Move to Dump">🗑️ Dump</button>` : ''}
  871. ${task.status !== 'deleted' ? `<button class="task-action-btn btn-deleted" onclick="ReasonModal.open(${index}, 'deleted')" title="Delete">❌ Delete</button>` : ''}
  872. ${task.status !== 'moo' ? `<button class="task-action-btn btn-moo" onclick="ReasonModal.open(${index}, 'moo')" title="Move to Moo">🐄 Moo</button>` : ''}
  873. ${task.status === 'deleted' ? `<button class="task-action-btn btn-permanent-delete" onclick="UI.permanentDelete(${index})" title="Permanently Delete (Cannot be undone)">💀 Permanent Delete</button>` : ''}
  874. </td>
  875. `;
  876.  
  877. return tr;
  878. }
  879. };
  880.  
  881. // Mock ReasonModal
  882. const ReasonModal = {
  883. open: (index, action) => {
  884. const task = TaskManager.tasks[index];
  885. alert(`Action: ${action}\nTask: ${task.name}`);
  886.  
  887. // Simulate status changes
  888. if (['active', 'review', 'completed', 'future', 'archived', 'dump', 'deleted', 'moo'].includes(action)) {
  889. task.status = action;
  890. UI.renderTaskTable(TaskManager.tasks);
  891. } else if (action === 'pin') {
  892. task.isPinned = true;
  893. UI.renderTaskTable(TaskManager.tasks);
  894. } else if (action === 'unpin') {
  895. task.isPinned = false;
  896. UI.renderTaskTable(TaskManager.tasks);
  897. } else if (action === 'favorite') {
  898. task.isFavorite = true;
  899. UI.renderTaskTable(TaskManager.tasks);
  900. } else if (action === 'unfavorite') {
  901. task.isFavorite = false;
  902. UI.renderTaskTable(TaskManager.tasks);
  903. }
  904. }
  905. };
  906.  
  907. // Generate test tasks
  908. function generateTestTasks() {
  909. TaskManager.tasks = [
  910. {
  911. name: "Test Task 1 - Active",
  912. status: "active",
  913. category: "Work",
  914. priority: 7.5,
  915. stepsCount: 5,
  916. stepsCompleted: 2,
  917. isPinned: false,
  918. isFavorite: true,
  919. dateCreated: "2025-12-13",
  920. dateDue: "2025-12-20",
  921. timesMoved: 0,
  922. lastMovedFrom: "-",
  923. isTestData: true
  924. },
  925. {
  926. name: "Test Task 2 - Review",
  927. status: "review",
  928. category: "Personal",
  929. priority: 6.2,
  930. stepsCount: 3,
  931. stepsCompleted: 1,
  932. isPinned: true,
  933. isFavorite: false,
  934. dateCreated: "2025-12-12",
  935. dateDue: "2025-12-18",
  936. timesMoved: 2,
  937. lastMovedFrom: "Active",
  938. isTestData: true
  939. },
  940. {
  941. name: "Test Task 3 - Future",
  942. status: "future",
  943. category: "Learning",
  944. priority: 8.9,
  945. stepsCount: 10,
  946. stepsCompleted: 0,
  947. isPinned: false,
  948. isFavorite: false,
  949. dateCreated: "2025-12-11",
  950. dateDue: "N/A",
  951. timesMoved: 0,
  952. lastMovedFrom: "-",
  953. isTestData: true
  954. },
  955. {
  956. name: "Test Task 4 - Completed",
  957. status: "completed",
  958. category: "Work",
  959. priority: 9.1,
  960. stepsCount: 8,
  961. stepsCompleted: 8,
  962. isPinned: false,
  963. isFavorite: true,
  964. dateCreated: "2025-12-10",
  965. dateDue: "2025-12-15",
  966. timesMoved: 5,
  967. lastMovedFrom: "Review",
  968. isTestData: true
  969. },
  970. {
  971. name: "Test Task 5 - Archived",
  972. status: "archived",
  973. category: "Personal",
  974. priority: 5.0,
  975. stepsCount: 4,
  976. stepsCompleted: 4,
  977. isPinned: false,
  978. isFavorite: false,
  979. dateCreated: "2025-12-09",
  980. dateDue: "2025-12-14",
  981. timesMoved: 3,
  982. lastMovedFrom: "Completed",
  983. isTestData: true
  984. }
  985. ];
  986.  
  987. UI.renderTaskTable(TaskManager.tasks);
  988. }
  989.  
  990. // Event listeners
  991. document.getElementById('generate-test-data').addEventListener('click', generateTestTasks);
  992. document.getElementById('clear-tasks').addEventListener('click', () => {
  993. TaskManager.tasks = [];
  994. UI.renderTaskTable(TaskManager.tasks);
  995. });
  996.  
  997. // Initial render
  998. UI.renderTaskTable(TaskManager.tasks);
  999.  
  1000. </script>
  1001. </body>
  1002. </html>
Advertisement
Add Comment
Please, Sign In to add comment