Skip to content

Latest commit

Β 

History

History
1551 lines (1287 loc) Β· 96.8 KB

File metadata and controls

1551 lines (1287 loc) Β· 96.8 KB
type Feature
title Persist wallet connection across reloads with a WalletProvider context
labels type:feature, area:wallet, stack:nextjs, stack:react, stack:typescript, priority:high, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN
assignees

Implement a shared WalletProvider that persists the connection across reloads

Description

components/WalletStatus.jsx keeps walletState/walletData in local component state, so the connection is lost on every navigation or page refresh and cannot be read by other components (e.g. a future "Fund this invoice" button or the Invoices page header). This issue introduces a WalletProvider React context that owns the wallet state, rehydrates it from storage on mount, and exposes a useWallet() hook.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Create components/WalletProvider.jsx exporting WalletProvider and a useWallet() hook returning { state, walletData, connect, disconnect }, reusing the existing WALLET_STATES enum from components/WalletStatus.jsx.
  • Persist a minimal, non-sensitive snapshot (connection intent + truncated address + network) via localStorage and rehydrate on mount; never persist secrets or full balances.
  • Refactor WalletStatus to consume useWallet() instead of its internal useState, keeping all existing accessibility regions and toast calls intact.
  • Mount WalletProvider once in app/layout.js inside the existing ToastProvider.
  • Guard against SSR by reading storage only after mount (no window access during render).

Suggested execution

Test and commit

  • Run npm run lint, npm test, and npm run build.
  • Cover edge cases: corrupt storage payload, SSR render, and rehydrate-then-disconnect.
  • Include the full npm test output and a note on what is persisted.

Example commit message

feat: persist wallet connection via a shared walletprovider context

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Add a client-side search box to filter the Invest marketplace by issuer" labels: type:feature, area:invest, stack:nextjs, stack:react, stack:typescript, priority:medium, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Implement an issuer search field on the Invest marketplace

Description

The marketplace list in app/invest/page.js renders every loaded invoice with no way to find a specific issuer; as the list grows beyond the three mock entries this becomes unusable. This issue adds a debounced search input that filters the rendered invoices by issuer name and keeps the polite aria-live announcement accurate.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Add a labelled search <input type="search"> above the list that filters invoices by case-insensitive substring match on issuer.
  • Debounce the input (e.g. 200ms) so filtering does not thrash on every keystroke.
  • Update getInvoiceLoadAnnouncement usage so the status region announces the filtered count (e.g. "2 of 3 invoices match"), and show a distinct "no matches" state separate from the empty-marketplace state.
  • Preserve the loading/error/empty branches and the slate/cyan styling; clearing the field restores the full list.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b feature/invest-02-issuer-search
  • Implement changes
    • Write code in: update app/invest/page.js; optionally extract a components/InvoiceSearch.jsx.
    • Write comprehensive tests in: extend app/invest/page.test.jsx and/or create components/InvoiceSearch.test.tsx β€” assert filtering, debounce, no-match state, and clear.
    • Add documentation: note the search behaviour in README.md.
    • Add JSDoc on any extracted search component.
    • Validate a11y: the input has an associated label and the filtered count is announced politely.
  • Test and commit

Test and commit

  • Run npm run lint, npm test, and npm run build.
  • Cover edge cases: empty query, no matches, whitespace-only query, and rapid typing.
  • Include the full npm test output.

Example commit message

feat: add issuer search box to the invest marketplace

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Add pagination or load-more to the Invest marketplace list" labels: type:feature, area:invest, stack:nextjs, stack:react, stack:typescript, priority:medium, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Implement pagination for the marketplace invoice list

Description

app/invest/page.js maps the entire invoice array into a single <ul> with no paging or windowing, so a real backend returning hundreds of invoices would render an unbounded DOM and a long, unscannable list. This issue adds page-size-bounded rendering with an accessible "Load more" (or numbered pages) control.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Render at most PAGE_SIZE (e.g. 10) invoices at a time and expose a "Load more" button (or prev/next page controls) that reveals the next batch.
  • Keep the polite status region accurate ("Showing N of M invoices"); announce when more results are appended.
  • Reset paging when filters/search change (coordinate with the existing list rendering so the change is non-breaking if those features land later).
  • Preserve loading/empty/error branches and keyboard focus on the control after each load.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b feature/invest-03-marketplace-pagination
  • Implement changes
    • Write code in: update app/invest/page.js; optionally extract a components/Pagination.jsx.
    • Write comprehensive tests in: extend app/invest/page.test.jsx β€” assert initial page size, load-more appends, and the count announcement.
    • Add documentation: note paging behaviour in README.md.
    • Add JSDoc on any pagination helper/component.
    • Validate a11y: the control has a clear accessible name and focus is managed after load.
  • Test and commit

Test and commit

  • Run npm run lint, npm test, and npm run build.
  • Cover edge cases: fewer items than a page, exact page boundary, and last page.
  • Include the full npm test output.

Example commit message

feat: paginate the invest marketplace invoice list

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Show a determinate progress bar during invoice upload in UploadZone" labels: type:enhancement, area:upload, stack:nextjs, stack:react, stack:typescript, priority:medium, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Add an accessible upload progress indicator to UploadZone

Description

components/UploadZone.jsx only shows an indeterminate spinner with "Uploading invoice..." during the uploading status; the user gets no sense of how far along a large (up to 10 MB) PDF upload is. This issue adds a determinate progress bar driven by upload progress events, with proper ARIA so screen-reader users hear progress too.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Render a role="progressbar" element with aria-valuemin/aria-valuemax/aria-valuenow and a visible percentage during the uploading status.
  • Accept an injectable onProgress-style callback (or progress prop) so the bar can be driven by a real XMLHttpRequest/fetch-stream progress source later and tested deterministically now.
  • Fall back to the existing indeterminate spinner when progress is unknown; keep the tokenizing and success copy unchanged so the e2e spec in tests/toast.spec.jsx still passes.
  • Respect prefers-reduced-motion for any bar transition.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b enhancement/upload-04-progress-bar
  • Implement changes
    • Write code in: update components/UploadZone.jsx; optionally extract a components/ProgressBar.jsx.
    • Write comprehensive tests in: extend components/UploadZone.test.jsx β€” assert progressbar ARIA values update and the indeterminate fallback.
    • Add documentation: note the progress UI in README.md.
    • Add JSDoc on the progress prop/callback.
    • Validate a11y: progressbar exposes value text and does not steal focus.
  • Test and commit

