From 974f0c24da9620d2160b50c109f7bdc178f55e49 Mon Sep 17 00:00:00 2001 From: somu0571 Date: Sun, 17 May 2026 11:44:24 +0900 Subject: [PATCH 1/4] Add roadmap progress tracker and completion UI --- .gitignore | Bin 2465 -> 2598 bytes static/script.js | 49 ++++++++++++++++ static/style.css | 125 ++++++++++++++++++++++++++++++++++++++++- templates/project.html | 125 ++++++++++++++++++++++++++++++++--------- 4 files changed, 272 insertions(+), 27 deletions(-) diff --git a/.gitignore b/.gitignore index 637039558acb76f26c528474e830a9d831e2e7b6..f24e00a1739b4740aa85aaf9e5819d7968e812ff 100644 GIT binary patch literal 2598 zcmb7G+m72d5cRVG|AT{lGhhmBKcLuVo1j38EV2*nn?O-xnQMw9NJ_T*^*y7TEqk*~ zV89~h&f%FEKCJ)JQIRpyl565>xe?09*e#4x2PPO-@yDMPf8x=vmZE61DZ$9F-s_lL zIIoud?_vGPG$~P72l8$kJt@7@(9H^MGbPoYpw(@(g_xBlE1XL)1?fd0)3=#%Kk#a8 zE1lR(No`h;Rr^|oL(FQbWL`;QD4ZuYY-b`M3{QDU9*67Im@aJ@oG$a^oQb0bjA|rB z7TM!(fnsA)+=$oc?4VgX6*K%z^1R>mrxwf<|7v8Z^U}#0UCd;CQ*d6yS=MHd<6Klh zChcsVC?d4YCOfGnQYdAT?@2wolF#I&I>?HqNHXPG3ZTF>77>Zku-<7yYvpW`+9K8K8Y$4*fLnr0+QXX|Wkp36UJ{jj{nO=VPco$Jxha4G({phi z&YAQY0f`d)F6+D*a<}!SskCMDHXmEDGyWuh(X%a*}e*qmrb$t zh{VZqJ3^3&aNa=~-@#)Jq+0;qXnUX%JI-xm`|WI#cUQ=4KKEk}q}g!?aPdvzYD+`g zBQWkMh*ud9RZoO(2#m5y`qTh)b80VnoJkI}zGSW}pl+oRJ~%i^W4cE3ko!Dd*mIZd zua~^N$`(MoGIgNy+>m%Z4CmEfUb25ax{_um)~>_tM%3W^)c(?0n-PD$C$>~>Wz;3j zrG0T?^xqHxWK>SlE!`N3XUheN=m&oy0>M#NR+NR&X=Ys{S;fsvx|K+%<)(5m@k9ZR z$|n@yjQ$5K|9UORB{-81@mw=z=2Tn?m)5oBb%_s-FC}#``Kj+NnLu|=d576tqvQsa zk^Shs*acbB(FJbaeKJPw@cj-6kMkhScNQk>h?7DNcA7`S+zI(T)#wOlY&RT0A9a0t zlioGV8~I&-<{a~g&=2qQMn0XqLo*@U>fmfm=m0z^25T=AxSK!G4!w-qYaBY>!2jA< zG_ZH70x;nMuci9((peqTIi0i*?ScV_q7Fu}DQ9=}7LR&|afd+W8k6CUcR>jJa3p_g zTe>6a5Q@isJx-r@+oJ04^G8(rH2$AP6snd7z?!4`Q`@G$W8l9z{YYfruh7T!zWgkz zkHainEw82`hx>A_3ygkDMxYbVn{ms$-%pBs2bpzpYgxd?Iy8o&SS>#c@WH2~oy35= z^t^BIy4LpwZ)$XJ@#g*R!`+l0UM~D($oQdvKh(nYxa^)2JcFj0jp)0#iPB8|Of@$p Zyz|sSw5TG$tXLp*FM@s6JdKSkz zXsM00ysFZN)n7VFGDcW(eXQ0@8WHo;IJqy67I%M^xW}WfSkr5xjB9ztb~+{(&K0f? ztIwuSiNY$7cbn)*>aCU)Z?xr7$Q|+FU0VoQVR++QiYW-s8j;@Q#ofT_v~6{Q4Mhju zkd?bmgni^4wW4l?F%-@d7j`)daKKZo$j4DBlZ92mX;mlZOdRE5Q6mGQ;rG7>ioHp3 z&7PyPgPw9Sa@;2A{J9-sWtqqR)qW;vbTgOqeUo#+&Z0AeR8Bw}MAFXIi6Wd@ulY&# zk%AIQyd(7J6k_p0?nO%%C%AM63ZU=`&j_=XKz`3r$NG|}As$p|(q3(~p_Ozt32l+v zRfo9sCZH&gNxN9FNtCr@aX=z9D>Hu(A@Rq)LA_1kA&Q(O;WdzdtGV;CNgzDKxH1^h@M<9R8Se(9D!d?fjx^*v4O^O2$Q4~KJ@_A zf;h+>=W-*dw8BgsJtz$G!QqTFW@j=Du`g3$9!qM!U(@s~4q|S9Pv?ah_Pj4a>Tgf{ zpHEKFJWTBhCfBS3T*w#miZ=V456hLM`;g2-B{$;!mN_nvKo=;-Le{+2lk{aC;w4&?P#{{j(q zl8Ah(G0lf+PREnqQHTCEw+tW~t$KQmoJZb`ne7m3jpad@X>YOV*@F(wc7&G3 zh#ze|QOKkCfwq`Qc|gWtZjJ2ky~QAU2leaRx1EsRp0dRk0T!n&^@bd9J_%j&^rDsG zQEyYWw^Uf9?TQATUHDsD<&I^R9f#LxW4t@tWU1cIXq3$TNFg%Wi9Kb<{?xWF1qH(U z(@!|{|K*EI?~BhI`ZVsY>bk_>=F_=ru%D}pK>T%#Uts)klH?08R>`eI1MOAl4MkSn zjUd58(NOAjq+<^7@dMg`0?~luNt?tS% UjntX?g}OXv%D)#oph + var step = cb.closest(".roadmap-step"); + + if(cb.checked){ + completed++; + if(step) step.classList.add("completed"); + } else { + if(step) step.classList.remove("completed"); + } + + }); + + var percent = Math.round( + (completed / roadmapCheckboxes.length) * 100 + ); + + if(progressFill){ + progressFill.style.width = percent + "%"; + } + + if(progressText){ + progressText.textContent = + percent + "% completed"; + } +} + +roadmapCheckboxes.forEach(function(cb){ + cb.addEventListener( + "change", + updateRoadmapProgress + ); +}); + +updateRoadmapProgress(); var copyToast = document.getElementById("copy-toast"); var toastTimeout = null; diff --git a/static/style.css b/static/style.css index 837c450..c32dfbf 100644 --- a/static/style.css +++ b/static/style.css @@ -1340,7 +1340,65 @@ select:focus { margin: 4px 0; } .roadmap-step:last-child .roadmap-line { display: none; } -.roadmap-content { padding: 0 0 28px 16px; flex: 1; } +/* Roadmap timeline structure */ +.roadmap-timeline{ + display:flex; + flex-direction:column; + width:100%; + padding:0; + margin:0; +} + +.roadmap-step{ + display:flex; + width:100%; + list-style:none; +} + +.roadmap-marker{ + display:flex; + flex-direction:column; + align-items:center; + flex-shrink:0; + width:36px; +} + +.roadmap-dot{ + width:14px; + height:14px; + border-radius:50%; + background:var(--indigo-600); + border:3px solid var(--indigo-100); + margin-top:4px; +} + +.roadmap-line{ + flex:1; + width:2px; + background:var(--border); + margin:4px 0; +} + +.roadmap-step:last-child .roadmap-line{ + display:none; +} +.roadmap-content{ + padding:0 0 28px 16px; + flex:1; +} + +/* keep checkbox row aligned */ +.roadmap-step-label{ + display:flex; + align-items:flex-start; + gap:12px; +} + +.roadmap-text-wrap{ + display:flex; + flex-direction:column; + gap:6px; +} .roadmap-step-num { display: inline-block; font-size: 0.72rem; @@ -1354,6 +1412,71 @@ select:focus { } .roadmap-step-text { font-size: 0.92rem; color: var(--text-body); line-height: 1.65; } + +.roadmap-checkbox { + margin-top: 5px; + width: 18px; + height: 18px; + accent-color: var(--indigo-600); + cursor: pointer; + transform: scale(1.05); +} + +/* Completed state */ +.roadmap-step.completed .roadmap-step-text, +.roadmap-step.completed .roadmap-step-num { + text-decoration: line-through; + opacity: 0.55; +} + +/* Make completed node visually */ +.roadmap-step.completed .roadmap-dot { + background: var(--green-500); + box-shadow: 0 0 0 4px rgba(16, 185, 129, 0.15); +} + +/* Progress container */ +.roadmap-progress-wrap{ + display:flex; + align-items:center; + gap:14px; + width:100%; + margin:18px 0 28px; +} + +/* Actual bar */ +.roadmap-progress-bar{ + flex:1; + width:100%; + min-width:300px; /* prevents collapsing */ + height:10px; + background:#e5e7eb; + border-radius:999px; + overflow:hidden; + border:1px solid #d1d5db; +} + +/* Fill animation */ +#roadmap-progress-fill{ + height:100%; + width:0%; + border-radius:999px; + background:linear-gradient( + 90deg, + #4f46e5, + #9333ea + ); + transition:width .35s ease; +} + +/* Percentage text */ +#roadmap-progress-text{ + white-space:nowrap; + min-width:120px; + font-size:.85rem; + font-weight:600; + color:#6b7280; +} /* Resources list */ .resource-list { display: flex; flex-direction: column; gap: 10px; } .resource-item { display: flex; } diff --git a/templates/project.html b/templates/project.html index 8825844..a66bca8 100644 --- a/templates/project.html +++ b/templates/project.html @@ -94,33 +94,106 @@

