Skip to content

Feat/islands - #554

Open
kake21 wants to merge 114 commits into
mainfrom
feat/islands
Open

kake21 wants to merge 114 commits into
mainfrom
feat/islands

Conversation

@kake21

@kake21 kake21 commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Major style overhaul of projectNext.

Extends #526 and #514.
Continues work on #357 and #401.
Implements hamburger menu from #7 issue.

Waiting on SVG support from CMS to color logos in mobile navbar.

  • Standardizes core UI components (Button, TextInput, DateInput, Checkbox, Textarea, NumberInput, SubmitButton) onto a consistent card/gap/rounding system, and adds new Dropdown/SearchableDropdown components used to rebuild the admin user list (sortable, standardized).
  • Various admin page redesigns (sidebar as nested cards, /admin/dots, flairs with animated drag-to-reorder, a new component test page) and smaller fixes (CommitteeCard, HeaderItemPopUp, PopUp, jobads/events zoning, omegaquote bubble tail, edit-mode icon visibility, frontpage preview link).
  • PageTitle context: PageTitleProvider (mounted once in layout.tsx) holds the current title; each page
    renders <PageTitleSetter title="..." />, which pushes the title up via a plain useEffect (set on mount/ch
    ange, clear on unmount) and NavBarTitle reads it back out to render in the nav bar. Adopted across ~15 pages
    (auth, admin, users, events, committees, images, error/not-found, etc.) to avoid prop-drilling a title throug
    h every layout.
  • Changed the colors to a base16 inspired layout.

Images showing the proposed stylechange:

Logged in main page desktop:
image

Profile page desktop:
image

Logged in main page mobile:
Screen Shot 2026-08-05 at 17 46 52

Pofile page mobile:
Screen Shot 2026-08-05 at 17 47 53

kake21 and others added 30 commits May 28, 2026 04:57
…rors

Renamed $base00-$base0F in _colors.scss to semantic surface-/ink-/accent-
tokens and updated all call sites. Also cleaned up dead imports and
variables left over from the nav-bar refactor (Menu, EditModeSwitch,
itemsForMenu, BackButton, faArrowLeft) and fixed DesktopSideBar missing
its required profile prop in layout.tsx.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Set --gap: 0.5rem in globals.scss and point $gap at var(--gap) instead
of a hardcoded 8px, so spacing can be adjusted at runtime via
document.documentElement.style.setProperty('--gap', ...). Since Sass
can't do compile-time math on a var(), every place that multiplied or
divided $gap directly is now wrapped in calc() so the arithmetic
happens in CSS instead.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Wrap every SCSS variable reference inside calc(...) in #{} (e.g.
calc(#{ohma.$gap} * 2)) per the project's IDE inspection preference.
Bare (non-calc) variable usages are left as-is.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Restyle SlideSidebar so each nav section header is a rounded card and
its links are indented, darker rounded cards beneath it, matching the
target admin design. Also tunes surface-base/surface-raised toward a
cooler navy and sets --primary to a flat hex.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds max-width: calc(100dvh * 16 / 9) with auto margins to the root
grid wrapper so the app fills the screen edge-to-edge on 16:9
displays but stays capped and centered on ultrawide monitors instead
of stretching the whole layout across the full width.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
.wrapper used position: absolute + width: 100vw, breaking out of the
root layout's .content grid area entirely (ignoring the nav/sidebar
frame and the 16:9 max-width cap). Switch to flex: 1 so it fills its
parent slot the same way error.module.scss and not-found.module.scss
already do.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Replace the full-bleed photo-hero tile (hover-zoom, text overlaid on
the image) with an actual card: solid surface background, a 128x128
contained logo tile instead of a cropped background image, and the
title laid out beside it. Reuses the boxShadow/rounding/surface-*
tokens already established elsewhere (SlideSidebar, NavBar). Widens
the committees grid columns to fit the new row layout.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Buttons now use rounding - gap instead of the full card radius, and
the shared table mixin gets rounded corners, a raised header, and
zebra/hover states pulled from the surface color tokens instead of
the old color-mix + blur hacks.
Swap the Opp/Ned buttons on the flairs admin table for a drag handle,
using framer-motion's Reorder for the spring-animated reordering. The
table markup moves from <table> to a flex "fake table" since Framer's
layout animations don't play well with table-row layout. Drop commits
the new position by replaying increase/decreaseFlairRankAction the
right number of times, then refreshes.
…tandard

Fields now use the filled surface-raised background, rounding - gap
corners, and primary-blue focus border established for buttons and
tables. DateInput also gets color-scheme: dark so the native picker
icon/popup stop rendering as a stark white box, and Checkbox swaps
the unstyled native control for a custom appearance:none box with a
CSS-drawn checkmark.
The root layout's mobile grid reserved a full nav-height row for a
"subPageNavBar" area that nothing ever renders into — each page's
SubPageNavBar lives inside its own content flow, not that named grid
area. Dropping the empty row gives .content back ~72px of height it
was silently losing on every mobile page.
kake21 and others added 2 commits August 21, 2026 10:38
…height

Restructures the committee layout into a grid with a scrollable main
area, lays the logo and cover image side by side instead of stacked,
and stretches the page content to fill the remaining viewport height.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DdkD6352w1jLe6TVj5KUnn
@kake21
kake21 marked this pull request as ready for review August 23, 2026 09:41
kake21 and others added 27 commits September 1, 2026 10:27
# Conflicts:
#	src/app/_components/NavBar/NavBar.tsx
#	src/app/committees/[shortName]/layout.tsx
#	src/app/image-collections/MakeNewCollection.tsx
#	src/app/layout.tsx
#	src/app/news/page.tsx
#	src/app/users/[username]/(user-admin)/theme/ThemeForm.tsx
#	standard_store/logo_simple.svg
#	standard_store/logo_white.svg
#	standard_store/magisk_hatt.svg
#	standard_store/omega_logo_white.svg
#	standard_store/pwa.svg
#	standard_store/vevcom_logo.svg
… gaps

Apply consistent padding, border-radius, and layout gap across news articles and components. Adjust scrollable behavior with flex-grow and overflow handling for better usability.
…s' into feat/islands

# Conflicts:
#	src/app/_components/Image/Image.tsx
#	src/app/_components/User/UserCard.tsx
#	src/services/flairs/operations.ts
#	src/services/groups/committees/operations.ts
#	src/services/images/standard/operations.ts
#	src/services/images/subservice/constants.ts
#	src/services/images/subservice/operations.ts
#	src/services/ombul/operations.ts
#	src/services/users/constants.ts
#	src/services/users/operations.ts
Introduced optional tinting functionality for SVGs in the `Image` component. Replaced several PNG assets with optimized SVG equivalents for better scalability and flexibility. Updated relevant styles and components to support new image configurations.
Added logic to associate seeded development events with a predefined standard image (`FAIR`) by updating relevant `cmsImage` records.
Reworked the `CommitteeImage` component to separate logo and cover into distinct "islands" with updated styling. Simplified SCSS, removed redundant BackdropImage, and streamlined `PageWrapper` with a new `className` prop for customizations.
… depth-based styling

Introduced logic to flatten and render notification channels as an indented, depth-first hierarchy. Added `orderByHierarchy` function to sort channels and updated the page layout to use a styled table. Integrated new SCSS styles for hierarchy visualization and badges.
… improved readability and layout consistency
…verflowing their card

LOGO_SIMPLE in the loader and the committee logo mask both defaulted to
hardcoded colours instead of following the theme. The committees list
also rendered logos via plain Image instead of CommitteeLogo, so its
inline width beat the card's percentage sizing rule and spilled past
the padded box.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The subnav already links to /users/[username]/settings, so the profile
card's own settings button was a redundant duplicate.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…`ImageCollectionList`

Introduced a new `ModeSwitch` component for segmented toggle functionality, with smooth transitions using `framer-motion`. Replaced mode toggle buttons in `ImageCollectionList` with the new `ModeSwitch`. Updated SCSS for improved layout and responsiveness.
…lor adjustments

Added `min-height: 100%` and `background-color: ohma.$colors-surface-base` to `.wrapper` styles in dynamic and special image collection pages for consistent layout and appearance.
… components

Integrated new "Ombul" and "Omegaquotes" sections on the logged-in frontpage. Developed `OmbulRow` and `OmegaquoteRow` components for compact list-row displays. Enhanced styling and dynamic content rendering based on user permissions.
… that fits

The large image view painted itself with $colors-gray-500 - a hardcoded #adb5bd
left over from before the surface tokens existed - while its text inherited
$colors-text, leaving the metadata at about 1.7:1 contrast in a dark themed app.
It also had no backdrop, so the page showed through around its 95vw/95vh box and
clicking outside did nothing, and it stacked metadata, a 90%-tall image and the
controls inside a padded box that could not hold all three.

- Paint the panel with $colors-surface-base behind PopUp's scrim, so the two
  overlay surfaces dim the page the same way, and close on click-outside.
- Lay the panel out as fixed header/footer bands around an image band that takes
  the rest, so a long name or credit shrinks the image instead of pushing the
  controls out of view.
- Move the resolution picker into the footer row next to the arrows; the two
  were absolutely positioned into the same strip and collided on narrow screens.
- Extract PopUp's close button into an ohma.closeBtn mixin and use it for both,
  so dismissing either surface looks the same.
- Replace the tile select button's gray-500 with surface tokens; its :hover set
  the same colour as its base, so it had no hover state at all.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Lqz7YRBiQxJWSK1FacUQ2
… its header

Both collection detail pages hand-rolled their own page wrapper, so they were
the only pages in the app padded with `2em min(4rem, 4vw)` instead of the shared
`2 * $gap`, the only ones rendering a visible <h1>, and - because they never
rendered PageTitleSetter - the only ones leaving the nav's title slot blank. The
collection name now reaches the nav the same way "Fotogalleri" does from the
gallery index, and the description leads the body instead.

With a header slot available, CollectionAdmin no longer has to float: it was
`position: fixed; top: 100px; right: 3em`, guessing at the nav height, ignoring
the layout's max-width centring, overlaying the image grid's top right corner
and staying there while the page scrolled. It is now a row of header items in
PageWrapper's header, like every other page's admin controls, built on the same
HeaderItemPopUp the rest of the app uses (with faUpload and faEye variants added
alongside the existing ones).

DynamicCollectionPanel owns the wrapper, since the admin controls in the header
slot and the image panel in the body have to share the refresh callback.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Lqz7YRBiQxJWSK1FacUQ2
- The tiles carried a 3px accent-blue border at rest that jumped to 10px on
  hover with no transition, so the frame snapped while the image inside glided
  through its 0.5s scale - and a wall of blue frames read before the photographs
  did. The border is neutral at rest now and only changes colour on hover.
- Spacing moves from per-tile margins (`margin: $gap; margin-left: 0`) to a gap
  on the panel, which drops the margin left hanging off the end of each row.
- An empty collection showed the pager's "Ingen flere å laste inn", which reads
  as though something had already been listed. It gets an empty state instead.
- The upload popup no longer resizes when switching between batch and single
  upload: the two modes set 50vw and 300px against a content-sized dialog, so
  the width now belongs to the popup and both modes fill it.
- The mode toggle moves into flow. As `position: absolute` it anchored to
  PopUp's fixed overlay below the mobile breakpoint, where .main is not
  positioned, and landed in the viewport's corner instead of the sheet's. It is
  also rendered once now rather than once per branch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Lqz7YRBiQxJWSK1FacUQ2
