feat: refactor proposal creation flow#892
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
📝 WalkthroughWalkthroughThis PR implements a staged proposal creation flow (draft → transactions → review), refactors the proposal store API (introducing startProposalDraft and draft metadata setters), adds multiple UI components for staging and mobile actions, updates link/layout APIs to accept typed stage/tab params, and removes the old SelectTransactionType component. Changes
Sequence DiagramsequenceDiagram
actor User
participant Page as CreateProposalPage
participant Store as ProposalStore
participant UI as UI Components
participant Nav as Navigation
User->>Page: Open create page / click create
Page->>Store: startProposalDraft(optional transactionType)
Store->>Store: initialize/merge draft state
Page->>UI: render ProposalStageIndicator + Draft form
User->>UI: enter title/summary
UI->>Store: setTitle / setSummary
User->>Page: click Continue
Page->>Page: validate draft
alt valid
Page->>UI: show Transactions stage (TransactionForm)
else invalid
UI->>User: show validation errors
end
User->>UI: add/configure transactions
UI->>Store: addTransaction()
User->>Page: click Continue
Page->>Nav: navigate/reveal Review stage
Page->>UI: render ProposalDescription (preview)
User->>UI: submit -> Page triggers final submission flow
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
25dd93c to
ee8b95d
Compare
8ca638d to
fe6ffff
Compare
fe6ffff to
b607f3a
Compare
b607f3a to
92df4df
Compare
92df4df to
92dd709
Compare
There was a problem hiding this comment.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/create-proposal-ui/src/components/TransactionForm/Droposal/DroposalForm.tsx (1)
88-96:⚠️ Potential issue | 🟡 MinorFix helper-link copy typo (“Lean more” → “Learn more”).
Line 95 has a user-facing typo in the link text.
✏️ Suggested fix
- Lean more + Learn more🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/create-proposal-ui/src/components/TransactionForm/Droposal/DroposalForm.tsx` around lines 88 - 96, In the DroposalForm component update the user-facing link text inside the Text JSX (the anchor within the Text element) from "Lean more" to the correct "Learn more"; locate the Text block in DroposalForm.tsx that references the ZORA 721 Contract and replace the typo in the anchor content so the displayed link reads "Learn more".
🧹 Nitpick comments (6)
packages/ui/src/DropdownSelect/DropdownSelect.tsx (1)
133-133: Remove redundant conditional in alignment prop.Line 133 resolves to
'center'in both branches, so the ternary adds noise.Optional cleanup
- align={option.description ? 'center' : 'center'} + align={'center'}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/ui/src/DropdownSelect/DropdownSelect.tsx` at line 133, The align prop in DropdownSelect.tsx is using a redundant ternary (option.description ? 'center' : 'center'); simplify by replacing that expression with a single literal 'center' for the align prop in the DropdownSelect component (remove the ternary and reference to option.description).packages/types/src/links.ts (1)
25-29: Consider exporting a sharedProposalCreateStagetype.The inline union is correct, but centralizing it avoids drift across UI/web link providers.
♻️ Proposed refactor
export type ProposalLinkHandler = ( chainId: CHAIN_ID, daoTokenAddress: AddressType, proposalId: number | string | bigint, tab?: string ) => LinkOptions +export type ProposalCreateStage = 'draft' | 'transactions' + export type ProposalCreateLinkHandler = ( chainId: CHAIN_ID, daoTokenAddress: AddressType, - stage?: 'draft' | 'transactions' + stage?: ProposalCreateStage ) => LinkOptions🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/types/src/links.ts` around lines 25 - 29, Introduce a shared exported type alias ProposalCreateStage = 'draft' | 'transactions' and replace the inline union in the ProposalCreateLinkHandler signature with that alias so the handler becomes (chainId: CHAIN_ID, daoTokenAddress: AddressType, stage?: ProposalCreateStage) => LinkOptions; update any other types/usages referencing the inline union to import and use ProposalCreateStage to prevent drift across consumers (keep LinkOptions and existing symbols unchanged).apps/web/src/modules/coin/CreateContentCoinForm/NoCreatorCoinWarning.tsx (1)
45-48: Avoid spreading fullrouter.queryinto proposal-create navigation.Passing all existing query params can leak unrelated state into the create route. Prefer explicit
network/token/stagekeys here for deterministic URLs.Suggested adjustment
router.push({ pathname: '/dao/[network]/[token]/proposal/create', query: { - ...router.query, + network: router.query.network, + token: router.query.token, stage: 'transactions', }, })🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/src/modules/coin/CreateContentCoinForm/NoCreatorCoinWarning.tsx` around lines 45 - 48, The navigation currently spreads router.query into the new URL (router.query), which can leak unrelated params; instead build the query object explicitly by selecting only the needed keys (e.g., network, token) and setting stage: 'transactions' before calling router.push or link builder in NoCreatorCoinWarning; locate the code that uses router.query (the query: { ...router.query, stage: 'transactions' } block) and replace the spread with an explicit object like { network: router.query.network, token: router.query.token, stage: 'transactions' } (or using optional chaining/defaults) so only deterministic params are forwarded.packages/create-proposal-ui/src/components/CreateProposalHeading/CreateProposalHeading.tsx (1)
121-146: Extract reset-confirmation modal into a shared component.Line 121–146 duplicates reset modal structure already present in
MobileProposalActionBar. A shared modal component would keep copy/actions/styles consistent.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/create-proposal-ui/src/components/CreateProposalHeading/CreateProposalHeading.tsx` around lines 121 - 146, Create a reusable ResetConfirmationModal component and replace the duplicated modal markup in CreateProposalHeading (the block using AnimatedModal, setResetModalOpen, resetModalOpen, and onReset) and the similar block in MobileProposalActionBar with that component: implement ResetConfirmationModal props for open, onConfirm, onCancel, title, description, confirmLabel and cancelLabel (or reasonable defaults), move the modal JSX into that component (using AnimatedModal and the same styles), and update CreateProposalHeading and MobileProposalActionBar to render <ResetConfirmationModal open={resetModalOpen} onConfirm={() => { onReset(); setResetModalOpen(false); }} onCancel={() => setResetModalOpen(false)} /> so copy/actions/styles remain consistent and centralized.apps/web/src/pages/dao/[network]/[token]/proposal/create.tsx (1)
210-251: SimplifycontinueHelperTextby deriving it from requirement arrays.Line 210–251 has a large branch matrix that can drift from
missingDraftRequirements/missingReviewRequirements. Consider generating the message from those arrays to reduce complexity.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/src/pages/dao/`[network]/[token]/proposal/create.tsx around lines 210 - 251, The current giant branch in continueHelperText should be replaced by deriving missing requirements from the existing requirement arrays instead of manual conditionals: inside the useMemo for continueHelperText, compute requiredMissing = createStage === 'draft' ? missingDraftRequirements.filter(Boolean) : missingReviewRequirements.filter(Boolean) (or build an array from booleans isMissingTitle/isMissingDescription/isMissingTransactions mapped to friendly labels), then if requiredMissing.length === 0 return null else return a single string like "To continue, add " + join the friendly labels with commas and " and " for the last item; reference continueHelperText, createStage, missingDraftRequirements/missingReviewRequirements (or isMissingTitle/isMissingDescription/isMissingTransactions) to locate where to change. Ensure the hook dependencies include the arrays/flags used.packages/create-proposal-ui/src/components/ProposalHelpLinks/ProposalHelpLinks.tsx (1)
4-6: Avoid hardcoded help URLs in this shared package.Line 16 and Line 32 hardcode destinations. In a reusable component package, this tightly couples behavior to one app/routing setup. Prefer passing hrefs via props (or a link provider) so host apps can control destinations.
♻️ Suggested refactor
type ProposalHelpLinksProps = { align?: 'left' | 'center' + createProposalGuideHref?: string + proposalTipsHref?: string } export const ProposalHelpLinks: React.FC<ProposalHelpLinksProps> = ({ align = 'left', + createProposalGuideHref = 'https://docs.nouns.build/onboarding/builder-proposal/', + proposalTipsHref = '/guidelines', }) => { @@ - <a href="https://docs.nouns.build/onboarding/builder-proposal/" ...> + <a href={createProposalGuideHref} ...> @@ - <a href="/guidelines" ...> + <a href={proposalTipsHref} ...>Also applies to: 15-33
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/create-proposal-ui/src/components/ProposalHelpLinks/ProposalHelpLinks.tsx` around lines 4 - 6, The component ProposalHelpLinks currently hardcodes help destinations; update it to accept hrefs via props (e.g., add optional props like proposalGuidelinesHref and howToVoteHref or a single links prop) and use those props instead of fixed URLs inside the ProposalHelpLinks component, falling back to existing defaults if props are undefined; update the ProposalHelpLinksProps type to include the new href properties and use them where the component renders the help links so host apps can control destinations.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/web/src/layouts/BaseLayout/BaseLayout.tsx`:
- Around line 43-45: The inline style { flex: 1 } on the Box can be lost when
props.style is passed; update BaseLayout so you merge props.style but ensure
flex: 1 wins (e.g., extract style from props with const { style, ...rest } =
props and render <Box style={{ ...style, flex: 1 }} {...rest}> {children}
</Box>) so other style attributes are preserved while guaranteeing flex: 1
remains applied.
In
`@packages/create-proposal-ui/src/components/ProposalStageIndicator/ProposalStageIndicator.tsx`:
- Around line 103-118: The Stack container currently uses onClick for selection
but is not keyboard-accessible; update the element rendered by
ProposalStageIndicator (the Stack with key={stage.id}) to support keyboard
activation by adding role="button" (or appropriate role), tabIndex={clickable &&
!isLocked ? 0 : -1}, aria-disabled={isLocked}, and a onKeyDown handler that
calls onStageSelect(stage.id) when Enter or Space is pressed (but only when
clickable and not isLocked), while preserving the existing onClick behavior;
ensure the handler prevents default for Space key so the page doesn't scroll.
In
`@packages/create-proposal-ui/src/components/ReviewProposalForm/ReviewProposalForm.tsx`:
- Around line 273-283: The timeline estimate logic incorrectly treats zero
values as missing; update the conditionals that compute estimatedVotingStartsAt,
estimatedVotingEndsAt, and estimatedEarliestExecutionAt to check for
null/undefined explicitly (e.g., votingDelay !== undefined && votingDelay !==
null) instead of using truthy checks so that 0 is preserved; ensure the same
explicit null/undefined checks are used where formatTimestamp consumes these
timestamps so DAOs with zero delays render correctly (refer to variables
votingDelay, votingPeriod, timelockDelay, nowTimestamp, estimatedVotingStartsAt,
estimatedVotingEndsAt, estimatedEarliestExecutionAt, and formatTimestamp).
In
`@packages/proposal-ui/src/components/ProposalDescription/StreamDetails/StreamItem.tsx`:
- Around line 218-219: The effect currently calls onOpenProposalReview() without
awaiting it, risking unhandled promise rejections; update the async callback
that references onOpenProposalReview, startProposalDraft, lockupAddress, and
liveData to await onOpenProposalReview() and wrap the call in try/catch so any
rejection is caught and handled (e.g., log or surface the error) before
proceeding.
In `@packages/stores/src/hooks/useProposalStore.ts`:
- Around line 71-75: startProposalDraft currently spreads the incoming draft
directly into state which allows explicit undefined values (e.g.,
draft.transactions or draft.disabled) to overwrite required fields in
initialState; sanitize the draft before merging by removing keys whose values
are undefined (e.g., build a sanitizedDraft from draft by filtering out entries
with value === undefined) and then set state with {...initialState,
...sanitizedDraft} so required fields on State (transactions, disabled, etc.)
can never be clobbered by undefined.
In `@packages/ui/src/DropdownSelect/DropdownSelect.tsx`:
- Line 102: The displayLabel assignment in DropdownSelect.tsx uses || which
treats valid falsy labels (like '' or 0) as missing; update the expression that
defines displayLabel (the const displayLabel in the DropdownSelect component) to
use the nullish coalescing operator (??) instead of || so it falls back only on
null/undefined (e.g. const displayLabel = customLabel ?? selectedOption?.label
?? 'Select option').
In `@packages/ui/src/MarkdownEditor/MarkdownEditor.tsx`:
- Around line 103-117: The fallback textarea in the MarkdownEditor component
lacks a programmatic label, hurting accessibility; update the <textarea>
rendered in MarkdownEditor (the element using props value and onChange) to
include a semantic label (either add an aria-label or aria-labelledby pointing
to an associated <label> element) so screen readers announce the field name;
ensure the chosen label string matches the visible label text and use the same
unique identifier (id) if using aria-labelledby so the association is explicit.
---
Outside diff comments:
In
`@packages/create-proposal-ui/src/components/TransactionForm/Droposal/DroposalForm.tsx`:
- Around line 88-96: In the DroposalForm component update the user-facing link
text inside the Text JSX (the anchor within the Text element) from "Lean more"
to the correct "Learn more"; locate the Text block in DroposalForm.tsx that
references the ZORA 721 Contract and replace the typo in the anchor content so
the displayed link reads "Learn more".
---
Nitpick comments:
In `@apps/web/src/modules/coin/CreateContentCoinForm/NoCreatorCoinWarning.tsx`:
- Around line 45-48: The navigation currently spreads router.query into the new
URL (router.query), which can leak unrelated params; instead build the query
object explicitly by selecting only the needed keys (e.g., network, token) and
setting stage: 'transactions' before calling router.push or link builder in
NoCreatorCoinWarning; locate the code that uses router.query (the query: {
...router.query, stage: 'transactions' } block) and replace the spread with an
explicit object like { network: router.query.network, token: router.query.token,
stage: 'transactions' } (or using optional chaining/defaults) so only
deterministic params are forwarded.
In `@apps/web/src/pages/dao/`[network]/[token]/proposal/create.tsx:
- Around line 210-251: The current giant branch in continueHelperText should be
replaced by deriving missing requirements from the existing requirement arrays
instead of manual conditionals: inside the useMemo for continueHelperText,
compute requiredMissing = createStage === 'draft' ?
missingDraftRequirements.filter(Boolean) :
missingReviewRequirements.filter(Boolean) (or build an array from booleans
isMissingTitle/isMissingDescription/isMissingTransactions mapped to friendly
labels), then if requiredMissing.length === 0 return null else return a single
string like "To continue, add " + join the friendly labels with commas and " and
" for the last item; reference continueHelperText, createStage,
missingDraftRequirements/missingReviewRequirements (or
isMissingTitle/isMissingDescription/isMissingTransactions) to locate where to
change. Ensure the hook dependencies include the arrays/flags used.
In
`@packages/create-proposal-ui/src/components/CreateProposalHeading/CreateProposalHeading.tsx`:
- Around line 121-146: Create a reusable ResetConfirmationModal component and
replace the duplicated modal markup in CreateProposalHeading (the block using
AnimatedModal, setResetModalOpen, resetModalOpen, and onReset) and the similar
block in MobileProposalActionBar with that component: implement
ResetConfirmationModal props for open, onConfirm, onCancel, title, description,
confirmLabel and cancelLabel (or reasonable defaults), move the modal JSX into
that component (using AnimatedModal and the same styles), and update
CreateProposalHeading and MobileProposalActionBar to render
<ResetConfirmationModal open={resetModalOpen} onConfirm={() => { onReset();
setResetModalOpen(false); }} onCancel={() => setResetModalOpen(false)} /> so
copy/actions/styles remain consistent and centralized.
In
`@packages/create-proposal-ui/src/components/ProposalHelpLinks/ProposalHelpLinks.tsx`:
- Around line 4-6: The component ProposalHelpLinks currently hardcodes help
destinations; update it to accept hrefs via props (e.g., add optional props like
proposalGuidelinesHref and howToVoteHref or a single links prop) and use those
props instead of fixed URLs inside the ProposalHelpLinks component, falling back
to existing defaults if props are undefined; update the ProposalHelpLinksProps
type to include the new href properties and use them where the component renders
the help links so host apps can control destinations.
In `@packages/types/src/links.ts`:
- Around line 25-29: Introduce a shared exported type alias ProposalCreateStage
= 'draft' | 'transactions' and replace the inline union in the
ProposalCreateLinkHandler signature with that alias so the handler becomes
(chainId: CHAIN_ID, daoTokenAddress: AddressType, stage?: ProposalCreateStage)
=> LinkOptions; update any other types/usages referencing the inline union to
import and use ProposalCreateStage to prevent drift across consumers (keep
LinkOptions and existing symbols unchanged).
In `@packages/ui/src/DropdownSelect/DropdownSelect.tsx`:
- Line 133: The align prop in DropdownSelect.tsx is using a redundant ternary
(option.description ? 'center' : 'center'); simplify by replacing that
expression with a single literal 'center' for the align prop in the
DropdownSelect component (remove the ternary and reference to
option.description).
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 59fe4070-144f-4c40-bf84-02b1cfa144ca
⛔ Files ignored due to path filters (2)
packages/zord/src/assets/pencil.svgis excluded by!**/*.svgpackages/zord/src/assets/queue.svgis excluded by!**/*.svg
📒 Files selected for processing (44)
apps/web/src/components/LinksProvider.tsxapps/web/src/layouts/BaseLayout/BaseLayout.tsxapps/web/src/layouts/DaoLayout/DaoLayout.tsxapps/web/src/modules/coin/CreateContentCoinForm/NoCreatorCoinWarning.tsxapps/web/src/pages/dao/[network]/[token]/[tokenId].tsxapps/web/src/pages/dao/[network]/[token]/index.tsxapps/web/src/pages/dao/[network]/[token]/proposal/create.tsxapps/web/src/pages/dao/[network]/[token]/proposal/review.tsxpackages/create-proposal-ui/src/components/CreateProposalHeading/CreateProposalHeading.tsxpackages/create-proposal-ui/src/components/MobileProposalActionBar/MobileProposalActionBar.css.tspackages/create-proposal-ui/src/components/MobileProposalActionBar/MobileProposalActionBar.tsxpackages/create-proposal-ui/src/components/MobileProposalActionBar/index.tspackages/create-proposal-ui/src/components/ProposalDraftForm/ProposalDraftForm.tsxpackages/create-proposal-ui/src/components/ProposalDraftForm/index.tspackages/create-proposal-ui/src/components/ProposalHelpLinks/ProposalHelpLinks.tsxpackages/create-proposal-ui/src/components/ProposalHelpLinks/index.tspackages/create-proposal-ui/src/components/ProposalStageIndicator/ProposalStageIndicator.tsxpackages/create-proposal-ui/src/components/ProposalStageIndicator/index.tspackages/create-proposal-ui/src/components/Queue/Queue.tsxpackages/create-proposal-ui/src/components/ReviewProposalForm/ReviewProposalForm.tsxpackages/create-proposal-ui/src/components/SelectTransactionType/AdminNav.tsxpackages/create-proposal-ui/src/components/SelectTransactionType/SelectTransactionType.tsxpackages/create-proposal-ui/src/components/SelectTransactionType/TransactionTypeCard.tsxpackages/create-proposal-ui/src/components/SelectTransactionType/index.tspackages/create-proposal-ui/src/components/TransactionForm/Droposal/DroposalForm.tsxpackages/create-proposal-ui/src/components/TransactionForm/Droposal/DroposalPreview.tsxpackages/create-proposal-ui/src/components/index.tspackages/dao-ui/src/components/Activity/Activity.tsxpackages/dao-ui/src/components/AdminForm/AdminForm.tsxpackages/dao-ui/src/components/FixRendererBase/FixRendererBase.tsxpackages/dao-ui/src/components/Gallery/Gallery.tsxpackages/dao-ui/src/components/Upgrade/Upgrade.tsxpackages/hooks/src/useDecodedTransactions.tspackages/proposal-ui/src/components/ProposalDescription/MilestoneDetails/EscrowInstance.tsxpackages/proposal-ui/src/components/ProposalDescription/ProposalDescription.tsxpackages/proposal-ui/src/components/ProposalDescription/Section.tsxpackages/proposal-ui/src/components/ProposalDescription/StreamDetails/StreamItem.tsxpackages/stores/src/hooks/useProposalStore.tspackages/types/src/links.tspackages/ui/src/DropdownSelect/DropdownSelect.tsxpackages/ui/src/LinksProvider/LinksProvider.tsxpackages/ui/src/MarkdownEditor/MarkdownEditor.tsxpackages/zord/src/elements/Spinner.css.tspackages/zord/src/icons.ts
💤 Files with no reviewable changes (4)
- packages/create-proposal-ui/src/components/SelectTransactionType/index.ts
- packages/create-proposal-ui/src/components/SelectTransactionType/SelectTransactionType.tsx
- packages/create-proposal-ui/src/components/SelectTransactionType/TransactionTypeCard.tsx
- packages/create-proposal-ui/src/components/SelectTransactionType/AdminNav.tsx
packages/create-proposal-ui/src/components/ProposalStageIndicator/ProposalStageIndicator.tsx
Show resolved
Hide resolved
packages/create-proposal-ui/src/components/ReviewProposalForm/ReviewProposalForm.tsx
Outdated
Show resolved
Hide resolved
packages/proposal-ui/src/components/ProposalDescription/StreamDetails/StreamItem.tsx
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
🧹 Nitpick comments (3)
packages/ui/src/DropdownSelect/DropdownSelect.tsx (1)
65-65: Consider requiring explicitvalueprop for API consistency, though current usage is safe.The optional
value?: Tpattern allows callers to omit it entirely. While all current call sites provide the prop explicitly (includingvalue={undefined}where appropriate), making it required asvalue: T | undefinedwould strengthen the API contract and prevent accidental omission. The component currently handles undefined values gracefully with fallback logic ('Select option'), so this is a refinement rather than a bug fix.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/ui/src/DropdownSelect/DropdownSelect.tsx` at line 65, Change the prop type for DropdownSelect to require the value prop explicitly by replacing the optional signature `value?: T` with `value: T | undefined` in the DropdownSelect props/interface; update any places that construct or spread those props (referencing the DropdownSelect component and its props type) to pass `value` explicitly (use `value={undefined}` where omission was intended) so compiler enforces callers provide the prop while component logic (fallback to 'Select option') remains unchanged.packages/create-proposal-ui/src/components/ResetConfirmationModal/ResetConfirmationModal.tsx (1)
33-39: Consider using a destructive variant for the reset confirmation button.The "Reset" action is destructive (clears title, summary, and queued transactions), but the confirm button uses the default primary variant. Typically, destructive confirmation buttons use a distinct visual treatment (e.g., red/danger styling) to signal the irreversible nature of the action.
If the
Buttoncomponent supports avariant="destructive"or similar, consider using it for the confirm button.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/create-proposal-ui/src/components/ResetConfirmationModal/ResetConfirmationModal.tsx` around lines 33 - 39, The confirm button in ResetConfirmationModal is using the default primary style but should signal a destructive action; update the Button that renders {confirmLabel} (the one with onClick={onConfirm}) to use the destructive/danger variant supported by the Button API (e.g., variant="destructive" or variant="danger") so the Reset confirm is visually distinct and communicates its irreversible effect.packages/create-proposal-ui/src/components/MobileProposalActionBar/MobileProposalActionBar.tsx (1)
48-55: Add explicittype="button"to all buttons for safe form embedding.These buttons are rendered inside a
<form>element in ReviewProposalForm. While the Button component from@buildeross/zordcurrently defaults totype="button"(line 66 of Button.tsx), explicitly setting this type prevents accidental form submissions if component defaults change in the future.Apply to: Back (line 48), Queue (line 57), Reset (line 66), and Continue (line 75) buttons.
Proposed patch
{showBack && onBack && ( <Button + type="button" variant="secondary" aria-label="Back" disabled={backDisabled} onClick={onBack} > @@ {showQueue && transactions.length > 0 && ( <Button + type="button" variant="secondary" aria-label={`Open queue with ${transactions.length} transactions`} onClick={() => setQueueModalOpen(true)} > @@ {showReset && onReset && ( <Button + type="button" variant="secondary" aria-label="Reset proposal" onClick={() => setResetModalOpen(true)} > @@ {showContinue && onContinue && ( <Button + type="button" className={mobileActionPrimary} disabled={continueDisabled} loading={continueLoading} onClick={onContinue}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/create-proposal-ui/src/components/MobileProposalActionBar/MobileProposalActionBar.tsx` around lines 48 - 55, The Button elements in MobileProposalActionBar (the Back, Queue, Reset, and Continue Button instances) need an explicit type attribute to avoid accidental form submissions; update each Button JSX (the Back Button with Icon id="arrowLeft", the Queue Button, the Reset Button, and the Continue Button) to include type="button" so they no longer rely on the Button component default.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In
`@packages/create-proposal-ui/src/components/MobileProposalActionBar/MobileProposalActionBar.tsx`:
- Around line 48-55: The Button elements in MobileProposalActionBar (the Back,
Queue, Reset, and Continue Button instances) need an explicit type attribute to
avoid accidental form submissions; update each Button JSX (the Back Button with
Icon id="arrowLeft", the Queue Button, the Reset Button, and the Continue
Button) to include type="button" so they no longer rely on the Button component
default.
In
`@packages/create-proposal-ui/src/components/ResetConfirmationModal/ResetConfirmationModal.tsx`:
- Around line 33-39: The confirm button in ResetConfirmationModal is using the
default primary style but should signal a destructive action; update the Button
that renders {confirmLabel} (the one with onClick={onConfirm}) to use the
destructive/danger variant supported by the Button API (e.g.,
variant="destructive" or variant="danger") so the Reset confirm is visually
distinct and communicates its irreversible effect.
In `@packages/ui/src/DropdownSelect/DropdownSelect.tsx`:
- Line 65: Change the prop type for DropdownSelect to require the value prop
explicitly by replacing the optional signature `value?: T` with `value: T |
undefined` in the DropdownSelect props/interface; update any places that
construct or spread those props (referencing the DropdownSelect component and
its props type) to pass `value` explicitly (use `value={undefined}` where
omission was intended) so compiler enforces callers provide the prop while
component logic (fallback to 'Select option') remains unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 81904fcd-c57c-4f87-be16-0b1966dfcbed
📒 Files selected for processing (23)
apps/web/src/components/LinksProvider.tsxapps/web/src/layouts/BaseLayout/BaseLayout.tsxapps/web/src/modules/coin/CreateContentCoinForm/NoCreatorCoinWarning.tsxapps/web/src/pages/dao/[network]/[token]/[tokenId].tsxapps/web/src/pages/dao/[network]/[token]/index.tsxapps/web/src/pages/dao/[network]/[token]/proposal/create.tsxapps/web/src/pages/dao/[network]/[token]/proposal/review.tsxpackages/create-proposal-ui/src/components/CreateProposalHeading/CreateProposalHeading.tsxpackages/create-proposal-ui/src/components/MobileProposalActionBar/MobileProposalActionBar.tsxpackages/create-proposal-ui/src/components/ProposalHelpLinks/ProposalHelpLinks.tsxpackages/create-proposal-ui/src/components/ProposalStageIndicator/ProposalStageIndicator.tsxpackages/create-proposal-ui/src/components/ResetConfirmationModal/ResetConfirmationModal.tsxpackages/create-proposal-ui/src/components/ResetConfirmationModal/index.tspackages/create-proposal-ui/src/components/ReviewProposalForm/ReviewProposalForm.tsxpackages/create-proposal-ui/src/components/TransactionForm/Droposal/DroposalForm.tsxpackages/create-proposal-ui/src/components/index.tspackages/dao-ui/src/components/Gallery/Gallery.tsxpackages/proposal-ui/src/components/ProposalDescription/StreamDetails/StreamItem.tsxpackages/stores/src/hooks/useProposalStore.tspackages/types/src/links.tspackages/ui/src/DropdownSelect/DropdownSelect.tsxpackages/ui/src/LinksProvider/LinksProvider.tsxpackages/ui/src/MarkdownEditor/MarkdownEditor.tsx
🚧 Files skipped from review as they are similar to previous changes (6)
- packages/create-proposal-ui/src/components/ProposalStageIndicator/ProposalStageIndicator.tsx
- packages/proposal-ui/src/components/ProposalDescription/StreamDetails/StreamItem.tsx
- packages/create-proposal-ui/src/components/ProposalHelpLinks/ProposalHelpLinks.tsx
- apps/web/src/modules/coin/CreateContentCoinForm/NoCreatorCoinWarning.tsx
- apps/web/src/components/LinksProvider.tsx
- packages/ui/src/MarkdownEditor/MarkdownEditor.tsx
Summary by CodeRabbit
New Features
Improvements