Test and commit

  • Run npm run lint, npm test, npm run build, and npm run test:e2e.
  • Cover edge cases: 0%, 100%, unknown-progress fallback, and reduced motion.
  • Include the full npm test output and confirmation the toast e2e still passes.

Example commit message

feat: add accessible upload progress bar to uploadzone

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Allow resetting UploadZone to upload another invoice after success" labels: type:enhancement, area:upload, stack:nextjs, stack:react, stack:typescript, priority:medium, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Add an "Upload another" reset flow to UploadZone

Description

After a successful submission components/UploadZone.jsx stays in the success status with the previous file still selected, and the submit button relabels to "Upload & Tokenize Invoice" while still pointing at the already-submitted file β€” there is no clean way to start a fresh upload without reloading the page. This issue adds an explicit reset that clears the file, error, and status back to idle.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Add an "Upload another invoice" button shown in the success state that resets file, error, and status to their initial values and clears the file <input>.
  • Move focus to the dropzone after reset so keyboard users can immediately start again.
  • Keep the existing status copy and role="status"/role="alert" regions; the success message should clear on reset.
  • Do not change the disabled/aria-disabled logic on #invoice-upload-btn for the idle/processing states.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b enhancement/upload-05-reset-flow
  • Implement changes
    • Write code in: update components/UploadZone.jsx.
    • Write comprehensive tests in: extend components/UploadZone.test.jsx β€” assert reset clears file/status and restores focus.
    • Add documentation: note the reset flow in README.md.
    • Add comments explaining the focus-management choice.
    • Validate a11y: focus lands on a sensible target after reset.
  • Test and commit

Test and commit

  • Run npm run lint, npm test, and npm run build.
  • Cover edge cases: reset after success, reset clears stale error, and re-upload after reset.
  • Include the full npm test output.

Example commit message

feat: add upload-another reset flow to uploadzone

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Cap the toast stack and de-duplicate repeated messages in ToastProvider" labels: type:enhancement, area:toast, stack:nextjs, stack:react, stack:typescript, priority:medium, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Bound the toast queue and collapse duplicates

Description

components/ToastProvider.jsx prepends every new toast to an unbounded array ([toast, ...current]) with no limit and no de-duplication, so a retry loop or rapid wallet errors (see the random-outcome flow in components/WalletStatus.jsx) can stack dozens of identical toasts and cover the viewport. This issue caps the visible stack and collapses duplicates.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Add a MAX_TOASTS limit (e.g. 3); when exceeded, drop the oldest toast and clear its timer in timers.
  • De-duplicate by variant + title + message: if an identical toast is already visible, refresh its auto-dismiss timer instead of adding a new one.
  • Preserve the public success/error/info API, the AUTO_DISMISS_MS behaviour, and pause/resume on hover.
  • Keep the role="status"/aria-live="polite" live region and ensure timer cleanup remains leak-free.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b enhancement/toast-06-cap-and-dedupe
  • Implement changes
    • Write code in: update components/ToastProvider.jsx.
    • Write comprehensive tests in: create components/ToastProvider.dedupe.test.tsx using fake timers β€” assert cap eviction, duplicate collapse, and no timer leaks.
    • Add documentation: note the queue limits in README.md.
    • Add JSDoc/comments on MAX_TOASTS and the dedupe key.
    • Validate a11y: stacked toasts remain individually dismissible.
  • Test and commit

Test and commit

  • Run npm run lint, npm test, and npm run build.
  • Cover edge cases: burst of identical toasts, cap eviction during hover-pause, and unmount mid-timer.
  • Include the full npm test output.

Example commit message

feat: cap toast stack and de-duplicate repeated messages

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Make the marketplace error state retryable with a working ErrorBanner action" labels: type:enhancement, area:invest, stack:nextjs, stack:react, stack:typescript, priority:medium, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Wire a retry action into the Invest marketplace error state

Description

When loadInvoices rejects, app/invest/page.js renders an ErrorBanner with only title/description/previewLabel β€” but components/ErrorBanner.jsx already supports actionLabel/onAction, which is unused here. The user has no way to recover except a full page reload. This issue adds a "Try again" action that re-runs the load.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Refactor InvestMarketplace so the load logic is callable on demand (e.g. a reload() that resets state to loading and re-invokes loadInvoices).
  • Pass actionLabel="Try again" and onAction={reload} to the ErrorBanner so the existing action button is used.
  • Reset loadError, set invoices back to null (loading), and re-announce via the polite status region on retry.
  • Continue to honour the AbortController/isActive cancellation so a retry does not race a stale request.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b enhancement/invest-07-retryable-error
  • Implement changes
    • Write code in: update app/invest/page.js.
    • Write comprehensive tests in: extend app/invest/page.test.jsx β€” fail then succeed on retry, assert the loading skeleton reappears and the list renders.
    • Add documentation: note the retry behaviour in README.md.
    • Add comments on the reload/abort interaction.
    • Validate a11y: the retry button has a clear accessible name and focus is sensible after retry.
  • Test and commit

Test and commit

  • Run npm run lint, npm test, and npm run build.
  • Cover edge cases: retry-after-failure success, retry-then-failure, and rapid double retry.
  • Include the full npm test output.

Example commit message

feat: add retry action to the invest marketplace error state

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Add a responsive mobile navigation menu to the app header" labels: type:feature, area:navigation, stack:nextjs, stack:react, stack:typescript, priority:medium, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Implement a responsive header navigation for small screens

Description

The headers in app/page.js, app/invoices/page.js, and app/invest/page.js place the brand and a "Connect Wallet" button in a single flex row with no links to the Invoices/Invest sections and no mobile menu β€” on narrow viewports there is no navigation affordance at all. This issue adds an accessible responsive nav with a disclosure menu on mobile.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Create components/NavMenu.jsx with links to Home, Invoices (/invoices), and Invest (/invest), rendered inline on desktop and behind an accessible toggle button (aria-expanded, aria-controls) on mobile.
  • Mark the current route as aria-current="page".
  • Close the menu on Escape and on navigation, and trap/return focus appropriately when open.
  • Keep the existing slate/cyan styling and the brand wordmark/back-link semantics; do not duplicate the static Connect Wallet button (reference the wallet UI rather than re-adding dead buttons).

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b feature/navigation-08-responsive-nav
  • Implement changes
  • Test and commit

Test and commit

  • Run npm run lint, npm test, and npm run build.
  • Cover edge cases: open/close, Escape, current-route marking, and focus return.
  • Include the full npm test output.

