Skip to content

feat: refresh Valhalla member archive - #5

Merged
ECWireless merged 2 commits into
mainfrom
feat/raidguild-brand-refresh
Aug 2, 2026
Merged

feat: refresh Valhalla member archive#5
ECWireless merged 2 commits into
mainfrom
feat/raidguild-brand-refresh

Conversation

@ECWireless

@ECWireless ECWireless commented Aug 2, 2026

Copy link
Copy Markdown
Member

This pull request introduces several significant improvements to the codebase, focusing on configuration flexibility, UI modernization, and utility enhancements. The most important changes include making the S3 bucket configurable via environment variables, redesigning the site header and wallet controls, updating font and theme usage, and adding a fuzzy search utility. Additionally, documentation has been improved for clarity and safety in the PR review workflow.

Configuration and Environment Variables

  • Added S3_BUCKET and DEV_ALLOWED_ORIGINS to environment variables, and implemented a getS3Bucket() function to retrieve the S3 bucket name from the environment, replacing hardcoded values throughout the codebase. This makes S3 integration more flexible and production-ready. [1] [2] [3] [4] [5] [6] [7]

UI and Theming

  • Replaced Chakra UI-based header and footer with a new custom header (Header.jsx) and wallet control (WalletControl.tsx), using Next.js components and improved branding. Footer was removed. [1] [2] [3]
  • Introduced custom fonts (fonts.ts) and updated the site to use these fonts consistently. [1] [2]
  • Customized the RainbowKit theme to match RaidGuild branding and applied new CSS class structure for layout. [1] [2]

Utilities

  • Added a new fuzzyScore function in utils/fuzzy.ts for improved search and matching capabilities.

Documentation

  • Updated the PR review workflow documentation for clarity, emphasizing safety, clarity of replies, and improved step descriptions.

These changes modernize the user interface, enhance configuration management, and improve both developer and user experience.

Summary by CodeRabbit

  • New Features
    • Added a redesigned responsive archive experience with fuzzy channel search, filtered file listings, loading states, retry actions, and clearer access/error messaging.
    • Added wallet connection controls with network-switch guidance and improved connection handling.
    • Added new branding, typography, responsive layouts, animations, and accessibility improvements.
    • File opening now validates signatures and excludes directory entries.
  • Bug Fixes
    • S3 storage and development-origin settings are now configurable and validated.
  • Documentation
    • Expanded environment-variable and workflow documentation.

Copilot AI review requested due to automatic review settings August 2, 2026 02:40
@vercel

vercel Bot commented Aug 2, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
the-valhalla Ready Ready Preview Aug 2, 2026 3:31am

Request Review

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@ECWireless, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 9 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6562203b-4362-48bf-a22e-e4fd3a6caf3a

📥 Commits

Reviewing files that changed from the base of the PR and between 2fb1140 and bd5e15e.

📒 Files selected for processing (7)
  • app/globals.css
  • app/page.tsx
  • app/shared/WalletControl.tsx
  • app/utils/fuzzy.ts
  • docs/pr-review-workflow.md
  • docs/session-workflow.md
  • sample.env
📝 Walkthrough

Walkthrough

The PR replaces the archive UI with custom responsive components, adds wallet controls and fuzzy search, externalizes S3 and development-origin configuration, and expands review and session workflow documentation.

Changes

Archive interface

Layer / File(s) Summary
Layout, fonts, and visual system
app/fonts.ts, app/layout.tsx, app/globals.css
Adds custom fonts, RainbowKit styling, site containers, responsive layouts, archive styles, accessibility rules, and reduced-motion behavior.
Header and wallet interaction
app/shared/Header.jsx, app/shared/WalletControl.tsx
Adds semantic branding and wallet controls for connection, unsupported-chain, and connected states.
Archive access, search, and file opening
app/page.tsx, app/utils/fuzzy.ts
Adds membership states, signing flow, fuzzy channel search, status announcements, retry actions, filtered file cards, and signed file opening.

Runtime configuration

Layer / File(s) Summary
Environment configuration and validation
next.config.js, sample.env, AGENTS.md
Configures cleaned development origins and documents DEV_ALLOWED_ORIGINS and S3_BUCKET.
Validated S3 bucket integration
app/config.ts, app/api/channel/route.ts, app/api/files/route.ts
Validates S3_BUCKET and uses it for S3 listing and signed URL requests.

Review and session workflows

Layer / File(s) Summary
Pull request review workflow
docs/pr-review-workflow.md
Defines review-thread tracking, evidence-based validation, sensitive-data restrictions, and approval-gated replies.
Session planning and closeout
docs/session-workflow.md
Defines session planning, implementation safeguards, verification, reviewer requirements, commit gates, and closeout checks.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant WalletControl
  participant Homepage
  participant FilesRoute
  participant S3
  WalletControl->>Homepage: report wallet state
  Homepage->>FilesRoute: request authorized files
  FilesRoute->>S3: list archive objects
  S3-->>FilesRoute: return file keys
  FilesRoute-->>Homepage: return files
  Homepage->>FilesRoute: request signed file URL
  FilesRoute->>S3: create signed URL
  S3-->>FilesRoute: return signed URL
