fix: improve the catalogue interface - #130
Merged
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
`pnpm dev` ran against whatever `.env.local` held, which is the hosted project carrying the pre-redesign schema, so the obvious command failed with PGRST205 while the working one, `dev:local`, had to be learned. The default is now the local stack for dev, build and start alike, and the hosted credentials are read only by the explicit `:prod` variants. Build and start gained the same treatment because a production build against the local stack had no command at all: the publishable key is baked in at build time, so a build reading hosted values cannot be served against local Postgres. `preview:local` does both steps in one. The Supabase status parsing that dev-preview owned moves to supabase-environment.mjs, shared by the three preview entry points, and each of them now spawns the Next binary directly rather than recursing through a pnpm script that would re-read the ambient environment.
The sign-in form only existed as a submit handler, so a password typed before hydration finished posted nowhere and the page appeared to swallow it. The form now posts to /auth/password, which signs in on the server and redirects, and the client handler still takes over once it is live. The route only accepts same-origin posts, takes a single value for each field, and sends a failed attempt back to /login?error=invalid-login rather than naming which half was wrong. Both handler paths reach the same message, so the server-rendered failure and the client one read alike. /auth/password and /auth/sign-in join the handler paths that safeInternalRedirect refuses as a destination, so a next= parameter cannot aim the redirect back into the sign-in machinery.
A failure under /admin dropped the operator onto the bare error layout with a "Back to home" button aimed at the student dashboard, so recovering from a broken admin page meant navigating back in from the outside. The error boundary now recognises an admin path, renders inside AppShell, and points home at /admin/dashboard. Catalogue activity gets its own boundary as well, so a failure there keeps its breadcrumbs and tabs and says which screen could not load rather than falling back to the generic page error.
"Operations" was a section of one item sitting beside Catalogue while describing the same records, so an administrator had two places to look for catalogue work. It becomes "Activity" inside Catalogue, and the breadcrumbs drop the operations segment they could not link anywhere. The catalogue links carry the year the operator is already reading, so moving between Courses and Programmes keeps the year rather than bouncing back to the profile default, while the active-state match still uses the yearless path so every year under a section highlights it. Discovery checks gained the filter bar the other catalogue tables have: listing, year, status and completeness, with an empty state that offers to clear them. The page titles students see now match their navigation labels: Academic history, Calendar, Profile.
Opening a catalogue record created its draft, so every record anyone had looked at reported itself as a draft, and discarding one brought it back on the next render. A draft is now created by the first change worth keeping: the editor reads the publication, or an empty record, and saving content that matches it writes nothing. A draft is also only reported while it still says something the record did not, so restoring the published version or editing a draft back by hand returns the record to Published or Not published. The directory rows carry the draft revision, so publishing, discarding and unpublishing can be done from the row menu against the draft the list actually read. The rows the old behaviour left behind are deleted by migration: a draft at revision 0 that was never restored is byte-identical to its base, so nothing authored is lost.
A record with no draft opened as a page of live inputs, so the published version could be changed by a stray keystroke and there was nothing to say whether it was being read or written. The fields are now read until Edit is pressed, and Edit only unlocks them - the draft still arrives with the first change worth keeping. The session behind those fields moved into a provider so the toolbar that reports and commits it can lead the page instead of sitting above the fields, where it was below the title it described. The toolbar now names the record's state in words - Published, Draft, Not published - and what that means for students, and Cancel backs out of editing while nothing has been saved. The header drops "Listed by ANU": it was true of nearly every record and so said nothing, while the delisting warning it shared a line with is worth keeping. View on ANU moves up beside the title it links to.
Popovers shared the page background, so in dark the border and shadow that carry elevation in light were both nearly invisible and a menu read as a hole rather than a card. The popover surface is now the lighter one, and the menu's own hover tone is mixed from the foreground rather than --accent, which was mixed against the page and vanished against it. The directory drops the columns nobody read and gives identity the spare width, a running sync reports itself through a task toast whose icon holds the first line, and a loading toast keeps the room a close button would have taken.
One sync was a single scroll, so a failing stage sat below several screens of contract versions and the artefact viewer never had the page to itself. The record now divides into Overview, Stages, Extractions and Artefacts, with the failure count on the Stages tab and sections that hold nothing disabled rather than shown empty. The status and any error stay above the tabs, because they are true of the sync whichever part of it is being read. Facts sit in cards and the content keeps a reading measure: highlighted source and long fact grids became unreadable when a wide screen stretched them edge to edge, so tables and artefacts scroll inside that measure instead of widening past it.
Reading a sparse record showed every field the form could hold, so a course with six facts filled a screen with labels above em dashes and the six facts were lost in it. A read now carries only what was recorded: empty fields, empty collections and rules nobody wrote are left out, and a section with nothing in it says so once instead of listing its blanks. Labels drop to muted and values take the foreground, because the value is the content and it was the fainter of the two.
A sync and a listing check answer the same kinds of question - what ran, against what, and what came back - but each had invented its own furniture, so the discovery check floated facts on the page while the sync put them in cards. Both now draw on one set of layout pieces, and the check's title names the kind properly rather than printing the database value.
Everything on the Changes tab is the output of a sync, and every source entry in the changelog was written by one, but neither said which. Both now name the check behind them and link to its diagnostics, for readers who hold the catalogue operations permission. The admin overview drew its import model as loose page furniture beside a card, so the two tiles in one grid did not look like they belonged to each other. It is a card now, with the same measure, padding and icon treatment as the tile it sits next to.
--accent is mixed against the page ground, so in dark it resolves to oklch(~0.204) while the popover surface a menu opens on is oklch(0.205): any highlight drawn with it disappeared on exactly the surface it was needed on. Nova's translucent menu preset already avoids this for dropdowns and selects, but three places did not - the notifications panel, the import model picker, which overrode the preset with an --accent utility of its own, and command items, which the preset does not cover. All three now mix from the foreground, which reads on whatever ground it is laid over, in both themes. Measured in a browser rather than reasoned about: the hovered item background is now a foreground mix at 8-10% on both.
A source page is the record of one exact set of bytes, and `catalogue_source_pages_reject_mutation` raises on every update. The upsert's `do update set fetched_at` therefore failed the moment ANU returned a listing whose bytes had not changed. Refetching an unchanged listing now reuses the page already recorded; when the refresh happened is on the discovery check that asked for it.
`toast.loading` withholds sonner's close button, so work that carries on server-side left a toast nobody could put away. The running toast is now an ordinary one with a spinner for an icon, which gets the close button back, and the close button overlaps the title alone so descriptions and the progress bar keep the full width. The bar also caught up to reported progress by easing, which only ever approaches a value and stranded it short of the phase it had been told about. It now closes the reported distance briskly, then drifts through the rest of the phase. A task that reports nothing for longer than either endpoint's cap is assumed to have lost whatever was driving it and says so.
`SectionTabs` took an icon as a rendered node, so every caller sized it itself and a bar of tabs came out uneven. It takes the component now and sizes it once. The route map gains the catalogue activity sections and the four record sections, so a tab and the breadcrumb above it read from one list; the breadcrumb names its trailing icon by key rather than by component, which is what lets a server page ask for one. Sync diagnostics also gains what it was missing to be read by someone who has not written the pipeline: each artefact tab explains what that artefact is, and the viewer scrolls inside a window rather than setting the page's length.
A draft appearing on the first saved change meant backing out of the editor was sometimes discarding a draft and sometimes nothing at all, and a record someone had started work on stopped reading as theirs the moment they navigated away. Opening the editor now creates the draft deliberately, through `beginCatalogueDraft`, so the act has a row behind it. That splits one flag into two questions the directory was conflating: whether a draft is open, and whether it says anything the publication does not. An untouched draft can be discarded but not published, and only the second question answers that. `catalogueRecordState` collapses the badge's cascade and the filter's options into one list, so what an operator can select is exactly what they can see, and a broken sync outranks a delisting outranks waiting changes.
HarryRandall
force-pushed
the
feat/landing-redesign
branch
from
September 22, 2026 12:25
0850563 to
0daf47d
Compare
HarryRandall
force-pushed
the
fix/ui-improvements
branch
from
September 22, 2026 12:25
57e84bb to
25ab8ba
Compare
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This is stack 15 of 16. It contains the focused commits between
feat/landing-redesignandfix/ui-improvementsand targets the branch immediately below it.Verification
Deployment notes
Do not deploy this branch independently. Merge the stack from the bottom upwards. The one-time hosted database rebuild remains a separate approved operation after the complete stack reaches
main.