Example commit message

feat: add responsive mobile navigation menu to the header

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Externalize copy into a typed i18n dictionary and remove inline strings" labels: type:refactor, area:i18n, stack:nextjs, stack:react, stack:typescript, priority:medium, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Centralize UI copy and remove hard-coded strings

Description

app/copy/en.js holds some strings, but many user-facing strings are still inlined: the marketplace yield disclaimer and filter labels in app/invest/page.js, the upload status copy in components/UploadZone.jsx, and the wallet helper texts in components/WalletStatus.jsx. This drift makes copy edits and future localization error-prone. This issue moves all visible strings into the dictionary and gives it a typed shape.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Extend app/copy/en.js with keys for the upload statuses, wallet states/helper texts, marketplace filter labels, and the yield disclaimer.
  • Replace the inline literals in the components/pages above with dictionary lookups.
  • Add a JSDoc @typedef (or a copy.types.js) describing the dictionary shape so missing keys are catchable.
  • No visible copy or behaviour change β€” strings must render identically.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b refactor/i18n-09-externalize-copy
  • Implement changes
  • Test and commit

Test and commit

  • Run npm run lint, npm test, and npm run build.
  • Cover edge cases: every referenced key exists; rendered text is byte-identical.
  • Include the full npm test output and a before/after string inventory.

Example commit message

refactor: externalize ui copy into a typed dictionary

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Lazy-load WalletStatus to keep wallet code off the initial bundle" labels: type:refactor, area:performance, stack:nextjs, stack:react, stack:typescript, priority:low, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Code-split the wallet UI with dynamic import

Description

components/WalletStatus.jsx is a client component that will soon pull in the Stellar/Freighter SDK, yet once mounted in the shared header it would ship in the first-load JS of every route β€” including the static home page that does not need wallet logic immediately. This issue lazy-loads the wallet UI so it is fetched on demand without blocking initial render.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Use next/dynamic to load WalletStatus (with ssr: false where appropriate) behind a small static placeholder that matches its dimensions to avoid layout shift.
  • Keep the exported WALLET_STATES import path stable for tests.
  • Ensure the accessible status region still mounts once the chunk loads and that no hydration warnings appear.
  • Document the measured first-load JS impact (before/after) using npm run build output.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b refactor/performance-10-lazy-walletstatus
  • Implement changes
    • Write code in: update the header/consumer that renders WalletStatus (e.g. app/page.js) to use a dynamic import wrapper.
    • Write comprehensive tests in: create components/WalletStatus.lazy.test.tsx β€” assert the placeholder renders then the wallet UI appears.
    • Add documentation: note the code-splitting decision in README.md with before/after bundle numbers.
    • Add comments explaining the ssr/placeholder choice.
    • Validate: no CLS from the placeholder swap.
  • Test and commit

Test and commit

  • Run npm run lint, npm test, and npm run build.
  • Cover edge cases: placeholder dimensions, hydration, and lazy mount.
  • Include the npm run build first-load JS comparison.

Example commit message

perf: lazy-load walletstatus to reduce initial bundle

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Extract a shared Button component to unify variants and focus styles" labels: type:refactor, area:components, stack:nextjs, stack:react, stack:typescript, priority:medium, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Refactor duplicated button markup into a shared Button

Description

Button styling is copy-pasted across the app with subtly different focus rings: the cyan pill in app/page.js, the disabled filter buttons in app/invest/page.js, the submit button and Spinner in components/UploadZone.jsx, the variant switch in components/WalletStatus.jsx, and the action button in components/ErrorBanner.jsx. They diverge (focus:ring vs focus-visible:outline), which is exactly the inconsistency a shared component prevents. This issue introduces a single Button.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Create components/Button.jsx supporting variant (primary/secondary/warning/external/danger), loading (renders the shared spinner), disabled, and forwarded props/ref.
  • Apply one consistent focus-visible outline across all variants.
  • Migrate the buttons in the files above to use Button without visual regressions.
  • Export the shared Spinner from Button (or a components/Spinner.jsx) and stop redefining the inline SVG in WalletStatus/UploadZone.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b refactor/components-11-shared-button
  • Implement changes
    • Write code in: create components/Button.jsx (and optionally components/Spinner.jsx); update the consumers listed above.
    • Write comprehensive tests in: create components/Button.test.tsx β€” assert variants, disabled/loading, and focus styles.
    • Add documentation: document Button in README.md UI section.
    • Add JSDoc on the props.
    • Validate a11y: focus-visible outline meets contrast; loading sets aria-busy.
  • Test and commit

Test and commit

  • Run npm run lint, npm test, and npm run build.
  • Cover edge cases: each variant, loading state, and disabled state.
  • Include the full npm test output and a before/after note confirming no visual change.

Example commit message

refactor: extract shared button and spinner components

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Add behavioral unit tests for the ErrorBanner component" labels: type:test, area:error-banner, stack:nextjs, stack:react, stack:typescript, priority:medium, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Test the ErrorBanner variants and action behaviour

Description

components/ErrorBanner.jsx has only an a11y smoke test in components/__tests__/ErrorBanner.a11y.test.jsx; its variant label switch (server vs validation), conditional details, and the actionLabel/onAction button are not behaviorally tested. This issue adds full coverage of its rendering contract.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Assert variantLabel renders "Server error" for server/default and "Validation error" for validation.
  • Assert title/description/previewLabel render, that details only renders when provided, and that the action button appears only when actionLabel is set and calls onAction on click.
  • Assert the role="alert"/aria-live="assertive" container is present.
  • Use @testing-library/user-event for the action click.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b test/error-banner-12-behavioral-coverage
  • Implement changes
    • Write code in: no source change unless a bug is found in components/ErrorBanner.jsx.
    • Write comprehensive tests in: create components/ErrorBanner.test.tsx.
    • Add documentation: none beyond test comments.
    • Add comments documenting the variant matrix.
    • Validate a11y: keep an axe check alongside the behavioral assertions.
  • Test and commit

Test and commit

  • Run npm run lint, npm test, and npm run build.
  • Cover edge cases: missing details, missing actionLabel, and both variants.
  • Include the full npm test output with ErrorBanner coverage.

Example commit message

test: cover errorbanner variants and action behaviour

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Add unit tests for the getInvoiceLoadAnnouncement helper and InvestMarketplace states" labels: type:test, area:invest, stack:nextjs, stack:react, stack:typescript, priority:medium, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Test the marketplace announcement helper and load states

Description