The icon-only header items were circles sitting next to the labelled pill
variant, which is a rounded square - two shapes for what is the same control.
They now share the pill's radius, so a header row reads as one set of buttons.

The collection admin's three items were also mismatched in size: the upload and
visibility variants default to a 40px button while the settings variant defaults
to 18px, so it is given the matching scale explicitly.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Lqz7YRBiQxJWSK1FacUQ2
- /report hand-rolled its own wrapper, so it was the one page whose content sat
  straight on the app's gradient with no surface, and it never set the nav's page
  title. It goes through PageWrapper now; the article's 6em hero heading stays,
  with the class doubled so it beats PageWrapper's own `.wrapper h1` by intent
  rather than by stylesheet order.
- /articles/[category] and the articles under it left the nav title blank too.
  PageTitleSetter goes in the shared layout, which covers both routes.
- The photo gallery grid was centre-justified, insetting it from the mode switch
  above and the load control below and leaving the last row offset from the rows
  above. It is left-aligned now, spaced with a container gap instead of per-item
  margins, and the covers use border-radius rather than ohma.round - the mixin's
  padding was insetting each cover inside its own cell.
- /career's three category rows were three different heights, because each image
  kept its own aspect ratio inside a `flex: 1` box. The image is a fixed box that
  the picture covers. The intro paragraph gets a measure instead of running the
  full page width.
- ImageCard was a fixed 280px with its text absolutely positioned into a fixed
  120px block, leaving ~75px of empty card under a one-line description. It is a
  flex column that ends where its text ends, with the description clamped so one
  long entry cannot set the height of a whole row.
- On the login page "Glemt passord?" was styled as body copy whose only hover
  state dimmed it, which read as disabled rather than as a link. The form column
  also widens from 380px to 460px so it is less of a strip beside the photo.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Lqz7YRBiQxJWSK1FacUQ2
Both rendered LOGO_SIMPLE untinted, so the Omega came out near-black against the
dark surface and was barely visible next to the message it sits beside. They now
pass tint="var(--text)", the same way Loader already does (and NavBar, with
--surface-base).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Lqz7YRBiQxJWSK1FacUQ2
The page returned a bare <div>Failed to load interest groups</div> instead of
throwing, so an unauthorised visitor got that string dropped into the layout's
content area with no page surface and no padding - the first letter clipped by
the area's rounded corner - while every other page renders the styled error page.
It now uses unwrapActionReturn, which the TODO on that line already suggested and
which the rest of the server components use, so the service's own message reaches
the boundary: "401 - Du trenger tillatelse 'INTEREST_GROUP_READ' ...".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Lqz7YRBiQxJWSK1FacUQ2
The page hand-rolled a three-column grid with every child placed explicitly, on
no background at all - it was one of the last pages floating straight on the app
gradient, and it never set the nav's page title.

- Into PageWrapper, so surface, padding and title come from there. The name stays
  in the body since it is editable in place (ChangeName), but no longer gets the
  wrapper's capitalisation - the name is whatever the editor typed.
- Title, issue line and description on the left of a header row, the three
  actions on the right. They were three identical accent buttons reading as three
  equally likely choices; downloading the issue is the point of the page, so it
  keeps the accent and the other two recede to secondary.
- The cover is the cover image in a 5/7 box rather than an OmbulCover card, which
  on this page linked back to the page you were already on and repeated the name
  and issue printed directly above it. It is capped so it does not stretch to the
  full page width once the columns collapse.
- The admin panel had a background and a radius but no padding, so its heading and
  first field sat flush against the edges. It gets padding, a delineating border
  (the fields inside are surface-raised, so a raised panel would swallow them),
  top-aligned columns instead of centred ones - which had floated the short form
  column against the middle of the much taller cover - hairline dividers in place
  of 3px rules, and a 200px cover instead of 400px.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Lqz7YRBiQxJWSK1FacUQ2
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