Features

-
-
-
- -
-

Project Roadmap

+ +
+ + +
+ +
+ + + + + +
+ +

Project Roadmap

+ +
+ + + +

+ Follow these steps in order. + Each one builds on the previous. +

+ + + +
+ +
+
+
+ + + 0% completed + + +
+ + + +
    + + {% for step in project.roadmap %} + +
  1. + + +
    + + + + +
    -

    Follow these steps in order. Each one builds on the previous.

    - - -
      - {% for step in project.roadmap %} -
    1. -
      - - -
      -
      - - Step {{ loop.index }} - -

      {{ step | replace("Step " + loop.index|string + ": ", "") }}

      -
      -
    2. - {% endfor %} -
    -
+ + + +
+ + + +
+ + + + {% endfor %} + + + +
From 18a725a4455a36c924ff503bfad9691464216bcc Mon Sep 17 00:00:00 2001 From: somu0571 Date: Sun, 17 May 2026 20:09:02 +0900 Subject: [PATCH 2/4] Add roadmap persistence and accessibility improvements --- static/script.js | 144 +++++++++++++++++++++++++++++++++++++---- static/style.css | 2 +- templates/project.html | 31 +++++---- 3 files changed, 154 insertions(+), 23 deletions(-) diff --git a/static/script.js b/static/script.js index c79d0e1..6fc7a67 100644 --- a/static/script.js +++ b/static/script.js @@ -631,50 +631,172 @@ if (isDetailPage) { // ROADMAP PROGRESS TRACKER // ============================================================ -var roadmapCheckboxes = document.querySelectorAll(".roadmap-checkbox"); -var progressFill = document.getElementById("roadmap-progress-fill"); -var progressText = document.getElementById("roadmap-progress-text"); -function updateRoadmapProgress() { - if (!roadmapCheckboxes.length) return; +var roadmapCheckboxes = document.querySelectorAll( + ".roadmap-checkbox" +); + +var progressFill = document.getElementById( + "roadmap-progress-fill" +); + +var progressText = document.getElementById( + "roadmap-progress-text" +); + +var progressBar = document.querySelector( + ".roadmap-progress-bar" +); + +// Local storage key +var roadmapStorageKey = + "devpath-roadmap-progress"; + + +// ------------------------------------------------------------ +// Restore saved roadmap state +// ------------------------------------------------------------ + +var savedRoadmapState = + localStorage.getItem( + roadmapStorageKey + ); + +if(savedRoadmapState){ + + try{ + + var parsedState = + JSON.parse(savedRoadmapState); + + roadmapCheckboxes.forEach( + function(cb,index){ + + cb.checked = + !!parsedState[index]; + + } + ); + + } catch(error){ + + console.error( + "Failed to restore roadmap progress", + error + ); + + } +} + + +// ------------------------------------------------------------ +// Update roadmap progress +// ------------------------------------------------------------ + +function updateRoadmapProgress(){ + + if(!roadmapCheckboxes.length){ + return; + } var completed = 0; roadmapCheckboxes.forEach(function(cb){ - // find parent
  • - var step = cb.closest(".roadmap-step"); + var step = cb.closest( + ".roadmap-step" + ); if(cb.checked){ + completed++; - if(step) step.classList.add("completed"); + + if(step){ + step.classList.add( + "completed" + ); + } + } else { - if(step) step.classList.remove("completed"); + + if(step){ + step.classList.remove( + "completed" + ); + } + } }); var percent = Math.round( - (completed / roadmapCheckboxes.length) * 100 + (completed / roadmapCheckboxes.length) + * 100 ); + // Update progress bar fill if(progressFill){ - progressFill.style.width = percent + "%"; + + progressFill.style.width = + percent + "%"; + } + // Update progress text if(progressText){ + progressText.textContent = percent + "% completed"; + } + + // Accessibility update + if(progressBar){ + + progressBar.setAttribute( + "aria-valuenow", + percent + ); + + } + + // Save checkbox state + var savedState = []; + + roadmapCheckboxes.forEach(function(cb){ + + savedState.push( + cb.checked + ); + + }); + + localStorage.setItem( + roadmapStorageKey, + JSON.stringify(savedState) + ); + } + +// ------------------------------------------------------------ +// Attach checkbox listeners +// ------------------------------------------------------------ + roadmapCheckboxes.forEach(function(cb){ + cb.addEventListener( "change", updateRoadmapProgress ); + }); + +// ------------------------------------------------------------ +// Initial progress render +// ------------------------------------------------------------ + updateRoadmapProgress(); var copyToast = document.getElementById("copy-toast"); var toastTimeout = null; diff --git a/static/style.css b/static/style.css index c32dfbf..c388a8b 100644 --- a/static/style.css +++ b/static/style.css @@ -1448,7 +1448,7 @@ select:focus { .roadmap-progress-bar{ flex:1; width:100%; - min-width:300px; /* prevents collapsing */ + max-width:100%; height:10px; background:#e5e7eb; border-radius:999px; diff --git a/templates/project.html b/templates/project.html index a66bca8..2c3f72e 100644 --- a/templates/project.html +++ b/templates/project.html @@ -127,19 +127,28 @@

    Project Roadmap

    - -
    - -
    -
    -
    - - - 0% completed - - + +
    + +
    +
    + + 0% completed + + +
      From 1700facc07c2597dc7e796a4703432ec9257df4f Mon Sep 17 00:00:00 2001 From: SOMSUBHRA CHATTERJEE Date: Mon, 18 May 2026 01:42:57 +0900 Subject: [PATCH 3/4] No Changes Made --- .gitignore | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) diff --git a/.gitignore b/.gitignore index e69de29..89060cf 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1,122 @@ +# Miscellaneous +*.class +*.lock +*.log +*.pyc +*.swp +.buildlog/ +.history + + + +# Flutter repo-specific +/bin/cache/ +/bin/internal/bootstrap.bat +/bin/internal/bootstrap.sh +/bin/mingit/ +/dev/benchmarks/mega_gallery/ +/dev/bots/.recipe_deps +/dev/bots/android_tools/ +/dev/devicelab/ABresults*.json +/dev/docs/doc/ +/dev/docs/flutter.docs.zip +/dev/docs/lib/ +/dev/docs/pubspec.yaml +/dev/integration_tests/**/xcuserdata +/dev/integration_tests/**/Pods +/packages/flutter/coverage/ +version +analysis_benchmark.json + +# packages file containing multi-root paths +.packages.generated + +# Flutter/Dart/Pub related +**/doc/api/ +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +**/generated_plugin_registrant.dart +.packages +.pub-preload-cache/ +.pub/ +build/ +flutter_*.png +linked_*.ds +unlinked.ds +unlinked_spec.ds + +# Android related +**/android/**/gradle-wrapper.jar +.gradle/ +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java +**/android/key.properties +*.jks + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/.last_build_id +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Flutter.podspec +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/ephemeral +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/Flutter/flutter_export_environment.sh +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# macOS +**/Flutter/ephemeral/ +**/Pods/ +**/macos/Flutter/GeneratedPluginRegistrant.swift +**/macos/Flutter/ephemeral +**/xcuserdata/ + +# Windows +**/windows/flutter/generated_plugin_registrant.cc +**/windows/flutter/generated_plugin_registrant.h +**/windows/flutter/generated_plugins.cmake + +# Linux +**/linux/flutter/generated_plugin_registrant.cc +**/linux/flutter/generated_plugin_registrant.h +**/linux/flutter/generated_plugins.cmake + +# Coverage +coverage/ + +# Symbols +app.*.symbols + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +!/dev/ci/**/Gemfile.lock.venv/ +# Python virtual environment +venv/ +.venv/ From beefe1368b4c7a4a7083f01bdc8241cd51c5ebcf Mon Sep 17 00:00:00 2001 From: somu0571 Date: Tue, 2 Jun 2026 21:55:36 +0530 Subject: [PATCH 4/4] fix: scope roadmap progress storage by project id --- static/script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/script.js b/static/script.js index e054410..01d093d 100644 --- a/static/script.js +++ b/static/script.js @@ -816,7 +816,7 @@ var progressBar = document.querySelector( // Local storage key var roadmapStorageKey = - "devpath-roadmap-progress"; + `devpath-roadmap-progress-${PROJECT_ID}`; // ------------------------------------------------------------