app/invest/page.js exports getInvoiceLoadAnnouncement and an injectable InvestMarketplace, but app/invest/page.test.jsx does not cover the helper's branches directly nor the abort/unmount path in the effect. This issue adds focused coverage for the pure helper and the loading/empty/error/non-array states.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Unit-test getInvoiceLoadAnnouncement for: non-array input, empty array, and N>0 (assert exact strings "No invoices available" / "N investable invoices loaded").
  • Test InvestMarketplace with injected loaders that resolve to a list, an empty array, a non-array (coerced to []), and a rejected promise (error banner + announcement).
  • Assert the skeleton renders while the loader is pending and that unmount during a pending load does not throw or set state (the isActive guard).
  • Reuse the injectable loadInvoices prop already used by the existing test.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b test/invest-13-announcement-and-states
  • Implement changes
  • Test and commit

Test and commit

  • Run npm run lint, npm test, and npm run build.
  • Cover edge cases: non-array, empty, populated, rejected, and unmount-mid-load.
  • Include the full npm test output with invest coverage.

Example commit message

test: cover getinvoiceloadannouncement and marketplace load states

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Add unit tests for the InvoiceListSkeleton row count and loading semantics" labels: type:test, area:loading-states, stack:nextjs, stack:react, stack:typescript, priority:low, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Test the InvoiceListSkeleton rendering contract

Description

components/InvoiceListSkeleton.jsx renders rows placeholder list items with aria-busy="true" and an "Loading investable invoices" label, but components/InvoiceListSkeleton.test.jsx is thin. This issue ensures the row count, default, and loading semantics are locked in so the skeleton stays in sync with the real card layout.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Assert the component renders exactly rows <li> items and falls back to the documented default when rows is omitted.
  • Assert the list carries aria-busy="true" and the aria-label "Loading investable invoices".
  • Assert each row contains the issuer/status and amount/yield/maturity placeholder blocks so a future card refactor cannot silently drop columns.
  • Cover rows={0} (no items, list still present).

Suggested execution

Test and commit

  • Run npm run lint, npm test, and npm run build.
  • Cover edge cases: default rows, custom rows, and rows={0}.
  • Include the full npm test output.

Example commit message

test: cover invoicelistskeleton row count and loading semantics

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Add unit tests for the Invoices page upload integration and header" labels: type:test, area:invoices, stack:nextjs, stack:react, stack:typescript, priority:medium, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Test the Invoices page rendering and UploadZone wiring

Description