Loading

Possibly related PRs

Suggested reviewers: copilot

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the primary archive refresh covered by the configuration, UI, branding, and utility changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/raidguild-brand-refresh

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR modernizes the Valhalla member archive experience by introducing a redesigned UI (custom header, wallet controls, and CSS-driven layout), adding fuzzy search over archive entries, and improving configuration flexibility by making the S3 bucket and dev origins configurable via environment variables.

Changes:

  • Added S3_BUCKET and DEV_ALLOWED_ORIGINS configuration (including getS3Bucket()), replacing the hardcoded S3 bucket in API routes.
  • Reworked the UI layout (new Header, new WalletControl, new CSS theme/fonts, and updated app/page.tsx gating + archive browsing UX).
  • Added fuzzyScore() utility and wired it into channel/file searching.

Reviewed changes

Copilot reviewed 15 out of 26 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
sample.env Documents new environment variables for dev origins and S3 bucket configuration.
next.config.js Reads DEV_ALLOWED_ORIGINS and exposes allowedDevOrigins for dev server behavior.
AGENTS.md Updates the repo’s known environment-variable list to include DEV_ALLOWED_ORIGINS and S3_BUCKET.
app/config.ts Adds getS3Bucket() helper to enforce configured S3 bucket at runtime.
app/api/files/route.ts Uses getS3Bucket() when listing S3 objects for members.
app/api/channel/route.ts Uses getS3Bucket() when creating signed URLs for member file access.
app/utils/fuzzy.ts Adds a fuzzy scoring helper for search.
app/page.tsx Rebuilds the member gating and archive UI; adds fuzzy search and richer loading/error states.
app/shared/WalletControl.tsx Introduces a custom RainbowKit wallet control used by the header and hero CTA.
app/shared/Header.jsx Replaces Chakra-based header with a new branded header using Next components.
app/shared/Footer.jsx Removes the old Chakra-based footer.
app/layout.tsx Switches to global CSS + custom fonts and applies a customized RainbowKit theme.
app/fonts.ts Adds font setup (local + Google fonts) and CSS variables.
app/globals.css Introduces the new site-wide styling, layout, and component classes.
app/icon.svg Adds the app icon asset.
public/brand/full-m800.svg Adds new full brand logo asset.
public/brand/symbol-m500.svg Adds new symbol brand logo asset.
public/brand/swords.svg Adds new “swords” brand icon asset.
public/brand/crystal.svg Adds new “crystal” brand icon asset (used via CSS masking).
docs/session-workflow.md Updates internal workflow guidance for sessions, verification, and review gates.
docs/pr-review-workflow.md Refines PR review workflow documentation for safety and clarity.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread app/utils/fuzzy.ts Outdated
Comment thread app/shared/WalletControl.tsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (7)
app/utils/fuzzy.ts (2)

4-5: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Use toLowerCase() for locale-independent matching.

toLocaleLowerCase() without an explicit locale uses the runtime locale. In a Turkish locale, "I" lowercases to "ı" and the match against "i" fails. Search results then differ per user for the same data. Use toLowerCase(), or pass a fixed locale.

♻️ Proposed change
-  const needle = query.trim().toLocaleLowerCase();
-  const haystack = candidate.toLocaleLowerCase();
+  const needle = query.trim().toLowerCase();
+  const haystack = candidate.toLowerCase();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/utils/fuzzy.ts` around lines 4 - 5, Update the normalization expressions
for needle and haystack to use locale-independent toLowerCase() instead of
toLocaleLowerCase(), preserving the existing trim behavior for query and
case-insensitive matching.

3-3: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Add an explicit return type.

fuzzyScore returns number | null. The caller in app/page.tsx line 231 relies on the null case. An explicit annotation documents the contract and prevents an accidental widening.

♻️ Proposed change
-export function fuzzyScore(query: string, candidate: string) {
+export function fuzzyScore(query: string, candidate: string): number | null {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/utils/fuzzy.ts` at line 3, Update the fuzzyScore function signature to
explicitly return number | null, preserving its existing behavior and
documenting the null case relied on by its caller.
app/page.tsx (1)

28-29: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

The static analysis secret findings are false positives.

