Add tenant branding & theming system with admin UI
Tenant admins can now customize their workspace appearance: page/nav backgrounds (solid, gradient, or image), column/card colors, borders, text, opacity with glass blur, card corner radius, and accent colors. Light and dark mode are configured separately. Theme CSS is injected server-side via transformPageChunk to prevent FOUC. Includes avatar components, account page updates, and pre-existing type error fixes (Buffer, async onMount, InputJsonValue). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
import CardModal from '$lib/components/CardModal.svelte';
|
||||
import ActivityFeed from '$lib/components/ActivityFeed.svelte';
|
||||
import BoardFilters from '$lib/components/BoardFilters.svelte';
|
||||
import Avatar from '$lib/components/Avatar.svelte';
|
||||
import type { FilterState } from '$lib/components/BoardFilters.svelte';
|
||||
|
||||
let { data } = $props();
|
||||
@@ -402,12 +403,7 @@
|
||||
<span class="text-xs text-gray-400 dark:text-gray-500">Also here:</span>
|
||||
<div class="flex -space-x-1.5">
|
||||
{#each viewingUsers.filter((u) => u.id !== data.user?.id) as viewer}
|
||||
<div
|
||||
class="w-6 h-6 rounded-full bg-emerald-500 text-white text-[11px] flex items-center justify-center border-2 border-white dark:border-gray-900"
|
||||
title={viewer.name}
|
||||
>
|
||||
{viewer.name[0].toUpperCase()}
|
||||
</div>
|
||||
<Avatar name={viewer.name} avatarUrl={viewer.avatarUrl} size="sm" class="border-2 border-white dark:border-gray-900" title={viewer.name} />
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
@@ -468,7 +464,8 @@
|
||||
{#each columns as column (column.id)}
|
||||
{@const visibleCards = filterCards(column.cards)}
|
||||
<div
|
||||
class="flex-shrink-0 w-64 sm:w-72 bg-[var(--color-column-bg)] rounded-xl flex flex-col max-h-full"
|
||||
class="flex-shrink-0 w-64 sm:w-72 rounded-xl flex flex-col max-h-full"
|
||||
style="background: var(--color-column-bg); border: 1px solid var(--color-column-border); color: var(--color-column-text); backdrop-filter: var(--column-backdrop-blur, none);"
|
||||
animate:flip={{ duration: flipDurationMs }}
|
||||
>
|
||||
<!-- Column header -->
|
||||
@@ -536,7 +533,8 @@
|
||||
{@const progress = getChecklistProgress(card)}
|
||||
{@const dueUrgency = getDueUrgency(card.dueDate)}
|
||||
<button
|
||||
class="w-full text-left mb-2 rounded-lg bg-[var(--color-card-bg)] p-3 shadow-sm hover:shadow-md border border-gray-200 hover:border-gray-300 dark:border-gray-600 dark:hover:border-gray-500 transition cursor-pointer"
|
||||
class="w-full text-left mb-2 p-3 shadow-sm hover:shadow-md transition cursor-pointer"
|
||||
style="background: var(--color-card-bg); border: 1px solid var(--color-card-border); color: var(--color-card-text); border-radius: var(--color-card-radius); backdrop-filter: var(--card-backdrop-blur, none);"
|
||||
animate:flip={{ duration: flipDurationMs }}
|
||||
onclick={() => (selectedCard = card)}
|
||||
>
|
||||
@@ -589,12 +587,7 @@
|
||||
{#if card.assignees && card.assignees.length > 0}
|
||||
<div class="flex -space-x-1 mt-2">
|
||||
{#each card.assignees.slice(0, 3) as assignee}
|
||||
<div
|
||||
class="w-5 h-5 rounded-full bg-[var(--color-primary)] text-white text-[10px] flex items-center justify-center border border-white"
|
||||
title={assignee.user.name}
|
||||
>
|
||||
{assignee.user.name[0].toUpperCase()}
|
||||
</div>
|
||||
<Avatar name={assignee.user.name} avatarUrl={assignee.user.avatarUrl} size="xs" class="border border-white" title={assignee.user.name} />
|
||||
{/each}
|
||||
{#if card.assignees.length > 3}
|
||||
<div
|
||||
@@ -681,7 +674,7 @@
|
||||
{#if data.canEdit}
|
||||
<div class="flex-shrink-0 w-72">
|
||||
{#if showAddColumn}
|
||||
<div class="bg-[var(--color-column-bg)] rounded-xl p-3">
|
||||
<div class="rounded-xl p-3" style="background: var(--color-column-bg);">
|
||||
<form onsubmit={(e) => { e.preventDefault(); addColumn(); }}>
|
||||
<input
|
||||
bind:value={addingColumnTitle}
|
||||
|
||||
Reference in New Issue
Block a user