enhancement: added interactive walkthrough to guide new users - #25
Conversation
WalkthroughAdds Tailwind integration and new dependencies, introduces first-launch detection in App that routes to a new multi-step GuidePage onboarding component, adds a “Tutorial” option to HomeOptions, and updates the Tauri API and related plugins. Changes
Sequence DiagramsequenceDiagram
participant App
participant LocalStorage
participant GuidePage
participant TauriStore
participant User
rect rgb(250,250,255)
Note over App,LocalStorage: First-launch detection
App->>LocalStorage: read "hasLaunched"
alt not found
LocalStorage-->>App: null
App->>LocalStorage: write "hasLaunched" = true
App->>App: set currentPage = "open-guide"
App->>GuidePage: render GuidePage
else found
LocalStorage-->>App: true
App->>App: set currentPage = "home"
end
end
rect rgb(240,255,240)
Note over GuidePage,User: Onboarding flow (pages 0–6)
User->>GuidePage: mount
GuidePage->>TauriStore: init settings (optional)
loop for each page
User->>GuidePage: click Next / submit
alt name form page
GuidePage->>GuidePage: validate via react-hook-form
GuidePage->>LocalStorage: save name
end
GuidePage->>GuidePage: increment page state
end
Note over GuidePage,User: final page completes onboarding
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Areas to check:
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 10
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (5)
package-lock.jsonis excluded by!**/package-lock.json,!**/package-lock.jsonsrc/assets/snapshort2.pngis excluded by!**/*.pngsrc/assets/snapshort3.pngis excluded by!**/*.pngsrc/assets/snapshort4.pngis excluded by!**/*.pngsrc/assets/snapshot1.pngis excluded by!**/*.png
📒 Files selected for processing (6)
package.json(1 hunks)src/App.css(1 hunks)src/App.jsx(3 hunks)src/components/HomeOptions.jsx(1 hunks)src/components/guidePages/GuidePage.jsx(1 hunks)vite.config.js(1 hunks)
🧰 Additional context used
🪛 Biome (2.1.2)
src/components/guidePages/GuidePage.jsx
[error] 93-93: Provide an explicit type prop for the button element.
The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset
(lint/a11y/useButtonType)
[error] 119-119: Provide an explicit type prop for the button element.
The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset
(lint/a11y/useButtonType)
[error] 137-137: Provide an explicit type prop for the button element.
The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset
(lint/a11y/useButtonType)
[error] 155-155: Provide an explicit type prop for the button element.
The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset
(lint/a11y/useButtonType)
🔇 Additional comments (4)
vite.config.js (1)
3-3: Tailwind v4 Vite plugin integration looks correct.Import and registration align with Tailwind v4’s recommended setup. No issues spotted here.
Also applies to: 9-9
src/App.css (1)
1-1: Tailwind v4 import is correct.Using @import "tailwindcss"; at the top matches v4 guidance. No issues. Based on Tailwind v4 notes.
src/components/guidePages/GuidePage.jsx (1)
3-6: Fix alt text attributes in image tags.The current imports and paths are correct—the actual files include the "snapshort" typo (snapshort2.png, snapshort3.png, snapshort4.png exist). However, two img tags have incorrect alt attributes:
- Line 150: change
alt='snapshot1'toalt='snapshot3'- Line 155: change
alt='snapshot1'toalt='snapshot4'Do not change the import paths as suggested in the original review—those files do not exist. The paths correctly reference the actual files in the assets directory.
Likely an incorrect or invalid review comment.
src/components/HomeOptions.jsx (1)
10-10: LGTM! Code change is complete and correct.The new Tutorial option integrates seamlessly with existing routing. The
"open-guide"page value is already fully handled inApp.jsx—it conditionally rendersGuidePage(line 82) and manages UI visibility (line 62). The routing chain works as expected:HomeOptions→onSelect(item.page)→setCurrentPage()→ conditional rendering inApp.jsx.
| "@tailwindcss/vite": "^4.1.16", | ||
| "@tauri-apps/api": "^2.9.0", | ||
| "@tauri-apps/plugin-fs": "^2.4.3", | ||
| "@tauri-apps/plugin-global-shortcut": "^2.3.0", | ||
| "@tauri-apps/plugin-opener": "^2.5.0", | ||
| "fuse.js": "^7.1.0", | ||
| "react": "^18.3.1", | ||
| "react-dom": "^18.3.1" | ||
| "react-dom": "^18.3.1", | ||
| "react-hook-form": "^7.65.0", | ||
| "tailwindcss": "^4.1.16" | ||
| }, |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Move build‑time tools to devDependencies (optional).
@tailwindcss/vite and tailwindcss are build‑time; consider moving them to devDependencies to reduce install footprint at runtime.
🤖 Prompt for AI Agents
In package.json around lines 16 to 26, move build-time tools "@tailwindcss/vite"
and "tailwindcss" from dependencies into devDependencies to avoid shipping them
at runtime; update the package.json by removing those two entries from
"dependencies" and adding identical entries under "devDependencies" (preserve
versions) and run npm/yarn install to update lockfile.
🧩 Analysis chain
Blocker: GuidePage imports @tauri-apps/plugin-store but it’s not declared.
GuidePage.jsx imports Store from @tauri-apps/plugin-store, but package.json lacks that dependency. Builds will fail (or the app will crash at runtime). Decide one path:
- Prefer simpler: remove Store usage and rely on localStorage for first‑launch (see GuidePage.jsx comments).
- Or keep Store: add the dependency and wire the plugin on the Rust side.
If you keep Store, add to dependencies:
"dependencies": {
+ "@tauri-apps/plugin-store": "^2.4.0",
"@tailwindcss/vite": "^4.1.16",
"@tauri-apps/api": "^2.9.0",
"@tauri-apps/plugin-fs": "^2.4.3",Run to check for mismatches:
🏁 Script executed:
#!/bin/bash
rg -n "@tauri-apps/plugin-store|\\bnew Store\\b|from '@tauri-apps/plugin-store'"
jq '.dependencies' package.jsonLength of output: 774
Add missing @tauri-apps/plugin-store dependency to package.json.
GuidePage.jsx imports and uses Store from @tauri-apps/plugin-store (lines 7, 16), but the dependency is missing from package.json. While package-lock.json contains the entry (^2.4.1), package.json must explicitly declare all direct dependencies. Add it to dependencies:
"dependencies": {
+ "@tauri-apps/plugin-store": "^2.4.1",
"@tailwindcss/vite": "^4.1.16",
"@tauri-apps/api": "^2.9.0",
"@tauri-apps/plugin-fs": "^2.4.3",📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "@tailwindcss/vite": "^4.1.16", | |
| "@tauri-apps/api": "^2.9.0", | |
| "@tauri-apps/plugin-fs": "^2.4.3", | |
| "@tauri-apps/plugin-global-shortcut": "^2.3.0", | |
| "@tauri-apps/plugin-opener": "^2.5.0", | |
| "fuse.js": "^7.1.0", | |
| "react": "^18.3.1", | |
| "react-dom": "^18.3.1" | |
| "react-dom": "^18.3.1", | |
| "react-hook-form": "^7.65.0", | |
| "tailwindcss": "^4.1.16" | |
| }, | |
| "@tauri-apps/plugin-store": "^2.4.1", | |
| "@tailwindcss/vite": "^4.1.16", | |
| "@tauri-apps/api": "^2.9.0", | |
| "@tauri-apps/plugin-fs": "^2.4.3", | |
| "@tauri-apps/plugin-global-shortcut": "^2.3.0", | |
| "@tauri-apps/plugin-opener": "^2.5.0", | |
| "fuse.js": "^7.1.0", | |
| "react": "^18.3.1", | |
| "react-dom": "^18.3.1", | |
| "react-hook-form": "^7.65.0", | |
| "tailwindcss": "^4.1.16" | |
| }, |
🤖 Prompt for AI Agents
In package.json around lines 16 to 26, the project is missing the direct
dependency "@tauri-apps/plugin-store" which is imported by GuidePage.jsx; add
"@tauri-apps/plugin-store" to the dependencies object (use the version found in
package-lock.json, e.g. "^2.4.1") and then run npm install (or yarn) to update
node_modules and the lockfile so the declared dependency and installed version
stay in sync.
| const [firstLaunchChecked, setFirstLaunchChecked] = useState(false); | ||
|
|
There was a problem hiding this comment.
Blocker: First‑launch logic always opens the guide; flag saved too early.
You’re setting hasLaunched=true on first mount and never reading it, so the guide shows every time. Read the flag and only show the guide when missing. Save the flag after completion (GuidePage sets it at page 6 per its fix).
- const [firstLaunchChecked, setFirstLaunchChecked] = useState(false);
+ const [firstLaunchChecked, setFirstLaunchChecked] = useState(false);
...
- useEffect(() => {
-
- if(firstLaunchChecked === false){
- localStorage.setItem("hasLaunched", "true");
- setCurrentPage("open-guide")
- console.log()
- }
- else{
- setCurrentPage("home")
- }
- setFirstLaunchChecked(true)
-
- },[])
+ useEffect(() => {
+ const hasLaunched = localStorage.getItem("hasLaunched") === "true";
+ setCurrentPage(hasLaunched ? "home" : "open-guide");
+ setFirstLaunchChecked(true);
+ }, []);Also applies to: 18-30
🤖 Prompt for AI Agents
In src/App.jsx around lines 15 to 30, the first-launch logic currently sets
hasLaunched=true on mount and never reads the persisted flag, which causes the
guide to open every time; change the flow to read the saved hasLaunched flag
from storage/localStorage on component mount, update firstLaunchChecked once the
read completes, and only open the Guide when the stored flag is missing/false;
remove any code that writes hasLaunched on mount and instead ensure the
GuidePage writes/saves hasLaunched=true after the user finishes the guide (page
6) so the app won’t reopen it on subsequent launches.
| className={`search-input ${currentPage === "open-guide" ? "hidden" : "block"}`} | ||
| /> |
There was a problem hiding this comment.
Minor: Passing unused prop to GuidePage.
GuidePage doesn’t consume query; you can drop it to reduce prop churn.
- {currentPage === "open-guide" && <GuidePage query={query} />}
+ {currentPage === "open-guide" && <GuidePage />}Also applies to: 82-83
🤖 Prompt for AI Agents
In src/App.jsx around lines 62-63 (and also at 82-83), the GuidePage is being
passed a prop named "query" which GuidePage does not use; remove the query prop
from the GuidePage JSX at both locations so the component receives only the
props it needs, and run a quick grep to confirm no other places pass an unused
"query" prop to GuidePage.
| import snapshot2 from "../../assets/snapshort2.png" | ||
| import snapshot3 from "../../assets/snapshort3.png" | ||
| import snapshort4 from "../../assets/snapshort4.png" | ||
| import { Store } from '@tauri-apps/plugin-store'; |
There was a problem hiding this comment.
Remove unguarded Tauri Store usage (or gate it), and set the launch flag on completion.
Current code creates .settings.json and writes firstLaunch=true on every mount, requires an undeclared plugin, and isn’t used elsewhere. Prefer localStorage (already used) and set the flag when the walkthrough completes:
-import { Store } from '@tauri-apps/plugin-store';
...
- useEffect(() => {
-
- const createFile = async() => {
- const store = new Store('.settings.json');
- await store.set('firstLaunch', true);
- await store.save();
-
- const firstLaunch = await store.get('firstLaunch');
- console.log(firstLaunch)}
-
- createFile()
-
- },[])
+ // Mark onboarding complete when reaching the final page
+ useEffect(() => {
+ if (page === 6) {
+ localStorage.setItem("hasLaunched", "true");
+ }
+ }, [page])If you truly want plugin-store, add the dependency and gate usage to Tauri env to avoid crashes in plain vite:
-const createFile = async() => {
- const store = new Store('.settings.json');
+const createFile = async() => {
+ if (!window.__TAURI__) return;
+ const store = new Store('.settings.json');Also applies to: 13-25
🤖 Prompt for AI Agents
In src/components/guidePages/GuidePage.jsx around lines 7 and 13-25, remove the
unguarded import and use of @tauri-apps/plugin-store (which creates
.settings.json and writes firstLaunch=true on every mount) and either (A) switch
to using localStorage for any simple launch flag and only set firstLaunch (e.g.,
localStorage.setItem('firstLaunch','false')) when the walkthrough completes, or
(B) if you must keep plugin-store, add the dependency and wrap all Store usage
in a Tauri runtime check (gate by an env/ua/isTauri flag) so it never runs in
plain Vite; ensure the initial mount no longer writes the flag and that the flag
is updated only on successful walkthrough completion.
| const handleClick = () => { | ||
| setPage(page + 1) | ||
| console.log(page) | ||
| } |
There was a problem hiding this comment.
Use functional state update to avoid stale closures.
-const handleClick = () => {
- setPage(page + 1)
- console.log(page)
-}
+const handleClick = () => setPage(p => p + 1)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const handleClick = () => { | |
| setPage(page + 1) | |
| console.log(page) | |
| } | |
| const handleClick = () => { | |
| setPage(p => p + 1) | |
| console.log(page) | |
| } |
🤖 Prompt for AI Agents
In src/components/guidePages/GuidePage.jsx around lines 30-33, the setPage call
uses the current page variable and can suffer from stale closures; change it to
use a functional state updater (i.e., setPage(prev => prev + 1)) so the
increment always uses the latest state, and if you need to log the new page
value either log it inside the functional updater by computing the next value
then returning it, or move the console.log into a useEffect that watches page so
it reports the updated value.
| <div className="felx flex-row justify-center text-center text-3xl">A tool to make your life easy</div> | ||
| <button onClick={handleClick} type="button" className="absolute bottom-3 right-5 flex flex-row justify-center py-1 px-3 bg-black rounded-md text-center text-white ">next</button> |
There was a problem hiding this comment.
Fix Tailwind class typos and invalid utilities.
- felx → flex
- justify-left → justify-start
- left-180 → left-[180px] (or another valid value)
- Copy edit “just my” → “just by”; “Hi ,{name}” → “Hi, {name}”
- <div className="felx flex-row justify-center text-center text-3xl">A tool to make your life easy</div>
+ <div className="flex flex-row justify-center text-center text-3xl">A tool to make your life easy</div>
...
- <div className="felx flex-row justify-left text-left text-4xl ">Hi ,{localStorage.getItem("name")} Welcome to Pathfinder</div>
+ <div className="flex flex-row justify-start text-left text-4xl ">Hi, {localStorage.getItem("name")} Welcome to Pathfinder</div>
...
- A powerful Raycast-inspired launcher application built with Tauri and React. PathFinder provides instant access to your most-used tools and information through a beautiful, keyboard-driven interface. And you can access it just my pressing
+ A powerful Raycast-inspired launcher application built with Tauri and React. PathFinder provides instant access to your most-used tools and information through a beautiful, keyboard-driven interface. And you can access it just by pressing
...
- <button onClick={handleClick} className="absolute bottom-3 left-180 flex flex-row justify-center py-1 px-3 bg-black rounded-md text-center text-white ">next</button>
+ <button type="button" onClick={handleClick} className="absolute bottom-3 left-[180px] flex flex-row justify-center py-1 px-3 bg-black rounded-md text-center text-white ">next</button>Also applies to: 88-93, 102-103
🤖 Prompt for AI Agents
In src/components/guidePages/GuidePage.jsx around lines 58-59 (and also apply
fixes at 88-93 and 102-103), fix Tailwind typos and invalid utilities: change
"felx" to "flex", replace "justify-left" with "justify-start", convert
"left-180" to a valid arbitrary value like "left-[180px]" (or another valid
Tailwind spacing), and correct copy edits: "just my" → "just by" and "Hi
,{name}" → "Hi, {name}"; update the affected className strings and text content
accordingly.
| return( | ||
| <div className="flex flex-col justify-center items-center gap-5 h-screen bg-[#3D3C3C] font-sans"> | ||
| <div className="text-4xl">Enter Your Name</div> | ||
| <div> | ||
| <form onSubmit={handleSubmit(onSubmit)}> | ||
| <input | ||
| className="bg-white rounded-md text-2xl text-center" | ||
| defaultValue="" {...register("name")} type='text' placeholder="Type"/> | ||
| </form> | ||
| </div> | ||
| <button type='button' onClick={handleClick} className="absolute bottom-3 right-5 flex flex-row justify-center py-1 px-3 bg-black rounded-md text-center text-white ">next</button> | ||
| </div> |
There was a problem hiding this comment.
Blocker: Name isn’t saved; Next doesn’t submit the form.
The “Next” button advances pages without submitting; onSubmit never runs unless the user presses Enter. Make Next submit the form and persist the name:
- <div>
- <form onSubmit={handleSubmit(onSubmit)}>
- <input
- className="bg-white rounded-md text-2xl text-center"
- defaultValue="" {...register("name")} type='text' placeholder="Type"/>
- </form>
- </div>
- <button type='button' onClick={handleClick} className="absolute bottom-3 right-5 flex flex-row justify-center py-1 px-3 bg-black rounded-md text-center text-white ">next</button>
+ <div>
+ <form onSubmit={handleSubmit(onSubmit)}>
+ <input
+ className="bg-white rounded-md text-2xl text-center"
+ {...register("name", { required: true })}
+ type="text"
+ placeholder="Your name"
+ />
+ <button type="submit" className="absolute bottom-3 right-5 flex flex-row justify-center py-1 px-3 bg-black rounded-md text-center text-white">
+ next
+ </button>
+ </form>
+ </div>🤖 Prompt for AI Agents
In src/components/guidePages/GuidePage.jsx around lines 65 to 76, the "Next"
button is outside the form and set as type='button' so handleSubmit/onSubmit
never runs; either move the button inside the <form> and change it to
type='submit' or keep it outside and change its onClick to call
handleSubmit(onSubmit) (e.g., onClick={() => handleSubmit(onSubmit)()}), and
ensure register("name") is used so the submitted value is persisted.
| <div className="felx flex-row justify-left text-left text-4xl ">Hi ,{localStorage.getItem("name")} Welcome to Pathfinder</div> | ||
| <div className="text-left backdrop-blur-sm"> | ||
| A powerful Raycast-inspired launcher application built with Tauri and React. PathFinder provides instant access to your most-used tools and information through a beautiful, keyboard-driven interface. And you can access it just my pressing | ||
| </div> | ||
| <div className="text-5xl text-center text-[#737373]">Ctrl+Shift+Space</div> | ||
| <button onClick={handleClick} className="absolute bottom-3 left-180 flex flex-row justify-center py-1 px-3 bg-black rounded-md text-center text-white ">next</button> | ||
| </div> | ||
| ) |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Avoid reading localStorage during render (optional).
Store the name in component state when it’s submitted; it avoids null flashes and makes SSR/testing easier. Example:
-const { register, handleSubmit, formState: { errors } } = useForm()
+const { register, handleSubmit } = useForm()
+const [name, setName] = useState("")
...
- const onSubmit = (data) => {
- localStorage.setItem("name", data.name)
- handleClick()
-}
+ const onSubmit = (data) => {
+ setName(data.name)
+ localStorage.setItem("name", data.name)
+ handleClick()
+}
...
-Hi, {localStorage.getItem("name")} Welcome to Pathfinder
+Hi, {name || localStorage.getItem("name") || "there"} Welcome to PathfinderCommittable suggestion skipped: line range outside the PR's diff.
🧰 Tools
🪛 Biome (2.1.2)
[error] 93-93: Provide an explicit type prop for the button element.
The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset
(lint/a11y/useButtonType)
🤖 Prompt for AI Agents
In src/components/guidePages/GuidePage.jsx around lines 88 to 95, the component
reads localStorage.getItem("name") directly during render which can cause null
flashes and hurts SSR/testing; change to read localStorage once into component
state (use useState) and populate it on mount (useEffect) or during the form
submit, providing a safe default (empty string) and rendering state instead of
calling localStorage directly; also ensure the handler that saves the name
updates both local state and localStorage so the UI stays in sync.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (9)
src/components/guidePages/GuidePage.jsx (7)
42-42: Fix Tailwind typo.
felxshould beflex.- <div className="felx flex-row justify-center text-center text-3xl">A tool to make your life easy</div> + <div className="flex flex-row justify-center text-center text-3xl">A tool to make your life easy</div>
52-60: BLOCKER: Name isn't saved when clicking "Next".The "Next" button (line 59) is outside the form and has
type='button'withonClick={handleClick}, so it advances the page without submitting. The name is only saved if the user presses Enter. Move the button inside the form and change it totype="submit".- <div> - <form onSubmit={handleSubmit(onSubmit)}> - <input - className="bg-white rounded-md text-2xl text-center" - defaultValue="" {...register("name")} type='text' placeholder="Type"/> - </form> - </div> - <button type='button' onClick={handleClick} className="absolute bottom-3 right-5 flex flex-row justify-center py-1 px-3 bg-black rounded-md text-center text-white ">next</button> + <div> + <form onSubmit={handleSubmit(onSubmit)}> + <input + className="bg-white rounded-md text-2xl text-center" + {...register("name", { required: true })} + type="text" + placeholder="Your name" + /> + <button type="submit" className="absolute bottom-3 right-5 flex flex-row justify-center py-1 px-3 bg-black rounded-md text-center text-white"> + next + </button> + </form> + </div>
72-77: Fix Tailwind v4 incompatibilities and copy errors.Multiple issues remain from previous review:
- Line 72:
felx→flex,justify-left→justify-start, "Hi ,{name}" → "Hi, {name}" (spacing)- Line 74: "just my pressing" → "just by pressing"
- Line 77:
left-180is invalid in Tailwind v4; useleft-[180px]or another valid arbitrary valueBased on library documentation.
- <div className="felx flex-row justify-left text-left text-4xl ">Hi ,{localStorage.getItem("name")} Welcome to Pathfinder</div> + <div className="flex flex-row justify-start text-left text-4xl ">Hi, {localStorage.getItem("name")} Welcome to Pathfinder</div> <div className="text-left backdrop-blur-sm"> - A powerful Raycast-inspired launcher application built with Tauri and React. PathFinder provides instant access to your most-used tools and information through a beautiful, keyboard-driven interface. And you can access it just my pressing + A powerful Raycast-inspired launcher application built with Tauri and React. PathFinder provides instant access to your most-used tools and information through a beautiful, keyboard-driven interface. And you can access it just by pressing </div> <div className="text-5xl text-center text-[#737373]">Ctrl+Shift+Space</div> - <button type="button" onClick={handleClick} className="absolute bottom-3 left-180 flex flex-row justify-center py-1 px-3 bg-black rounded-md text-center text-white ">next</button> + <button type="button" onClick={handleClick} className="absolute bottom-3 left-[180px] flex flex-row justify-center py-1 px-3 bg-black rounded-md text-center text-white ">next</button>
103-103: Add explicit button type.The button lacks a
typeattribute, which can cause accidental form submissions. Addtype="button".- <button onClick={handleClick} className=" py-1 px-3 bg-black rounded-md text-center text-white ">next</button> + <button type="button" onClick={handleClick} className=" py-1 px-3 bg-black rounded-md text-center text-white ">next</button>
121-121: Add explicit button type.The button lacks a
typeattribute, which can cause accidental form submissions. Addtype="button".- <button onClick={handleClick} className=" py-1 px-3 bg-black rounded-md text-center text-white ">next</button> + <button type="button" onClick={handleClick} className=" py-1 px-3 bg-black rounded-md text-center text-white ">next</button>
139-139: Add explicit button type.The button lacks a
typeattribute, which can cause accidental form submissions. Addtype="button".- <button onClick={handleClick} className=" py-1 px-3 bg-black rounded-md text-center text-white ">next</button> + <button type="button" onClick={handleClick} className=" py-1 px-3 bg-black rounded-md text-center text-white ">next</button>
9-162: BLOCKER: Completion flag never saved; guide reopens every launch.The component never writes
localStorage.setItem("hasLaunched", "true")when the walkthrough finishes (page 6), so App.jsx will reopen the guide on every launch. Add auseEffectthat sets the flag whenpage === 6.+ // Mark onboarding complete when reaching the final page + useEffect(() => { + if (page === 6) { + localStorage.setItem("hasLaunched", "true"); + } + }, [page]); + const handleClick = () => {src/App.jsx (2)
18-30: BLOCKER: First-launch logic always opens the guide.The effect writes
hasLaunched=trueon every mount (line 21) without reading the existing flag, so the guide opens every time. Read the flag first and only show the guide when it's missing or false. The flag should be saved by GuidePage when the user completes the walkthrough (page 6).useEffect(() => { - - if(firstLaunchChecked === false){ - localStorage.setItem("hasLaunched", "true"); - setCurrentPage("open-guide") - console.log() - } - else{ - setCurrentPage("home") - } - setFirstLaunchChecked(true) - + const hasLaunched = localStorage.getItem("hasLaunched") === "true"; + setCurrentPage(hasLaunched ? "home" : "open-guide"); + setFirstLaunchChecked(true); },[])
81-81: Remove unused prop.GuidePage doesn't consume the
queryprop; you can drop it to reduce prop churn.- {currentPage === "open-guide" && <GuidePage query={query} />} + {currentPage === "open-guide" && <GuidePage />}
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
src/App.jsx(3 hunks)src/components/guidePages/GuidePage.jsx(1 hunks)
🧰 Additional context used
🪛 Biome (2.1.2)
src/components/guidePages/GuidePage.jsx
[error] 103-103: Provide an explicit type prop for the button element.
The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset
(lint/a11y/useButtonType)
[error] 121-121: Provide an explicit type prop for the button element.
The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset
(lint/a11y/useButtonType)
[error] 139-139: Provide an explicit type prop for the button element.
The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset
(lint/a11y/useButtonType)
| import snapshort1 from "../../assets/snapshot1.png" | ||
| import snapshot2 from "../../assets/snapshort2.png" | ||
| import snapshot3 from "../../assets/snapshort3.png" | ||
| import snapshort4 from "../../assets/snapshort4.png" |
There was a problem hiding this comment.
Fix inconsistent asset import naming.
The imports mix snapshort and snapshot (lines 3, 4, 6 use snapshort; line 5 uses snapshot). Standardize to snapshot for clarity.
-import snapshort1 from "../../assets/snapshot1.png"
-import snapshot2 from "../../assets/snapshort2.png"
-import snapshot3 from "../../assets/snapshort3.png"
-import snapshort4 from "../../assets/snapshort4.png"
+import snapshot1 from "../../assets/snapshot1.png"
+import snapshot2 from "../../assets/snapshot2.png"
+import snapshot3 from "../../assets/snapshot3.png"
+import snapshot4 from "../../assets/snapshot4.png"Then update references on lines 91, 98, 117, and 136 accordingly.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/components/guidePages/GuidePage.jsx around lines 3 to 6, the asset
imports use inconsistent variable names (`snapshort1`, `snapshort4`, etc.) while
one uses `snapshot2`; rename all imports to use the consistent `snapshot` prefix
(e.g., snapshot1, snapshot2, snapshot3, snapshot4) and adjust the import paths
if necessary to match file names; then update all usages of those variables on
lines 91, 98, 117, and 136 to use the new consistent names.
|
@Larry8668 I have made the PR and have checked it several times could you please review it. |
|
Hey @AlokPy1484 , will have a look at this tonight |
|
Hey @AlokPy1484 , tried this out few typos but its good to go - merging it |
|
Hi @Larry8668, |
|
While working on this issue, I tried to store the nickname in a file so that we could use it later for the settings feature. I wasn’t able to complete it as it turned out to be a bit more complex than expected, but I’d like to spend more time on it and continue working on it. |
|
Hey @AlokPy1484 sure i can open it up |
ok |
This PR introduces a walkthrough/onboarding flow that guides first-time users through the app’s key features.
It enhances usability and improves user understanding of core functionality.
🚀 Changes Made
🧠 How It Works
🧪 Testing
✅ Tested first-launch scenario — walkthrough appears as expected.
✅ Ensured normal navigation flow after walkthrough completion.
✅ Checked visual consistency of guide page
WhatsApp.Video.2025-10-28.at.00.49.30.mp4
Summary by CodeRabbit
New Features
Chores
Style