Line 28 holds a public ERC-20 contract address on Gnosis, not a credential. No change is needed. Consider a short comment above the constant to name the token, so future scans and readers have context.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/page.tsx` around lines 28 - 29, Keep SHARES_TOKEN_ADDRESS unchanged
because it is a public contract address, not a credential; add a brief comment
immediately above it identifying the ERC-20 token and its Gnosis-network
context.

Source: Linters/SAST tools

app/globals.css (1)

44-45: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider 100dvh for the full-height containers.

100vh on mobile browsers includes the collapsing address bar. The shell then overflows the visible viewport. min-height: 100dvh matches the visible area.

♻️ Proposed change
 .site-shell {
   position: relative;
   display: flex;
-  min-height: 100vh;
+  min-height: 100dvh;
   flex-direction: column;

Also applies to: 97-101

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/globals.css` around lines 44 - 45, Update the body min-height declaration
to use 100dvh instead of 100vh, and apply the same viewport-unit change to the
related full-height container declarations in this stylesheet.
app/shared/Header.jsx (2)

8-10: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Convert Header.jsx to TypeScript.

The rest of the new UI uses .tsx, for example app/shared/WalletControl.tsx. A .jsx file gets no type checking against the WalletControl props contract. Rename the file to app/shared/Header.tsx.

As per coding guidelines: "app/**/*.{ts,tsx}: Follow the existing Next.js 16 App Router, React 19, TypeScript, and Chakra UI patterns."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/shared/Header.jsx` around lines 8 - 10, Rename the Header component file
from Header.jsx to Header.tsx and preserve its existing implementation while
applying the project’s TypeScript and React patterns. Update any imports or
references to use the renamed module so Header participates in type checking
alongside WalletControl.

Source: Coding guidelines


12-29: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Remove priority from the logo that is hidden at the current breakpoint.

Both logos render at every breakpoint. CSS hides one with display: none in app/globals.css lines 159-163 and 788-795. priority adds a preload link for both files. The browser then fetches an image that is never shown. Keep priority on the full logo only, or drop it from both because SVG logos are small.

♻️ Proposed change
         <Image
           className="brand-logo-symbol"
           src="/brand/symbol-m500.svg"
           alt="RaidGuild"
           width={40}
           height={38}
-          priority
           unoptimized
         />
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/shared/Header.jsx` around lines 12 - 29, Remove the priority prop from
the breakpoint-hidden logo in Header’s paired Image elements, while retaining it
only on the full logo (or remove it from both if preferred). Ensure the hidden
symbol logo no longer generates a preload request.
app/shared/WalletControl.tsx (1)

41-48: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Guard the deferred connect effect against repeated calls.

openConnectModal comes from ConnectButton.Custom and gets a new identity on each render. The effect depends on it. While connectRequested stays true, any re-render re-runs the effect and calls openConnectModal() again, and the cleanup cancels the pending reset timeout. Clear the request flag before you open the modal instead of using a timeout.

♻️ Proposed change
   useEffect(() => {
     if (!ready || !connectRequested) return;
 
+    setConnectRequested(false);
     openConnectModal();
-    const resetRequest = window.setTimeout(() => setConnectRequested(false), 0);
-
-    return () => window.clearTimeout(resetRequest);
   }, [connectRequested, openConnectModal, ready]);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/shared/WalletControl.tsx` around lines 41 - 48, Update the useEffect
handling connectRequested to clear the request flag synchronously before calling
openConnectModal, removing the deferred setConnectRequested timeout and its
cleanup. Keep the existing ready and connectRequested guards, and retain the
dependency on openConnectModal while ensuring rerenders cannot reopen the modal
for the same request.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/globals.css`:
- Line 59: Update the affected declarations in the stylesheet to satisfy
Stylelint: change text-rendering to the lowercase optimizelegibility value,
replace the deprecated clip declaration with clip-path: inset(50%), and use the
lowercase currentcolor value at the referenced color declarations.

In `@app/page.tsx`:
- Around line 243-244: Update the isCheckingAccess calculation so
isFilesFetching does not trigger the loading gate that replaces the archive;
scope access loading to the initial connection/share checks while preserving the
existing behavior for isConnecting and isSharesLoading.
- Around line 396-436: Add an explicit pre-archive guard in the component’s
final render flow, after the existing wallet and signature checks, so the
archive is rendered only when the membership lookup has completed and the user
is confirmed as a member with a successful signature. For unresolved or
non-member states, route to the appropriate existing connect/check-in gate
instead of falling through to the “Guild archive” section.

In `@app/utils/fuzzy.ts`:
- Around line 18-38: Update the fuzzy matching loop around `searchFrom` and
`previousMatch` to account for each matched code point’s UTF-16 length: advance
`searchFrom` by `character.length` rather than one unit, and update the
adjacency check to compare the current match index with the end of the previous
matched character. Preserve existing scoring behavior for word separators and
gaps.