app/invoices/page.js renders the title, subtext, back link, a Connect Wallet button, and an <UploadZone />, but has no unit test, so a broken copy key, a missing UploadZone mount, or a regressed back-link focus-visible style would go unnoticed. This issue adds coverage for the page composition.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Assert the heading and subtext from copy.invoices render and the "← LiquiFact" link points to /.
  • Assert the UploadZone form mounts (e.g. the #invoice-file-input and #invoice-upload-btn are present).
  • Assert the back link carries the focus-visible outline classes that distinguish this page from the others.
  • Keep the test resilient to UploadZone internals by querying roles/ids rather than implementation details.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b test/invoices-15-page-coverage
  • Implement changes
    • Write code in: no source change unless a bug is found in app/invoices/page.js.
    • Write comprehensive tests in: create app/invoices/page.test.tsx.
    • Add documentation: none beyond test comments.
    • Add comments on how UploadZone is queried.
    • Validate a11y: optional jest-axe smoke check on the page.
  • Test and commit

Test and commit

  • Run npm run lint, npm test, and npm run build.
  • Cover edge cases: copy rendering, UploadZone mount, and back-link target.
  • Include the full npm test output.

Example commit message

test: cover the invoices page composition and uploadzone wiring

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Make WalletStatus open the wallet install page safely via rel=noopener" labels: type:security, area:wallet, stack:nextjs, stack:react, stack:typescript, priority:medium, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Harden the external wallet-install navigation in WalletStatus

Description

In the NO_WALLET state, components/WalletStatus.jsx opens the install page with window.open('https://www.stellar.org/wallets', '_blank') β€” without the noopener,noreferrer window features, the opened tab can access window.opener (reverse-tabnabbing), and an untrusted URL would flow straight through. This issue makes the external navigation safe and centralizes the allowed destination.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Pass 'noopener,noreferrer' as the window.open features argument and null the returned reference's opener as a defensive fallback.
  • Move the install URL into a single trusted constant (or app/copy/en.js) and validate it is an https: origin before opening.
  • Preserve the WALLET_STATES.NO_WALLET button behaviour and accessibility.
  • Audit any other window.open/external anchors introduced here for the same protection.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b security/wallet-16-safe-external-open
  • Implement changes
    • Write code in: update components/WalletStatus.jsx; add the URL constant where appropriate.
    • Write comprehensive tests in: create components/WalletStatus.external.test.tsx β€” mock window.open and assert the features string and URL.
    • Add documentation: note the external-link policy in README.md.
    • Add comments explaining the tabnabbing mitigation.
    • Validate security: confirm noopener is set and only https: URLs are opened.
  • Test and commit

Test and commit

  • Run npm run lint, npm test, and npm run build.
  • Cover edge cases: correct features argument and rejected non-https URL.
  • Include the full npm test output and a short threat note.

Example commit message

fix: open wallet install page with noopener to prevent tabnabbing

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Bound and safely render the backend health JSON on the home page" labels: type:security, area:home, stack:nextjs, stack:react, stack:typescript, priority:medium, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Harden how the home page renders untrusted health responses

Description

app/page.js takes whatever the backend returns from /health and dumps it via JSON.stringify(health, null, 2) into a <pre> with overflow-auto β€” an attacker-controlled or compromised backend could return an enormous payload (DoS via giant render) or deeply nested data that bloats the page. While React escapes text, the size and shape are unbounded. This issue bounds and sanitizes what is rendered.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Cap the rendered payload size (e.g. truncate the stringified output to a max length with an explicit "…(truncated)" marker) and limit object depth before display.
  • Render a small set of recognized fields (e.g. status, message, version) in a structured way and keep the raw payload behind a collapsible <details> rather than always-expanded.
  • Never render the response as HTML; keep it as text content only.
  • Coordinate gracefully with the health-check helper if present, without duplicating fetch logic.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b security/home-17-bounded-health-render
  • Implement changes
    • Write code in: update app/page.js; optionally add a lib/format/safeJson.js helper.
    • Write comprehensive tests in: create app/page.health-render.test.tsx and/or lib/format/safeJson.test.tsx β€” assert truncation, depth limit, and recognized-field rendering.
    • Add documentation: note the bounded rendering in README.md.
    • Add JSDoc on the formatting helper.
    • Validate security: confirm large/nested payloads cannot blow up the DOM.
  • Test and commit

Test and commit

  • Run npm run lint, npm test, and npm run build.
  • Cover edge cases: huge string, deep nesting, and a normal healthy payload.
  • Include the full npm test output and a short note on the limits chosen.

Example commit message

fix: bound and safely render backend health json on the home page

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Add a Dependabot config and lockfile-integrity check for the frontend" labels: type:security, area:dependencies, stack:nextjs, stack:react, stack:typescript, priority:low, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Automate dependency updates with Dependabot and a lockfile check

Description

The repo pins next, react, and a set of dev tooling in package.json with a committed package-lock.json, but there is no .github/dependabot.yml and CI (.github/workflows/ci.yml) runs npm ci without verifying the lockfile is in sync. Without automated updates, security patches for Next.js/React/Playwright land late. This issue adds Dependabot and a lockfile-drift guard.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Add .github/dependabot.yml configuring weekly npm ecosystem updates (and github-actions ecosystem) grouped sensibly to limit PR noise.
  • Add a CI step asserting package-lock.json is in sync (e.g. npm ci fails on drift, or an explicit npm install --package-lock-only diff check) so PRs cannot merge with a stale lockfile.
  • Keep existing lint/test jobs intact.
  • Document how to review and merge Dependabot PRs against the campaign workflow.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b security/dependencies-18-dependabot-lockfile
  • Implement changes
    • Write code in: create .github/dependabot.yml; update .github/workflows/ci.yml.
    • Write comprehensive tests in: validate via a CI run on the PR; add a documented local lockfile-drift command.
    • Add documentation: add a "Dependency updates" subsection to README.md.
    • Add comments in the workflow explaining the lockfile gate.
    • Validate security: ensure the config does not auto-merge without review.
  • Test and commit

Test and commit

  • Run npm run lint, npm test, npm run build, and npm ci locally.
  • Cover edge cases: clean lockfile passes; an intentionally drifted lockfile fails CI.
  • Include the CI run link/output.

Example commit message

ci: add dependabot config and lockfile-integrity check

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Fix the inaccurate README project structure, component props, and design tokens" labels: type:docs, area:readme, stack:nextjs, stack:react, stack:typescript, priority:medium, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Correct the README to match the actual codebase

Description

README.md is out of sync with the code in several places: the "Project structure" tree omits components/, app/copy/, and the test/Playwright setup; the CI/CD section lists "Lint" and "Build" but the workflow actually runs lint and npm test (accessibility), not build; the WalletStatus props are documented as a status prop it does not accept; ErrorBanner props are wrong (it has variant/title/description/details/actionLabel/onAction/previewLabel, not message); and the Design Tokens claim Geist is imported via @fontsource/geist when app/layout.js uses next/font/google. This issue makes the README accurate.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Update the project-structure tree to reflect real folders/files (components/, app/copy/en.js, tests/, jest.config.js, playwright.config.mjs, next.config.mjs).
  • Fix the CI/CD section to match .github/workflows/ci.yml (lint + accessibility tests).
  • Correct the WalletStatus and ErrorBanner prop docs against their real signatures.
  • Fix the Design Tokens section: Geist via next/font/google, and reconcile the listed color hexes with the actual slate/cyan palette.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b docs/readme-19-accuracy-fixes
  • Implement changes
    • Write code in: docs-only.
    • Write comprehensive tests in: not applicable; cross-check every claim against source.
    • Add documentation: update README.md.
    • Add a short "last verified against commit" note.
    • Validate accuracy by diffing each statement against the corresponding file.
  • Test and commit

Test and commit

  • Run npm run lint and npm run build to confirm nothing breaks.
  • Cover edge cases: every documented prop/path exists in the code.
  • Include a rendered preview of the corrected sections.

Example commit message

docs: correct readme structure, component props, and design tokens

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Add an accessibility statement documenting the app's a11y commitments" labels: type:docs, area:accessibility, stack:nextjs, stack:react, stack:typescript, priority:low, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Document the accessibility approach and known gaps

Description

The codebase invests heavily in accessibility β€” jest-axe wired in jest.setup.js, role="status"/aria-live regions in components/UploadZone.jsx, components/WalletStatus.jsx, and app/invest/page.js, and a CI step literally named "Test Accessibility" in .github/workflows/ci.yml β€” but there is no document explaining the standards targeted, the testing approach, or the known gaps (e.g. disabled filter buttons, motion handling). This issue writes an accessibility statement.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Create docs/accessibility.md stating the target standard (WCAG 2.1 AA), the keyboard/screen-reader patterns used, and how jest-axe is run in CI.
  • List known limitations and link to the relevant components/issues (disabled "Soon" filters, reduced-motion handling, focus styles).
  • Provide a contributor checklist for keeping new UI accessible (labels, landmarks, focus, live regions, contrast).
  • Link the statement from README.md.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b docs/accessibility-20-a11y-statement
  • Implement changes
    • Write code in: docs-only.
    • Write comprehensive tests in: not applicable; ensure referenced patterns exist in code.
    • Add documentation: create docs/accessibility.md and link from README.md.
    • Add a maintenance note on updating the statement when a11y issues close.
    • Validate accuracy against the current components and CI.
  • Test and commit

Test and commit

  • Run npm run lint and npm run build.
  • Cover edge cases: every referenced pattern and CI step is accurate.
  • Include a rendered preview of the new doc.

Example commit message

docs: add accessibility statement and contributor checklist

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Document environment variables and add the missing test/test:e2e to the README scripts" labels: type:docs, area:configuration, stack:nextjs, stack:react, stack:typescript, priority:low, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Document env vars and align the README command reference

Description

.env.local.example defines NEXT_PUBLIC_API_URL (and a commented NEXT_PUBLIC_STELLAR_NETWORK), but README.md only mentions NEXT_PUBLIC_API_URL in passing and its Development command table omits npm test even though package.json defines it (and CI runs it). This issue creates a clear environment-variable reference and aligns the documented scripts with the real ones.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Add an "Environment variables" table to README.md listing each var, whether it is required, its default, and what reads it (link to app/page.js for the API URL and WALLET_INTEGRATION_CONTRACT.md for the network).
  • Add npm test (Jest/jsdom) to the Development command table alongside test:e2e.
  • Ensure .env.local.example and the README stay consistent (same var names/defaults).
  • Note that NEXT_PUBLIC_* values are exposed to the client and must not hold secrets.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b docs/configuration-21-env-and-scripts
  • Implement changes
    • Write code in: docs-only; optionally clarify comments in .env.local.example.
    • Write comprehensive tests in: not applicable; verify documented defaults match the code fallbacks.
    • Add documentation: update README.md and .env.local.example.
    • Add a security note on NEXT_PUBLIC_ exposure.
    • Validate accuracy against package.json scripts and the env reads in code.
  • Test and commit

Test and commit

  • Run npm run lint, npm test, and npm run build.
  • Cover edge cases: documented defaults match app/page.js; every script in the table exists.
  • Include a rendered preview of the env section.

Example commit message

docs: document environment variables and align readme scripts

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Give the toast close button reliable Escape-to-dismiss and focus handling" labels: type:a11y, area:toast, stack:nextjs, stack:react, stack:typescript, priority:medium, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Improve keyboard accessibility of toast notifications

Description

Toasts in components/ToastProvider.jsx can only be dismissed by clicking "Close" or waiting for the timer; there is no keyboard shortcut to dismiss, and hovering pauses the timer but focusing (keyboard equivalent of hover) does not β€” so a keyboard user reading a toast can have it disappear mid-read. This issue adds keyboard parity: pause on focus, dismiss on Escape, and sensible focus return.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Pause/resume the auto-dismiss timer on focus/blur of the toast (mirroring the existing mouseenter/mouseleave pause/resume) so focusing a toast does not let it vanish.
  • Allow Escape to dismiss the focused toast.
  • Ensure the "Close" button and toast are reachable in a sensible tab order and that focus moves to a safe element after dismissal (no focus loss to body).
  • Keep the role="status"/aria-live="polite" region and all existing variant styling.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b a11y/toast-22-keyboard-dismiss
  • Implement changes
    • Write code in: update components/ToastProvider.jsx.
    • Write comprehensive tests in: create components/ToastProvider.keyboard.test.tsx using user-event and fake timers β€” assert focus pauses the timer, Escape dismisses, and focus return.
    • Add documentation: note the keyboard behaviour in README.md.
    • Add comments on the focus/blur pause parity.
    • Validate a11y: no jest-axe violations and keyboard-operable dismissal.
  • Test and commit

Test and commit

  • Run npm run lint, npm test, and npm run build.
  • Cover edge cases: focus-pause, Escape dismiss, and focus return after close.
  • Include the full npm test output.

Example commit message

fix: add escape-to-dismiss and focus pause to toast notifications

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Consolidate the duplicate WalletProvider and WalletContext into a single wallet module" labels: type:refactor, area:wallet, stack:nextjs, stack:react, stack:typescript, priority:high, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Unify the two competing wallet providers into one source of truth

Description

The repo ships two separate, incompatible wallet context implementations: components/WalletProvider.jsx exposes useWallet() returning { state, walletData, connect, disconnect } with localStorage rehydration, while components/WalletContext.jsx exposes useWallet() returning { walletState, walletData, error, connectWallet, disconnectWallet }. app/layout.js mounts WalletProvider from WalletContext, but consumers like app/invest/[id]/page.js destructure walletState/connectWallet. Having two providers with the same hook name is a latent footgun. This issue consolidates them into one canonical module.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Pick one canonical file (keep the persistence-capable WalletProvider.jsx implementation) and delete or re-export the other so only one useWallet()/WALLET_STATES exists.
  • Settle on a single hook shape and update every consumer (app/invest/[id]/page.js, app/layout.js, and any @/components/WalletContext import) to match.
  • Preserve localStorage rehydration, toast side effects, and WALLET_STATES.
  • Update all imports app-wide; no dangling references to the removed file.

Suggested execution

Test and commit

  • Run npm run lint, npm test, and npm run build.
  • Cover edge cases: every consumer compiles and the hook returns one stable shape.
  • Include the full npm test output and a before/after import inventory.

Example commit message

refactor: consolidate duplicate wallet providers into one module

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Fix WalletStatus to import Button and use the correct getStateConfig keys" labels: type:refactor, area:wallet, stack:nextjs, stack:react, stack:typescript, priority:high, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Repair the broken Button usage and config key mismatch in WalletStatus

Description

components/WalletStatus.jsx renders <Button variant={config.variant} loading={config.loading} ...> but (1) never imports Button from components/Button.jsx, and (2) getStateConfig returns buttonVariant/buttonText keys, not variant/loading β€” so config.variant and config.loading are always undefined. The component as written would throw at runtime. This issue wires the import and aligns the prop names so the wallet button renders the right variant and loading state.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Add import Button from './Button'; (and remove the leftover inline spinner SVG now that Button renders its own Spinner via loading).
  • Map getStateConfig's buttonVariant to the Button variant prop and derive loading from the connecting state.
  • Reconcile WalletStatus's local WALLET_STATES/mock with the canonical wallet provider once consolidated (coordinate with the provider-unification work).
  • Keep the sr-only role="status" live region and aria-describedby helper text intact.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b refactor/wallet-02-fix-button-config
  • Implement changes
    • Write code in: update components/WalletStatus.jsx.
    • Write comprehensive tests in: extend components/WalletStatus.test.tsx β€” assert each state renders the correct Button variant and loading spinner.
    • Add documentation: note the fix in README.md UI section.
    • Add JSDoc/comments on the config-to-prop mapping.
    • Validate a11y: connecting state sets aria-busy via Button.
  • Test and commit

Test and commit

  • Run npm run lint, npm test, and npm run build.
  • Cover edge cases: every WALLET_STATES variant and the connecting spinner.
  • Include the full npm test output.

Example commit message

fix: import button and align getstateconfig keys in walletstatus

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Repair the broken Invest page: undefined filter state and missing InvoiceSearch import" labels: type:refactor, area:invest, stack:nextjs, stack:react, stack:typescript, priority:high, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Fix the runtime references and dead code in the Invest marketplace page

Description

app/invest/page.js is currently broken in several ways: getInvoiceLoadAnnouncement references filterActive and filteredCount that are never defined; the JSX renders <InvoiceSearch /> without importing it; and the file both import { loadMockInvoices } from "./lib" and redefines a local loadMockInvoices plus a duplicate MOCK_INVOICES. This issue cleans up the merge artifacts so the page compiles and the search wiring actually works.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Remove the duplicate local MOCK_INVOICES and loadMockInvoices; rely solely on the imports from app/invest/lib.js.
  • Import InvoiceSearch from components/InvoiceSearch.jsx.
  • Fix getInvoiceLoadAnnouncement so it does not reference undefined filterActive/filteredCount; either pass the filter state in or compute the filtered count from searchQuery/debouncedQuery already in state.
  • Actually apply debouncedQuery to filter visibleInvoices by issuer (the state exists but is unused), and keep the polite status announcement accurate.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b refactor/invest-03-fix-broken-page
  • Implement changes
    • Write code in: update app/invest/page.js.
    • Write comprehensive tests in: extend app/invest/page.test.jsx β€” assert search filters the list and the announcement reports the filtered count.
    • Add documentation: note the search/announcement behaviour in README.md.
    • Add comments explaining the announcement signature.
    • Validate a11y: filtered count announced via the polite region.
  • Test and commit

Test and commit

  • Run npm run lint, npm test, and npm run build.
  • Cover edge cases: no matches, cleared query, and full list.
  • Include the full npm test output.

Example commit message

fix: repair undefined filter state and missing imports on invest page

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Fix the missing NavMenu import on the home page" labels: type:refactor, area:home, stack:nextjs, stack:react, stack:typescript, priority:high, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Import NavMenu so the home page renders without a ReferenceError

Description

app/page.js renders <NavMenu /> at the top of the layout but never imports it, so the home page throws a NavMenu is not defined ReferenceError at render. This issue adds the missing import and verifies the home page mounts the shared navigation.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Add import NavMenu from "../components/NavMenu"; (matching the path style already used by app/invoices/page.js).
  • Confirm NavMenu is the single header for the home page and there is no leftover duplicate header markup.
  • Keep the existing hero, CTA cards, and API-status panel intact.
  • Verify no hydration warnings from the lazy WalletStatusLazy inside NavMenu.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b refactor/home-04-fix-navmenu-import
  • Implement changes
    • Write code in: update app/page.js.
    • Write comprehensive tests in: create app/page.navmenu.test.tsx β€” assert the navigation landmark renders and links to Home/Invoices/Invest exist.
    • Add documentation: note the home page header composition in README.md.
    • Add a comment referencing the shared NavMenu.
    • Validate a11y: a single <nav>/<header> landmark with an accessible name.
  • Test and commit

Test and commit

  • Run npm run lint, npm test, and npm run build.
  • Cover edge cases: NavMenu mounts, links resolve.
  • Include the full npm test output.

Example commit message

fix: import navmenu on the home page

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Fix the Invoices page: missing Link import and replace the dead static Connect Wallet button" labels: type:refactor, area:invoices, stack:nextjs, stack:react, stack:typescript, priority:high, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Repair the Invoices page header and mount the shared NavMenu

Description

app/invoices/page.js imports NavMenu but never renders it, instead hand-rolling a header that uses <Link> without importing it (a Link is not defined ReferenceError) and a static "Connect Wallet" <button> that does nothing. This issue fixes the broken import and replaces the dead header with the shared NavMenu.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Replace the bespoke header with the imported <NavMenu /> so the page uses the same navigation and real wallet UI as the home page.
  • Remove the dead static "Connect Wallet" button (it uses copy.invoices.connectWallet and has no handler).
  • If the bespoke header is kept for any reason, add the missing import Link from "next/link";.
  • Preserve the page title/subtext and the <UploadZone /> mount.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b refactor/invoices-05-fix-header
  • Implement changes
    • Write code in: update app/invoices/page.js.
    • Write comprehensive tests in: extend app/invoices/page.test.tsx β€” assert NavMenu renders and no stray static Connect Wallet button remains.
    • Add documentation: note the unified header in README.md.
    • Add a comment referencing NavMenu reuse.
    • Validate a11y: one header landmark; back link is keyboard focusable.
  • Test and commit

Test and commit

  • Run npm run lint, npm test, and npm run build.
  • Cover edge cases: header renders, UploadZone mounts, no dead button.
  • Include the full npm test output.

Example commit message

fix: use navmenu and import link on the invoices page

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Fix ErrorBanner so it honors actionLabel and the error variant label" labels: type:refactor, area:error-banner, stack:nextjs, stack:react, stack:typescript, priority:high, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Make ErrorBanner render the passed actionLabel and correct variant label

Description

components/ErrorBanner.jsx accepts an actionLabel prop but the action button hard-codes the text "Retry", ignoring actionLabel entirely. Its variantLabel only special-cases "validation", so callers passing variant="error" (e.g. app/invest/page.js and app/invest/[id]/page.js) get the misleading label "Server error". This issue fixes both so the component renders what callers ask for.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Render {actionLabel} (not the literal "Retry") inside the action Button, keeping onAction wired.
  • Map variant to a correct label, including an "error" case, so the displayed label matches the caller's intent (or document the allowed variant set).
  • Keep previewLabel, role="alert"/aria-live="assertive", and conditional details behaviour unchanged.
  • Audit existing callers and adjust any that now show a different (correct) label.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b refactor/error-banner-06-actionlabel-variant
  • Implement changes
  • Test and commit

Test and commit

  • Run npm run lint, npm test, and npm run build.
  • Cover edge cases: custom actionLabel, no actionLabel, server/validation/error variants.
  • Include the full npm test output.

Example commit message

fix: render actionlabel and correct variant label in errorbanner

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Define the missing API_URL constant in UploadZone before the upload fetch" labels: type:refactor, area:upload, stack:nextjs, stack:react, stack:typescript, priority:high, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Fix the undefined API_URL reference in the UploadZone submit handler

Description

handleSubmit in components/UploadZone.jsx calls fetch(${API_URL}/invoices, ...), but API_URL is never imported or declared in the module, so submitting an invoice throws API_URL is not defined. Other files (e.g. app/page.js) read process.env.NEXT_PUBLIC_API_URL with a localhost fallback. This issue defines the base URL consistently so the upload request actually fires.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Derive the base URL from process.env.NEXT_PUBLIC_API_URL with the http://localhost:3001 fallback, matching the home page, ideally via a shared helper in lib/api.
  • Keep the multipart FormData body, the !res.ok error mapping, the tokenizingβ†’success transition, and existing status copy unchanged.
  • Ensure the e2e toast spec in tests/toast.spec.jsx still passes (mock the network where needed).
  • Add an AbortController so an unmount mid-upload does not set state on an unmounted component.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b refactor/upload-07-define-api-url
  • Implement changes
    • Write code in: update components/UploadZone.jsx; optionally add a shared base-URL helper in lib/api.
    • Write comprehensive tests in: extend components/UploadZone.test.jsx β€” mock fetch, assert the request URL and success/error transitions.
    • Add documentation: note the env var usage in README.md.
    • Add JSDoc/comments on the URL source.
    • Validate security: only the configured origin is used for the request.
  • Test and commit

Test and commit

  • Run npm run lint, npm test, npm run build, and npm run test:e2e.
  • Cover edge cases: success, non-2xx, network error, and unmount mid-upload.
  • Include the full npm test output and e2e confirmation.

Example commit message

fix: define api_url base in uploadzone submit handler

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Align the invoice-detail Fund button with the consolidated wallet hook API" labels: type:refactor, area:invest, stack:nextjs, stack:react, stack:typescript, priority:high, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Fix the wallet hook destructuring in the invoice detail page

Description

app/invest/[id]/page.js destructures { walletState, connectWallet } from useWallet(), but the canonical persistence-capable provider in components/WalletProvider.jsx returns { state, walletData, connect, disconnect }. Depending on which provider is mounted, walletState/connectWallet are undefined, so the "Fund this invoice" gating and the connect call silently break. This issue aligns the detail page with one hook shape.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Destructure the hook fields that actually exist on the canonical provider and update handleFund/isFundingDisabled accordingly.
  • Import WALLET_STATES from the same module that backs useWallet() (avoid mixing @/components/WalletContext and WalletProvider).
  • Keep the disabled-while-connecting and disconnected-prompts-connect behaviour and the educational disclaimer.
  • Coordinate with the provider-consolidation work so the import path is stable.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b refactor/invest-08-detail-wallet-hook
  • Implement changes
    • Write code in: update app/invest/[id]/page.js.
    • Write comprehensive tests in: extend app/invest/[id]/page.test.tsx β€” assert the Fund button prompts connect when disconnected and disables while connecting.
    • Add documentation: note the funding-intent flow in README.md.
    • Add comments on the wallet gating.
    • Validate a11y: the Fund button keeps a clear accessible name.
  • Test and commit

Test and commit

  • Run npm run lint, npm test, and npm run build.
  • Cover edge cases: disconnected, connecting, connected, and no-wallet states.
  • Include the full npm test output.

Example commit message

fix: align invoice-detail fund button with the wallet hook api

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Remove duplicated MOCK_INVOICES by sourcing all mock data from app/invest/lib.js" labels: type:refactor, area:invest, stack:nextjs, stack:react, stack:typescript, priority:medium, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Single-source the mock invoice fixtures

Description

The same MOCK_INVOICES array and a loadMockInvoices helper are defined twice β€” in app/invest/lib.js (the canonical, test-aware version reading window.__TEST_MOCK_INVOICES__) and again inline in app/invest/page.js. Duplicated fixtures drift apart over time and the detail-by-id lookup in lib.js already depends on the canonical array. This issue removes the inline copy so there is one source of truth.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Delete the inline MOCK_INVOICES/loadMockInvoices/DEV_DELAY from app/invest/page.js and use only the exports from app/invest/lib.js.
  • Confirm getInvoiceById in lib.js resolves the detail route against the same array.
  • No behaviour change to the rendered marketplace or the test hook window.__TEST_MOCK_INVOICES__.
  • Add a short comment marking lib.js as the single mock-data source until the API client lands.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b refactor/invest-09-dedupe-mock-data
  • Implement changes
  • Test and commit

Test and commit

  • Run npm run lint, npm test, and npm run build.
  • Cover edge cases: list render, detail lookup, and the test hook override.
  • Include the full npm test output.

Example commit message

refactor: single-source mock invoices from app/invest/lib.js

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Migrate WalletStatus and remaining buttons to the shared Button focus-visible styles" labels: type:refactor, area:components, stack:nextjs, stack:react, stack:typescript, priority:medium, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Finish the shared-Button migration and remove leftover focus:ring styles

Description

A shared components/Button.jsx exists with a unified focus-visible:outline treatment, yet several buttons still use the older divergent focus:ring pattern: the home API-status button in app/page.js, the Fund button in app/invest/[id]/page.js, the disabled filter buttons in app/invest/page.js, and the inline getButtonStyles in components/WalletStatus.jsx. This issue completes the migration so focus styling is consistent everywhere.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Replace the remaining hand-styled buttons with <Button> (or its variants), deleting getButtonStyles from WalletStatus.
  • Ensure every interactive button uses the cyan focus-visible:outline from Button rather than focus:ring.
  • No visual regression beyond the intentional focus-style unification; preserve disabled/loading semantics.
  • Keep the disabled filter buttons' "coming soon" affordance (coordinate with any a11y work on those controls).

Suggested execution

Test and commit

  • Run npm run lint, npm test, and npm run build.
  • Cover edge cases: each variant, disabled, loading, and focus visibility.
  • Include the full npm test output and a before/after note.

Example commit message

refactor: migrate remaining buttons to the shared button component

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward. ++++++

type: Feature title: "Add an aria-label and screen-reader title to the UploadZone Spinner SVG" labels: type:a11y, area:upload, stack:nextjs, stack:react, stack:typescript, priority:low, MAYBE REWARDED, GRANTFOX OSS, OFFICIAL CAMPAIGN assignees: ''

Give loading spinners an accessible name

Description

The Spinner components in components/UploadZone.jsx, components/Spinner.jsx, and the inline SVG fallback are marked aria-hidden="true". That is fine when wrapped in a role="status" text region, but the submit button renders a bare <Spinner /> next to text with no status text of its own, so assistive tech announces only the static button label during processing. This issue ensures the loading state is consistently perceivable.

Requirements and context

  • Repository scope: Liquifact/Liquifact-frontend only.
  • Confirm every spinner usage is paired with an aria-busy host or a role="status" text node; where a spinner stands alone, add an accessible loading label.
  • Keep decorative spinners aria-hidden only when their loading meaning is conveyed elsewhere.
  • Do not introduce double announcements (avoid both aria-busy and a redundant live region announcing simultaneously).
  • Respect prefers-reduced-motion already handled globally.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b a11y/upload-11-spinner-label
  • Implement changes
  • Test and commit

Test and commit

  • Run npm run lint, npm test, and npm run build.
  • Cover edge cases: standalone spinner and spinner-in-status-region.
  • Include the full npm test output.

Example commit message

fix: give loading spinners an accessible name

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • πŸ’¬ Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project β€” if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward.