Upgrade dependencies and add release workflow - #44
Conversation
- Bump React, Tailwind CSS, TypeScript, Vite to latest major versions - Add GitHub Actions release workflow (.github/workflows/release.yml)
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughThis PR adds release automation, upgrades the frontend platform, introduces authentication and email-template workflows, replaces the navbar with a responsive sidebar, redesigns page and profile views, and refreshes the shared UI component system and styling configuration. ChangesRelease and Platform Migration
Authentication and Email Workflows
Workspace Navigation and Page Experience
UI Component System
Supporting Styling and Documentation
Estimated code review effort: 5 (Critical) | ~120 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 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: 3
🧹 Nitpick comments (1)
package.json (1)
24-24: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
bunlisted as a runtime dependency is unusual.
bun(and@types/bun) is the runtime/toolchain rather than an app dependency; pinning it underdependenciesdoesn't install a usable Bun binary and can be confusing. Consider relying on the CI/.tool-versions/engines to pin Bun instead, unless this is intentional for a specific reason.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@package.json` at line 24, The package.json dependency list includes bun as an app runtime dependency, which is unusual and can be misleading. Update the package metadata around the bun entry so Bun is pinned via the project’s runtime/tooling configuration instead of dependencies, unless there is a deliberate reason to keep it there; use the package.json dependency block and any related Bun/runtime settings as the location to adjust.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/release.yml:
- Around line 27-30: The checkout step in the release workflow is persisting the
GITHUB_TOKEN in git config unnecessarily. Update the existing
actions/checkout@v4 configuration to disable credential persistence by setting
persist-credentials to false while keeping the full-history/tag fetch settings
unchanged.
In `@package.json`:
- Line 53: Remove the stray install dependency from package.json and update the
lockfile accordingly. The dependency is unused, so delete the install entry from
the dependencies section and regenerate or edit the lockfile so it no longer
references it, keeping the change consistent with the package manifest.
In `@src/index.css`:
- Around line 1-5: Stylelint is flagging Tailwind v4 directives as unknown
at-rules in the stylesheet; update the stylelint configuration to allowlist the
Tailwind-specific directives used in src/index.css. Adjust the rule that powers
scss/at-rule-no-unknown so it ignores `@config` and `@custom-variant` (and any other
Tailwind v4 at-rules already present in the stylesheet), keeping the change in
the stylelint config rather than the CSS itself.
---
Nitpick comments:
In `@package.json`:
- Line 24: The package.json dependency list includes bun as an app runtime
dependency, which is unusual and can be misleading. Update the package metadata
around the bun entry so Bun is pinned via the project’s runtime/tooling
configuration instead of dependencies, unless there is a deliberate reason to
keep it there; use the package.json dependency block and any related Bun/runtime
settings as the location to adjust.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 0fcbc1e3-84e2-4be1-b02a-aca94aca1a5d
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (12)
.github/workflows/release.ymlpackage.jsonpostcss.config.jssrc/components/ProfileDropdown.tsxsrc/index.csssrc/routeTree.gen.tssrc/views/Page.tsxtailwind.config.tstsconfig.app.jsontsconfig.app.tsbuildinfotsconfig.jsontsconfig.node.tsbuildinfo
💤 Files with no reviewable changes (2)
- tsconfig.json
- tsconfig.app.json
| - name: Checkout (full history + tags) | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win
Set persist-credentials: false on checkout.
actions/checkout persists the GITHUB_TOKEN in .git/config by default. This workflow never pushes via git (the release is created through action-gh-release using the token directly), so the persisted credential is unnecessary and leaves a credential exposed to any later step.
🔒️ Proposed hardening
- name: Checkout (full history + tags)
uses: actions/checkout@v4
with:
fetch-depth: 0
+ persist-credentials: false📝 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.
| - name: Checkout (full history + tags) | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Checkout (full history + tags) | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false |
🧰 Tools
🪛 zizmor (1.26.1)
[warning] 27-30: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/release.yml around lines 27 - 30, The checkout step in the
release workflow is persisting the GITHUB_TOKEN in git config unnecessarily.
Update the existing actions/checkout@v4 configuration to disable credential
persistence by setting persist-credentials to false while keeping the
full-history/tag fetch settings unchanged.
Source: Linters/SAST tools
| "eslint-plugin-react-hooks": "^7.1.1", | ||
| "eslint-plugin-react-refresh": "^0.5.3", | ||
| "globals": "^17.7.0", | ||
| "install": "^0.13.0", |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Confirm nothing references the `install` package.
rg -nP "require\(['\"]install['\"]\)|from ['\"]install['\"]" .Repository: macintushar/draw
Length of output: 154
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '--- package.json excerpt ---'
cat -n package.json | sed -n '40,65p'
echo
echo '--- plain-text references to "install" (filtered to likely relevant paths) ---'
rg -n --hidden --glob '!**/node_modules/**' --glob '!**/.git/**' --glob '!package-lock.json' --glob '!pnpm-lock.yaml' --glob '!yarn.lock' '\binstall\b' .
echo
echo '--- package.json dependency entries ---'
python3 - <<'PY'
import json
from pathlib import Path
pkg = json.loads(Path('package.json').read_text())
for section in ('dependencies', 'devDependencies', 'optionalDependencies', 'peerDependencies'):
deps = pkg.get(section, {})
if 'install' in deps:
print(section, deps['install'])
PYRepository: macintushar/draw
Length of output: 2141
Remove the stray install dependency. install doesn’t appear to be used anywhere; remove it from package.json and the lockfile to avoid unnecessary supply-chain surface.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@package.json` at line 53, Remove the stray install dependency from
package.json and update the lockfile accordingly. The dependency is unused, so
delete the install entry from the dependencies section and regenerate or edit
the lockfile so it no longer references it, keeping the change consistent with
the package manifest.
| @import "tailwindcss"; | ||
| @import "tw-animate-css"; | ||
| @config "../tailwind.config.ts"; | ||
|
|
||
| @custom-variant dark (&:is(.dark *)); |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Update stylelint to recognize Tailwind v4 at-rules.
Stylelint flags @config (Line 3) and @custom-variant (Line 5) as unknown at-rules via scss/at-rule-no-unknown. These are valid Tailwind v4 directives, so this will produce persistent CI/editor lint noise (and may fail lint gates) unless the stylelint config allowlists them.
🔧 Suggested stylelint config update
rules: {
"scss/at-rule-no-unknown": [
true,
{
- ignoreAtRules: [/* existing entries */],
+ ignoreAtRules: [
+ "tailwind",
+ "apply",
+ "layer",
+ "config",
+ "custom-variant",
+ "theme",
+ "utility",
+ "source",
+ /* existing entries */
+ ],
},
],
},🧰 Tools
🪛 Stylelint (17.14.0)
[error] 3-3: Unexpected unknown at-rule "@config" (scss/at-rule-no-unknown)
(scss/at-rule-no-unknown)
[error] 5-5: Unexpected unknown at-rule "@custom-variant" (scss/at-rule-no-unknown)
(scss/at-rule-no-unknown)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/index.css` around lines 1 - 5, Stylelint is flagging Tailwind v4
directives as unknown at-rules in the stylesheet; update the stylelint
configuration to allowlist the Tailwind-specific directives used in
src/index.css. Adjust the rule that powers scss/at-rule-no-unknown so it ignores
`@config` and `@custom-variant` (and any other Tailwind v4 at-rules already present
in the stylesheet), keeping the change in the stylelint config rather than the
CSS itself.
Source: Linters/SAST tools
- Add forgot-password, update-password, and verify-email pages - Add React Email templates for auth emails - Replace Navbar with AppSidebar using Sheet component - Add OAuth buttons and env validation - Swap Virgil font for Excalifont - Upgrade UI components and add Dialog, Separator, Skeleton
There was a problem hiding this comment.
Actionable comments posted: 12
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/components/ui/skeleton.tsx (1)
1-14: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winImport React types in these files
src/components/ui/skeleton.tsxandsrc/components/ui/sonner.tsxboth useReact.ComponentProps/React.CSSPropertieswithout importingReact, and the current tsconfig doesn’t enableallowUmdGlobalAccess. Addimport type * as React from "react"(or import the specific types) so these modules compile.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/ui/skeleton.tsx` around lines 1 - 14, Add a type-only React import in the Skeleton component module so React.ComponentProps resolves without relying on a global UMD namespace. Apply the same import fix in src/components/ui/skeleton.tsx lines 1-14 and src/components/ui/sonner.tsx lines 26-33, where React.CSSProperties is referenced.
🧹 Nitpick comments (4)
src/views/Pages.tsx (1)
28-47: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick winShared React Query key
["pages"]with divergentqueryFn. Both files register the same cache key but different fetchers/return shapes, so when both are mounted the effectivequeryFn(and its toast side effect /nullvs{data,error}return) is nondeterministic. Unify the fetcher or use distinct keys.
src/views/Pages.tsx#L28-L47: extract the shared pages fetcher (or key it distinctly, e.g.["pages","list"]) and keep the toast/empty-session handling in one place.src/components/AppSidebar.tsx#L86-L97: consume the same shared fetcher/key so the recents list and the full list stay consistent.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/views/Pages.tsx` around lines 28 - 47, Unify the pages query contract across src/views/Pages.tsx:28-47 and src/components/AppSidebar.tsx:86-97 by extracting or reusing one shared fetcher and query key, preserving the toast and empty-session handling in that shared implementation; update both query sites to consume it so the full pages list and recents use the same return shape and behavior.src/index.css (1)
90-100: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winTarget the sidebar's own
data-slotattributes instead of positional child selectors.The comment explains why the offcanvas geometry needs a hard override, but
> div:first-child/> div:last-child+!importantis fragile — it silently breaks if the sidebar's internal markup gains/reorders a wrapper.src/components/ui/sidebar.tsxalready exposesdata-slot="sidebar-gap"anddata-slot="sidebar-container"on exactly these divs, which is a stable, self-documenting target. Also, the override only patchesleft; ifAppSidebar(or any future consumer) ever renders withside="right", this rule won't undo therightpositioning used by that variant.♻️ Suggested fix
-[data-collapsible="offcanvas"] > div:first-child { +[data-collapsible="offcanvas"] [data-slot="sidebar-gap"] { width: 0 !important; } -[data-collapsible="offcanvas"] > div:last-child { +[data-collapsible="offcanvas"] [data-slot="sidebar-container"] { left: calc(var(--sidebar-width) * -1) !important; }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/index.css` around lines 90 - 100, Update the offcanvas overrides to target the sidebar’s stable data-slot attributes, using sidebar-gap for the width rule and sidebar-container for positioning instead of first-child/last-child selectors. Preserve the hard offcanvas geometry while clearing the side-specific right positioning as well as overriding left, so both left- and right-sided sidebars collapse correctly.tsconfig.app.tsbuildinfo (1)
1-1: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueStop tracking the generated
.tsbuildinfofiles.tsconfig.app.tsbuildinfoandtsconfig.node.tsbuildinfoare both tracked and not ignored; remove them from git and add a*.tsbuildinfoignore rule so they don’t keep churning diffs.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tsconfig.app.tsbuildinfo` at line 1, Remove the tracked generated tsconfig.app.tsbuildinfo and tsconfig.node.tsbuildinfo files from version control, and add a *.tsbuildinfo rule to the repository ignore configuration so future TypeScript build-info files remain untracked.src/db/auth.ts (1)
20-31: 🎯 Functional Correctness | 🔵 TrivialVerify new redirect targets are allow-listed in Supabase.
sendPasswordReset(/update-password),linkIdentity(/profile),signInWithOAuth/signUp/resend(/pages) all passwindow.location.origin+ a path asredirectTo/emailRedirectTo. Supabase rejects/redirects to the Site URL for any redirect target not present in the project's Auth → URL Configuration allow-list. Please confirm/update-passwordand/profile(and/pages, if not already present) are added there for every deployed environment origin.Also applies to: 64-107
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/db/auth.ts` around lines 20 - 31, Verify the Supabase Auth URL Configuration includes the deployed origins with /update-password, /profile, and /pages redirect paths used by sendPasswordReset, linkIdentity, signInWithOAuth, signUp, and resend. Add any missing targets for every deployed environment without changing the existing redirect construction.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/mockups/sidebar-layout.html`:
- Around line 327-336: Replace the personal email text in the profile markup’s
email element with an obviously fake placeholder address, while leaving the
surrounding profile structure unchanged.
In `@email-templates/emails/components/layout.tsx`:
- Line 15: Update the asset URL configuration near baseUrl and the related image
rendering at the additionally affected lines to require a hosted
EMAIL_ASSETS_BASE_URL instead of falling back to an empty string. Ensure
generated HTML always uses an absolute hosted asset URL, and fail clearly when
the environment variable is missing.
In `@email-templates/render.tsx`:
- Line 41: Replace the console.log call in the rendering status message with the
lint-compliant process.stdout.write API, preserving the existing “Rendered
out/${name}.html” output and newline behavior.
- Around line 31-40: Update the output path handling around outDir to convert
both file URLs with fileURLToPath() instead of using URL.pathname, and use
join() when constructing the static directory and template HTML paths. Preserve
the existing mkdir, cp, and writeFile behavior while ensuring paths work with
percent-encoded names and Windows separators.
In `@email-templates/tsconfig.json`:
- Line 16: Update the include list in email-templates/tsconfig.json to include
both the existing emails directory and render.tsx, ensuring the render.tsx
imports and props are type-checked without removing the current emails coverage.
In `@src/components/PagePreview.tsx`:
- Around line 24-63: Remove the synchronous setIsEmpty calls from the useEffect
callback. Derive the empty state during render from the nonDeleted elements
collection, while retaining isEmpty state only for asynchronous export failures
in the catch handler; ensure the rendered empty condition still reflects either
no non-deleted elements or an export failure.
In `@src/components/ui/input.tsx`:
- Around line 32-42: Add an accessible name to the icon-only password toggle
button in the HiddenInput component, using a state-dependent aria-label that
clearly indicates whether it will show or hide the password. Preserve the
existing showPassword toggle behavior and icon rendering.
In `@src/index.css`:
- Line 9: Update the font-family declaration in the stylesheet to use the
unquoted Excalifont name, preserving the existing font choice while satisfying
the font-family-name-quotes lint rule.
In `@src/views/Layout.tsx`:
- Around line 12-49: The LayoutContent mobile flow lacks an external sidebar
trigger when the mobile sheet is closed. Update ExpandButton or add a nearby
trigger using the sidebar context’s mobile open state and toggle action, render
it outside AppSidebar so it remains visible on small screens, and preserve the
existing desktop collapsed-sidebar behavior.
In `@src/views/Login.tsx`:
- Around line 53-58: Update the error check in the Login submit flow to use
data.error.code === "email_not_confirmed" instead of matching data.error.message
text, while preserving the existing navigation to /verify-email with the
submitted email and the early return.
In `@src/views/Pages.tsx`:
- Around line 132-136: Update the delete control in Pages around Trash2 by
wrapping the icon in a focusable button with an accessible label describing page
deletion. Move the click handler to the button, preserve the existing styling
and handlePageDelete(page.page_id) behavior, and ensure the icon remains
decorative within the labeled button.
In `@src/views/VerifyEmail.tsx`:
- Around line 38-40: Initialize the cooldown state in VerifyEmail using the
existing emailParam: when a pre-filled email is present, seed it with the
intended resend cooldown; otherwise retain the zero cooldown for users without
an email parameter. Keep the existing email, loading, and cooldown behavior
unchanged after initialization.
---
Outside diff comments:
In `@src/components/ui/skeleton.tsx`:
- Around line 1-14: Add a type-only React import in the Skeleton component
module so React.ComponentProps resolves without relying on a global UMD
namespace. Apply the same import fix in src/components/ui/skeleton.tsx lines
1-14 and src/components/ui/sonner.tsx lines 26-33, where React.CSSProperties is
referenced.
---
Nitpick comments:
In `@src/db/auth.ts`:
- Around line 20-31: Verify the Supabase Auth URL Configuration includes the
deployed origins with /update-password, /profile, and /pages redirect paths used
by sendPasswordReset, linkIdentity, signInWithOAuth, signUp, and resend. Add any
missing targets for every deployed environment without changing the existing
redirect construction.
In `@src/index.css`:
- Around line 90-100: Update the offcanvas overrides to target the sidebar’s
stable data-slot attributes, using sidebar-gap for the width rule and
sidebar-container for positioning instead of first-child/last-child selectors.
Preserve the hard offcanvas geometry while clearing the side-specific right
positioning as well as overriding left, so both left- and right-sided sidebars
collapse correctly.
In `@src/views/Pages.tsx`:
- Around line 28-47: Unify the pages query contract across
src/views/Pages.tsx:28-47 and src/components/AppSidebar.tsx:86-97 by extracting
or reusing one shared fetcher and query key, preserving the toast and
empty-session handling in that shared implementation; update both query sites to
consume it so the full pages list and recents use the same return shape and
behavior.
In `@tsconfig.app.tsbuildinfo`:
- Line 1: Remove the tracked generated tsconfig.app.tsbuildinfo and
tsconfig.node.tsbuildinfo files from version control, and add a *.tsbuildinfo
rule to the repository ignore configuration so future TypeScript build-info
files remain untracked.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 3a764067-1f28-4c55-8b6f-20a0cea1fcd2
⛔ Files ignored due to path filters (6)
bun.lockis excluded by!**/*.lockemail-templates/bun.lockis excluded by!**/*.lockemail-templates/emails/static/draw-logo.pngis excluded by!**/*.pngpublic/static/draw-logo.pngis excluded by!**/*.pngsrc/assets/fonts/Excalifont.woff2is excluded by!**/*.woff2src/assets/fonts/Virgil.woff2is excluded by!**/*.woff2
📒 Files selected for processing (58)
.env.example.gitignore.tanstack/tmp/cfbf5386-d35b5b35ba1538933b305e6abb8fa3abcomponents.jsondocs/mockups/sidebar-layout.htmldocs/supabase.mdemail-templates/emails/change-email.tsxemail-templates/emails/components/layout.tsxemail-templates/emails/confirm-signup.tsxemail-templates/emails/reset-password.tsxemail-templates/package.jsonemail-templates/render.tsxemail-templates/tsconfig.jsonpackage.jsonsrc/components/AppSidebar.tsxsrc/components/OAuthButtons.tsxsrc/components/PagePreview.tsxsrc/components/TitleBar.tsxsrc/components/ui/button.tsxsrc/components/ui/card.tsxsrc/components/ui/dropdown-menu.tsxsrc/components/ui/form.tsxsrc/components/ui/input.tsxsrc/components/ui/label.tsxsrc/components/ui/separator.tsxsrc/components/ui/sheet.tsxsrc/components/ui/sidebar.tsxsrc/components/ui/skeleton.tsxsrc/components/ui/sonner.tsxsrc/components/ui/textarea.tsxsrc/components/ui/tooltip.tsxsrc/db/auth.tssrc/db/supabase.tssrc/env.tssrc/hooks/use-mobile.tssrc/index.csssrc/lib/schemas.tssrc/lib/utils.tssrc/main.tsxsrc/routeTree.gen.tssrc/routes/__root.tsxsrc/routes/forgot-password.lazy.tsxsrc/routes/update-password.lazy.tsxsrc/routes/verify-email.tsxsrc/views/ForgotPassword.tsxsrc/views/HomePage.tsxsrc/views/Layout.tsxsrc/views/Login.tsxsrc/views/Mermaid.tsxsrc/views/Navbar.tsxsrc/views/Page.tsxsrc/views/Pages.tsxsrc/views/Profile.tsxsrc/views/SignUp.tsxsrc/views/UpdatePassword.tsxsrc/views/VerifyEmail.tsxtailwind.config.tstsconfig.app.tsbuildinfo
💤 Files with no reviewable changes (2)
- src/views/Navbar.tsx
- tailwind.config.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- package.json
| <div class="profile"> | ||
| <div class="avatar">T</div> | ||
| <div class="who"> | ||
| <div class="name">Tushar</div> | ||
| <div class="email">tusharkumar91111@gmail.com</div> | ||
| </div> | ||
| <button class="icon-btn" id="themeToggle" title="Toggle theme"> | ||
| <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/></svg> | ||
| </button> | ||
| </div> |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win
Replace the real email address with a placeholder.
Line 331 embeds what appears to be a personal email address in a committed mockup. Even in demo markup this exposes it to scraping/spam; use an obviously fake placeholder instead.
🔒 Proposed fix
- <div class="email">tusharkumar91111@gmail.com</div>
+ <div class="email">tushar@example.com</div>📝 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.
| <div class="profile"> | |
| <div class="avatar">T</div> | |
| <div class="who"> | |
| <div class="name">Tushar</div> | |
| <div class="email">tusharkumar91111@gmail.com</div> | |
| </div> | |
| <button class="icon-btn" id="themeToggle" title="Toggle theme"> | |
| <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/></svg> | |
| </button> | |
| </div> | |
| <div class="profile"> | |
| <div class="avatar">T</div> | |
| <div class="who"> | |
| <div class="name">Tushar</div> | |
| <div class="email">tushar@example.com</div> | |
| </div> | |
| <button class="icon-btn" id="themeToggle" title="Toggle theme"> | |
| <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/></svg> | |
| </button> | |
| </div> |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/mockups/sidebar-layout.html` around lines 327 - 336, Replace the
personal email text in the profile markup’s email element with an obviously fake
placeholder address, while leaving the surrounding profile structure unchanged.
| } from "react-email"; | ||
| import type { ReactNode } from "react"; | ||
|
|
||
| const baseUrl = process.env.EMAIL_ASSETS_BASE_URL ?? ""; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Require a hosted asset base URL.
With the current fallback, exported HTML contains src="/static/draw-logo.png". The renderer only copies assets locally; after pasting the template into Supabase, recipients cannot resolve this relative URL and the logo will be broken.
Proposed fix
-const baseUrl = process.env.EMAIL_ASSETS_BASE_URL ?? "";
+const assetBaseUrl = process.env.EMAIL_ASSETS_BASE_URL;
+if (!assetBaseUrl) {
+ throw new Error("EMAIL_ASSETS_BASE_URL must be configured");
+}
+const logoUrl = new URL("/static/draw-logo.png", assetBaseUrl).href;
...
- src={`${baseUrl}/static/draw-logo.png`}
+ src={logoUrl}Also applies to: 43-48
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@email-templates/emails/components/layout.tsx` at line 15, Update the asset
URL configuration near baseUrl and the related image rendering at the
additionally affected lines to require a hosted EMAIL_ASSETS_BASE_URL instead of
falling back to an empty string. Ensure generated HTML always uses an absolute
hosted asset URL, and fail clearly when the environment variable is missing.
| const outDir = new URL("./out/", import.meta.url).pathname; | ||
|
|
||
| await mkdir(outDir, { recursive: true }); | ||
| await cp(new URL("./emails/static/", import.meta.url).pathname, outDir + "static", { | ||
| recursive: true, | ||
| }); | ||
|
|
||
| for (const [name, element] of Object.entries(templates)) { | ||
| const html = await render(element, { pretty: true }); | ||
| await writeFile(`${outDir}${name}.html`, html); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
git ls-files email-templates/render.tsx
wc -l email-templates/render.tsx
cat -n email-templates/render.tsx | sed -n '1,120p'Repository: macintushar/draw
Length of output: 1820
🏁 Script executed:
node - <<'JS'
const { fileURLToPath } = require('node:url');
const u1 = new URL('file:///tmp/My%20Folder/out/');
const u2 = new URL('file:///C:/tmp/My%20Folder/out/');
console.log('pathname1:', u1.pathname);
console.log('fileURLToPath1:', fileURLToPath(u1));
console.log('pathname2:', u2.pathname);
console.log('fileURLToPath2:', fileURLToPath(u2));
JSRepository: macintushar/draw
Length of output: 298
Convert file URLs with fileURLToPath()
URL.pathname leaves percent-encoding intact and produces a bad Windows path here. Use fileURLToPath() for both URLs, then join() when building static and *.html output paths.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@email-templates/render.tsx` around lines 31 - 40, Update the output path
handling around outDir to convert both file URLs with fileURLToPath() instead of
using URL.pathname, and use join() when constructing the static directory and
template HTML paths. Preserve the existing mkdir, cp, and writeFile behavior
while ensuring paths work with percent-encoded names and Windows separators.
| for (const [name, element] of Object.entries(templates)) { | ||
| const html = await render(element, { pretty: true }); | ||
| await writeFile(`${outDir}${name}.html`, html); | ||
| console.log(`Rendered out/${name}.html`); |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
Remove the reported lint violation.
The CI lint job rejects console.log here. Use a lint-compliant status writer, such as process.stdout.write(...), so this known error no longer blocks the check.
Proposed fix
- console.log(`Rendered out/${name}.html`);
+ process.stdout.write(`Rendered out/${name}.html\n`);📝 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.
| console.log(`Rendered out/${name}.html`); | |
| process.stdout.write(`Rendered out/${name}.html\n`); |
🧰 Tools
🪛 GitHub Actions: Lint Code / 0_build.txt
[error] 41-41: ESLint (no-console): Unexpected console statement. Only these console methods are allowed: error
🪛 GitHub Actions: Lint Code / build
[error] 41-41: ESLint (no-console): Unexpected console statement. Only these console methods are allowed: error.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@email-templates/render.tsx` at line 41, Replace the console.log call in the
rendering status message with the lint-compliant process.stdout.write API,
preserving the existing “Rendered out/${name}.html” output and newline behavior.
Source: Pipeline failures
| "isolatedModules": true, | ||
| "noEmit": true | ||
| }, | ||
| "include": ["emails"] |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
bunx tsc -p email-templates/tsconfig.json --noEmit --listFiles | rg 'email-templates/render\.tsx'Repository: macintushar/draw
Length of output: 192
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the relevant tsconfig and nearby files.
git ls-files 'email-templates/*' | sed -n '1,120p'
printf '\n--- tsconfig ---\n'
cat -n email-templates/tsconfig.json
printf '\n--- render file ---\n'
cat -n email-templates/render.tsx
printf '\n--- emails dir listing ---\n'
find email-templates/emails -maxdepth 2 -type f | sort | sed -n '1,120p'Repository: macintushar/draw
Length of output: 2872
Type-check render.tsx too. email-templates/tsconfig.json only includes emails, so email-templates/render.tsx is skipped and its imports/props can drift unnoticed. Add it to the project’s include list.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@email-templates/tsconfig.json` at line 16, Update the include list in
email-templates/tsconfig.json to include both the existing emails directory and
render.tsx, ensuring the render.tsx imports and props are type-checked without
removing the current emails coverage.
| @layer base { | ||
| @font-face { | ||
| font-family: "Virgil"; | ||
| font-family: "Excalifont"; |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Unquote the font-family name to satisfy stylelint.
Stylelint flags the quoted "Excalifont" value with font-family-name-quotes.
🔧 Suggested fix
- font-family: "Excalifont";
+ font-family: Excalifont;📝 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.
| font-family: "Excalifont"; | |
| font-family: Excalifont; |
🧰 Tools
🪛 Stylelint (17.14.0)
[error] 9-9: Expected no quotes around "Excalifont" (font-family-name-quotes)
(font-family-name-quotes)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/index.css` at line 9, Update the font-family declaration in the
stylesheet to use the unquoted Excalifont name, preserving the existing font
choice while satisfying the font-family-name-quotes lint rule.
Source: Linters/SAST tools
| function ExpandButton() { | ||
| const { open, toggleSidebar } = useSidebar(); | ||
|
|
||
| if (open) return null; | ||
|
|
||
| return ( | ||
| <button | ||
| onClick={toggleSidebar} | ||
| title="Expand sidebar" | ||
| className="group/expand border-sidebar-border fixed top-3 left-3 z-20 flex h-9 w-9 items-center justify-center rounded-lg border bg-white text-lg dark:bg-zinc-900" | ||
| > | ||
| <span className="group-hover/expand:hidden">📄</span> | ||
| <PanelLeft className="hidden h-4 w-4 group-hover/expand:block" /> | ||
| <span className="sr-only">Expand sidebar</span> | ||
| </button> | ||
| ); | ||
| } | ||
|
|
||
| function LayoutContent() { | ||
| const { open } = useSidebar(); | ||
|
|
||
| export default function Layout() { | ||
| return ( | ||
| <div className="flex h-full w-full flex-col p-1"> | ||
| <Navbar /> | ||
| <div className="h-full w-full p-3 pt-1"> | ||
| <div className="flex h-full flex-row justify-center gap-8 overflow-clip rounded-xl border-2 border-black bg-gray-200/60 dark:border-white dark:bg-gray-900"> | ||
| <> | ||
| <AppSidebar /> | ||
| <ExpandButton /> | ||
| <main className="h-svh min-w-0 flex-1 p-2"> | ||
| <div | ||
| className={cn( | ||
| "scrollbar-thumb-accent flex h-full flex-row justify-center gap-8 overflow-y-auto rounded-xl border-2 border-black bg-white dark:border-white dark:bg-zinc-900", | ||
| !open && "pl-12", | ||
| )} | ||
| > | ||
| <Outlet /> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </main> | ||
| </> | ||
| ); | ||
| } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find any sidebar trigger / toggleSidebar usage rendered outside AppSidebar
rg -nP '\btoggleSidebar\b|SidebarTrigger|openMobile|setOpenMobile' src --type=ts --type=tsx -C2Repository: macintushar/draw
Length of output: 182
🏁 Script executed:
#!/bin/bash
set -euo pipefail
git ls-files 'src/**' | rg 'Layout\.tsx|sidebar|Sidebar|sheet|trigger'Repository: macintushar/draw
Length of output: 263
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n## src/components/AppSidebar.tsx\n'
ast-grep outline src/components/AppSidebar.tsx --view expanded || true
printf '\n## src/components/ui/sidebar.tsx\n'
ast-grep outline src/components/ui/sidebar.tsx --view expanded || true
printf '\n## src/views/Layout.tsx\n'
ast-grep outline src/views/Layout.tsx --view expanded || true
printf '\n## Sidebar-trigger related lines in AppSidebar.tsx\n'
rg -n "SidebarTrigger|toggleSidebar|openMobile|setOpenMobile|Sheet|ProfileFooter|header" src/components/AppSidebar.tsx src/components/ui/sidebar.tsx src/views/Layout.tsx -C 3Repository: macintushar/draw
Length of output: 12922
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '## SidebarTrigger usages\n'
rg -n "\bSidebarTrigger\b" src --type-add 'ts:*.ts' --type-add 'tsx:*.tsx' -g '!src/components/ui/sidebar.tsx' -C 3 || true
printf '\n## AppSidebar excerpt\n'
sed -n '227,288p' src/components/AppSidebar.tsx
printf '\n## Layout excerpt\n'
sed -n '1,80p' src/views/Layout.tsxRepository: macintushar/draw
Length of output: 3659
Add a mobile sidebar trigger
ExpandButton only reflects the desktop open state, and the only toggleSidebar controls live inside AppSidebar, which is hidden behind the mobile sheet when openMobile is false. Add a trigger outside the sheet so the sidebar can be opened on small screens.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/views/Layout.tsx` around lines 12 - 49, The LayoutContent mobile flow
lacks an external sidebar trigger when the mobile sheet is closed. Update
ExpandButton or add a nearby trigger using the sidebar context’s mobile open
state and toggle action, render it outside AppSidebar so it remains visible on
small screens, and preserve the existing desktop collapsed-sidebar behavior.
|
|
||
| if (data.error.message.toLowerCase().includes("email not confirmed")) { | ||
| navigate({ to: "/verify-email", search: { email: values.email } }); | ||
| return; | ||
| } | ||
|
|
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Map the relevant file and nearby auth handling
printf '\n== src/views/Login.tsx outline ==\n'
ast-grep outline src/views/Login.tsx --view expanded || true
printf '\n== src/views/Login.tsx lines 1-220 ==\n'
cat -n src/views/Login.tsx | sed -n '1,220p'
printf '\n== Search for email_not_confirmed and error.code usage ==\n'
rg -n --hidden -S 'email_not_confirmed|error\.code|email not confirmed' src . || trueRepository: macintushar/draw
Length of output: 5963
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Check whether the repo references the structured auth error code anywhere else.
rg -n --hidden -S 'email_not_confirmed|EMAIL_NOT_CONFIRMED|not confirmed' .Repository: macintushar/draw
Length of output: 257
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== auth-related files ==\n'
fd -a 'auth.*' src
printf '\n== src/db/auth.* outline or contents ==\n'
for f in src/db/auth.ts src/db/auth.tsx src/db/auth.js src/db/auth.jsx; do
if [ -f "$f" ]; then
echo "--- $f"
ast-grep outline "$f" --view expanded || true
echo
cat -n "$f" | sed -n '1,260p'
fi
done
printf '\n== package.json relevant deps ==\n'
cat -n package.json | sed -n '1,220p'
printf '\n== search for supabase imports/usages ==\n'
rg -n --hidden -S 'supabase|createClient|signInWithPassword|AuthError|error\.code|email_confirm' src package.json .Repository: macintushar/draw
Length of output: 16258
🌐 Web query:
Supabase AuthError code email_not_confirmed @supabase/supabase-js 2.110.0 documentation
💡 Result:
In the @supabase/supabase-js SDK (which utilizes @supabase/auth-js), the email_not_confirmed error code is a standard identifier returned by the Supabase Auth API when a user attempts to sign in with an email address that has not yet been verified [1][2]. Key Technical Details: - SDK Representation: Errors originating from the Supabase Auth API are wrapped in the AuthError class [1][3]. You should handle this by checking the error.code property rather than parsing error messages [4][3]. - Meaning: The email_not_confirmed code explicitly indicates that the user's email address is unverified, and as a result, sign-in is blocked [1][5]. - Implementation Guidance: Supabase recommends using error.code and error.name for robust error handling [3]. When using TypeScript, AuthError exposes the code property (typically typed as ErrorCode or string) [6]. - Known Behaviors: There have been reports that this error can persist even when email confirmation settings are disabled, particularly for users created via the Admin API, as the email_confirmed_at timestamp may remain NULL [7]. Example Pattern: const { data, error } = await supabase.auth.signInWithPassword({ email: 'example@email.com', password: 'example-password', }) if (error) { if (error.code === 'email_not_confirmed') { // Handle unconfirmed email (e.g., prompt user to check inbox) } console.error(error) }
Citations:
- 1: https://supabase.com/docs/guides/auth/debugging/error-codes
- 2: https://github.com/supabase/auth/blob/f3425cf7/internal/api/apierrors/errorcode.go
- 3: https://github.com/supabase/supabase/blob/master/apps/docs/content/guides/auth/debugging/error-codes.mdx
- 4: https://supabase.com/docs/guides/api/handling-errors-in-supabase-js
- 5: https://github.com/supabase/supabase/blob/master/apps/docs/content/errorCodes/authErrorCodes.toml
- 6: https://supabase.github.io/auth-js/v2/classes/AuthError.html
- 7: Disabling 'Confirm Email' still blocks non-confirmed users (created with admin client) from signing in supabase/supabase#29632
Prefer error.code here instead of matching the message text.
supabase-js returns email_not_confirmed for this case, so checking data.error.code === "email_not_confirmed" is more robust than relying on message.toLowerCase().includes(...).
♻️ Proposed fix
- if (data.error.message.toLowerCase().includes("email not confirmed")) {
+ if (data.error.code === "email_not_confirmed") {
navigate({ to: "/verify-email", search: { email: values.email } });
return;
}📝 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.
| if (data.error.message.toLowerCase().includes("email not confirmed")) { | |
| navigate({ to: "/verify-email", search: { email: values.email } }); | |
| return; | |
| } | |
| if (data.error.code === "email_not_confirmed") { | |
| navigate({ to: "/verify-email", search: { email: values.email } }); | |
| return; | |
| } | |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/views/Login.tsx` around lines 53 - 58, Update the error check in the
Login submit flow to use data.error.code === "email_not_confirmed" instead of
matching data.error.message text, while preserving the existing navigation to
/verify-email with the submitted email and the early return.
| <Trash2 | ||
| className="invisible h-4 w-4 cursor-pointer rounded-lg text-gray-600 transition-all hover:bg-gray-100 hover:text-red-500 group-hover:visible hover:dark:bg-gray-900" | ||
| strokeWidth={3} | ||
| className="mt-0.5 h-4 w-4 flex-shrink-0 cursor-pointer text-gray-400 opacity-0 transition-all hover:text-red-500 group-hover:opacity-100" | ||
| strokeWidth={2.5} | ||
| onClick={() => handlePageDelete(page.page_id)} | ||
| /> |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Delete control is not keyboard accessible.
The Trash2 icon is a bare SVG with an onClick; it cannot be focused or activated via keyboard and exposes no button role/label. Wrap it in a <button> with an accessible label.
♿ Proposed fix
- <Trash2
- className="mt-0.5 h-4 w-4 flex-shrink-0 cursor-pointer text-gray-400 opacity-0 transition-all hover:text-red-500 group-hover:opacity-100"
- strokeWidth={2.5}
- onClick={() => handlePageDelete(page.page_id)}
- />
+ <button
+ type="button"
+ aria-label={`Delete ${page.name || "Untitled"}`}
+ className="mt-0.5 flex-shrink-0 text-gray-400 opacity-0 transition-all hover:text-red-500 focus-visible:opacity-100 group-hover:opacity-100"
+ onClick={() => handlePageDelete(page.page_id)}
+ >
+ <Trash2 className="h-4 w-4" strokeWidth={2.5} />
+ </button>📝 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.
| <Trash2 | |
| className="invisible h-4 w-4 cursor-pointer rounded-lg text-gray-600 transition-all hover:bg-gray-100 hover:text-red-500 group-hover:visible hover:dark:bg-gray-900" | |
| strokeWidth={3} | |
| className="mt-0.5 h-4 w-4 flex-shrink-0 cursor-pointer text-gray-400 opacity-0 transition-all hover:text-red-500 group-hover:opacity-100" | |
| strokeWidth={2.5} | |
| onClick={() => handlePageDelete(page.page_id)} | |
| /> | |
| <button | |
| type="button" | |
| aria-label={`Delete ${page.name || "Untitled"}`} | |
| className="mt-0.5 flex-shrink-0 text-gray-400 opacity-0 transition-all hover:text-red-500 focus-visible:opacity-100 group-hover:opacity-100" | |
| onClick={() => handlePageDelete(page.page_id)} | |
| > | |
| <Trash2 className="h-4 w-4" strokeWidth={2.5} /> | |
| </button> |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/views/Pages.tsx` around lines 132 - 136, Update the delete control in
Pages around Trash2 by wrapping the icon in a focusable button with an
accessible label describing page deletion. Move the click handler to the button,
preserve the existing styling and handlePageDelete(page.page_id) behavior, and
ensure the icon remains decorative within the labeled button.
| const [email, setEmail] = useState<string | undefined>(emailParam); | ||
| const [isLoading, setIsLoading] = useState<boolean>(false); | ||
| const [cooldown, setCooldown] = useState<number>(0); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Seed cooldown when arriving with a pre-filled email.
cooldown starts at 0 even when emailParam is already set (i.e., right after signup already triggered the initial email), letting the user immediately click "Resend" and likely hit Supabase's resend rate limit.
🐛 Proposed fix
- const [cooldown, setCooldown] = useState<number>(0);
+ const [cooldown, setCooldown] = useState<number>(
+ emailParam ? RESEND_COOLDOWN_SECONDS : 0,
+ );📝 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 [email, setEmail] = useState<string | undefined>(emailParam); | |
| const [isLoading, setIsLoading] = useState<boolean>(false); | |
| const [cooldown, setCooldown] = useState<number>(0); | |
| const [email, setEmail] = useState<string | undefined>(emailParam); | |
| const [isLoading, setIsLoading] = useState<boolean>(false); | |
| const [cooldown, setCooldown] = useState<number>( | |
| emailParam ? RESEND_COOLDOWN_SECONDS : 0, | |
| ); |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/views/VerifyEmail.tsx` around lines 38 - 40, Initialize the cooldown
state in VerifyEmail using the existing emailParam: when a pre-filled email is
present, seed it with the intended resend cooldown; otherwise retain the zero
cooldown for users without an email parameter. Keep the existing email, loading,
and cooldown behavior unchanged after initialization.
Summary
package.jsonandbun.locktailwindcss-animate, addtw-animate-css).github/workflows/release.ymlwith cron (weekly Friday) and manual triggerspostcss.config.jslingering v3 config and update import paths (src/index.css,tailwind.config.ts)routeTree.gen.tsand rebuildtsconfig.app.tsbuildinfo/tsconfig.node.tsbuildinfoTesting
npm run build)npm run dev)import Reacterrors)npm run lint)Summary by CodeRabbit