In `@docs/pr-review-workflow.md`:
- Around line 41-61: Update the staging/merge-readiness flow in steps 6–7 to
require the independent-review gate from docs/session-workflow.md after PR-sized
implementation and automated verification, before staging or declaring the work
ready to merge; make this conditional for PR-sized fixes or explicitly require
following the companion workflow, while preserving the existing user-approval
requirement.

In `@docs/session-workflow.md`:
- Around line 11-14: Update docs/session-workflow.md lines 11-14, 66-69, and
172-173 to define and consistently use the candidate’s intended parent or merge
base as the review baseline; retain main only when it is the intended parent,
and require the complete diff to be reviewed against that same baseline.

In `@sample.env`:
- Around line 10-11: Update the S3_BUCKET placeholder in the sample environment
configuration to use hyphens instead of underscores, ensuring the copied value
conforms to general-purpose S3 bucket naming rules while preserving the existing
placeholder intent.

---

Nitpick comments:
In `@app/globals.css`:
- Around line 44-45: Update the body min-height declaration to use 100dvh
instead of 100vh, and apply the same viewport-unit change to the related
full-height container declarations in this stylesheet.

In `@app/page.tsx`:
- Around line 28-29: Keep SHARES_TOKEN_ADDRESS unchanged because it is a public
contract address, not a credential; add a brief comment immediately above it
identifying the ERC-20 token and its Gnosis-network context.

In `@app/shared/Header.jsx`:
- Around line 8-10: Rename the Header component file from Header.jsx to
Header.tsx and preserve its existing implementation while applying the project’s
TypeScript and React patterns. Update any imports or references to use the
renamed module so Header participates in type checking alongside WalletControl.
- Around line 12-29: Remove the priority prop from the breakpoint-hidden logo in
Header’s paired Image elements, while retaining it only on the full logo (or
remove it from both if preferred). Ensure the hidden symbol logo no longer
generates a preload request.

In `@app/shared/WalletControl.tsx`:
- Around line 41-48: Update the useEffect handling connectRequested to clear the
request flag synchronously before calling openConnectModal, removing the
deferred setConnectRequested timeout and its cleanup. Keep the existing ready
and connectRequested guards, and retain the dependency on openConnectModal while
ensuring rerenders cannot reopen the modal for the same request.

In `@app/utils/fuzzy.ts`:
- Around line 4-5: Update the normalization expressions for needle and haystack
to use locale-independent toLowerCase() instead of toLocaleLowerCase(),
preserving the existing trim behavior for query and case-insensitive matching.
- Line 3: Update the fuzzyScore function signature to explicitly return number |
null, preserving its existing behavior and documenting the null case relied on
by its caller.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ae1e4dba-ead9-4dc5-9123-d8a627b827e9

📥 Commits

Reviewing files that changed from the base of the PR and between dfceeae and 2fb1140.

⛔ Files ignored due to path filters (9)
  • app/favicon.ico is excluded by !**/*.ico
  • app/icon.svg is excluded by !**/*.svg
  • public/brand/crystal.svg is excluded by !**/*.svg
  • public/brand/full-m800.svg is excluded by !**/*.svg
  • public/brand/swords.svg is excluded by !**/*.svg
  • public/brand/symbol-m500.svg is excluded by !**/*.svg
  • public/fonts/MAZIUSREVIEW20.09-Regular.woff is excluded by !**/*.woff
  • public/fonts/MaziusDisplay-Bold.otf is excluded by !**/*.otf
  • public/fonts/MaziusDisplay-Extraitalic.otf is excluded by !**/*.otf
📒 Files selected for processing (17)
  • AGENTS.md
  • app/api/channel/route.ts
  • app/api/files/route.ts
  • app/config.ts
  • app/fonts.ts
  • app/globals.css
  • app/layout.tsx
  • app/page.tsx
  • app/shared/Footer.jsx
  • app/shared/Header.jsx
  • app/shared/WalletControl.tsx
  • app/utils/fuzzy.ts
  • docs/pr-review-workflow.md
  • docs/session-workflow.md
  • next.config.js
  • public/brand/portal-arch-c.webp
  • sample.env
💤 Files with no reviewable changes (1)
  • app/shared/Footer.jsx
👮 Files not reviewed due to content moderation or server errors (1)
  • public/brand/portal-arch-c.webp

Comment thread app/globals.css Outdated
Comment thread app/page.tsx Outdated
Comment thread app/page.tsx
Comment thread app/utils/fuzzy.ts Outdated
Comment thread docs/pr-review-workflow.md
Comment thread docs/session-workflow.md
Comment thread sample.env Outdated
@ECWireless
ECWireless merged commit 6ddb876 into main Aug 2, 2026
3 checks passed
@ECWireless
ECWireless deleted the feat/raidguild-brand-refresh branch August 2, 2026 03:35
@coderabbitai coderabbitai Bot mentioned this pull request Aug 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants