Skip to content

Projects Page Search UX Improvements#1133

Open
matmanna wants to merge 15 commits into
hackclub:mainfrom
matmanna:projects-page
Open

Projects Page Search UX Improvements#1133
matmanna wants to merge 15 commits into
hackclub:mainfrom
matmanna:projects-page

Conversation

@matmanna
Copy link
Copy Markdown
Member

@matmanna matmanna commented Apr 5, 2026

Some of the Hackatime improvements I've wanted for a while :D

image image image

@matmanna matmanna marked this pull request as ready for review May 2, 2026 20:28
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 2, 2026

Greptile Summary

This PR adds several UX improvements to the Projects page: a client-side text search box, an archival-status selector (active/archived), a sort dropdown, and a grid/list view toggle. The broken-name warning is also now surfaced in list view as a compact badge.

  • Client-side filteredAndSortedProjects derived state powers search and sort without additional server requests; the archival-status change still triggers a full page reload via window.location.href to stay consistent with the existing URL-driven pattern.
  • The complete project action-button set (homepage, GitHub, edit, archive/restore) is duplicated across the list-mode header block and the grid-mode action bar, roughly doubling the template lines needed to maintain those controls.

Confidence Score: 5/5

Safe to merge; all changes are client-side rendering improvements with no impact on data persistence or security boundaries.

The change is entirely within a single Svelte component and touches only how project data is displayed and filtered. The derived filtering and sorting operate on already-loaded data, the archival status redirects use the existing URL-building helpers, and no new server endpoints are introduced.

app/javascript/pages/Projects/Index.svelte — specifically the duplicated action-button blocks for list vs. grid view, which will need to stay in sync manually until extracted into a component.

Important Files Changed

Filename Overview
app/javascript/pages/Projects/Index.svelte Adds client-side search, sort, archival-status filter, and grid/list view toggle to the Projects page. Action buttons are duplicated across list and grid render paths (~60 lines), and min-h-36 is applied in list mode making rows unnecessarily tall; both are style-level issues.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Projects page loads] --> B{projects_data deferred?}
    B -- loading --> C[Skeleton cards]
    B -- ready --> D{projects_data.projects.length == 0?}
    D -- yes --> E[Server empty state message]
    D -- no --> F[filteredAndSortedProjects derived]
    F --> G{User inputs}
    G -- searchQuery change --> F
    G -- sortBy change --> F
    G -- archivalStatus change --> H[changeArchivedStatus]
    H --> I[window.location.href = new URL]
    I --> A
    F --> J{filteredAndSortedProjects.length == 0?}
    J -- yes --> K[No search results message]
    J -- no --> L{viewMode}
    L -- grid --> M[Auto-fill grid of cards]
    L -- list --> N[Compact list rows]
Loading
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
app/javascript/pages/Projects/Index.svelte:603-650
**Action buttons duplicated across list and grid modes**

The complete set of project action buttons — homepage link, GitHub link, edit/link-repo button, and archive/restore button — is rendered twice: once in the list-mode header block (here) and again in the grid-mode action bar (~lines 683–735). That's ~60 lines of near-identical markup that diverges over time. The repository guidelines suggest extracting duplicated markup into a shared component; a small `ProjectActions.svelte` accepting `project`, `show_archived`, and `viewMode` as props would serve both modes without the duplication.

### Issue 2 of 2
app/javascript/pages/Projects/Index.svelte:564-570
The `min-h-36` class (144 px) is applied unconditionally in both grid and list modes. In list mode this makes every row at least 144 px tall, producing a sparse list that looks more like a short grid than a compact view. List rows need far less vertical space — removing the minimum height in list mode lets the content dictate the row height naturally.

```suggestion
                <article
                  class="group relative flex w-full {viewMode === 'list'
                    ? 'flex-row items-start sm:items-center sm:justify-between'
                    : 'min-h-36'} overflow-hidden rounded-2xl {projectHref
                    ? 'cursor-pointer'
                    : ''}"
                >
```

Reviews (3): Last reviewed commit: "chore: format" | Re-trigger Greptile

Comment thread app/javascript/pages/Projects/Index.svelte Outdated
Comment thread app/javascript/pages/Projects/Index.svelte Outdated
Comment thread app/javascript/pages/Projects/Index.svelte Outdated
@matmanna matmanna marked this pull request as draft May 8, 2026 11:51
@matmanna matmanna marked this pull request as ready for review May 21, 2026 03:04
@matmanna
Copy link
Copy Markdown
Member Author

@greptileai review

Copy link
Copy Markdown
Member

@skyfallwastaken skyfallwastaken left a comment

Choose a reason for hiding this comment

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

Image

This bit feels kinda clunky iykwim?

What I would suggest is to make the archival picker a two-icon switch like the view one, then switching the interval picker from the full width to a calendar icon button (which'd probably need a few changes to IntervalSelect.svelte)

@matmanna
Copy link
Copy Markdown
Member Author

matmanna commented May 31, 2026

What I would suggest is to make the archival picker a two-icon switch like the view one,

one of the reasons i elected a dropdown over the old archival toggle was in case project labels/tagging is eventually reimplemented from hackatime v1 (my thought was "archived" would then basically be a label from a frontend perspective and it might be elegant to have it share a dropdown). i will definitely change this back for now though! 👍

then switching the interval picker from the full width to a calendar icon button (which'd probably need a few changes to IntervalSelect.svelte)

wouldn't having it be an icon button hide the 'currently selected' state from being visible from search results. it feels a bit more jank to have the user have to open a menu just to see what date filter is applied... i'm not 100% opposed to doing so, but can also see this making triage using the filter more difficult in #hackatime-help

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