Files
Musify/web-player/src/lib/components/ui/layout/PageHeader.svelte
T
Admin cb046bba9e Let users browse followers and following lists
Following lists are public; followers are visible to the user and to mutual followers.
Adds GET /users/{id}/followers and /following, exposes isFollowing and canViewFollowers
on the profile, and returns isFollowedByViewer from user search so the web player no
longer calls /is-following per user.
2026-09-23 22:55:14 +02:00

64 lines
1.4 KiB
Svelte

<script lang="ts">
import type { Snippet } from 'svelte';
interface Props {
title: string;
eyebrow?: string;
description?: string;
meta?: string | Snippet;
cover?: Snippet;
actions?: Snippet;
align?: 'center' | 'end';
class?: string;
}
let {
title,
eyebrow,
description,
meta,
cover,
actions,
align = 'end',
class: klass = ''
}: Props = $props();
</script>
<div class="mb-7 sm:mb-8 {klass}">
<div
class="flex flex-col gap-5 sm:flex-row sm:gap-6 {cover
? align === 'end'
? 'sm:items-end'
: 'sm:items-center'
: 'sm:items-end sm:justify-between'}"
>
{#if cover}
{@render cover()}
{/if}
<div class="min-w-0 flex-1">
{#if eyebrow}
<p class="text-eyebrow text-fg-2">{eyebrow}</p>
{/if}
<h1 class="text-display-1 wrap-break-word text-fg {eyebrow ? 'mt-1.5' : ''}">
{title}
</h1>
{#if description}
<p class="mt-3 max-w-2xl text-body text-fg-2">{description}</p>
{/if}
{#if typeof meta === 'string'}
<p class="mt-3 text-sm text-fg-2">{meta}</p>
{:else if meta}
<p class="mt-3 text-sm text-fg-2">{@render meta()}</p>
{/if}
</div>
{#if actions && !cover}
<div class="flex shrink-0 items-center gap-3">{@render actions()}</div>
{/if}
</div>
{#if actions && cover}
<div class="mt-6 flex flex-wrap items-center gap-2.5 sm:mt-7">
{@render actions()}
</div>
{/if}
</div>