This commit is contained in:
AlacrisDevs
2026-02-07 23:10:10 +02:00
parent 23693db9ec
commit 75a2aefadb
25 changed files with 457 additions and 679 deletions

View File

@@ -1,13 +1,14 @@
<!doctype html>
<html lang="%paraglide.lang%">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1"
/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
@@ -22,4 +23,5 @@
<body data-sveltekit-preload-data="tap">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>
</html>

View File

@@ -2,6 +2,9 @@
import { Button, Input } from "$lib/components/ui";
import { createRoom } from "$lib/matrix";
import { toasts } from "$lib/stores/ui";
import { createLogger, getErrorMessage } from "$lib/utils/logger";
const log = createLogger('matrix:room');
import { syncRoomsFromEvent, selectRoom } from "$lib/stores/matrix";
interface Props {
@@ -35,9 +38,9 @@
roomName = "";
isDirect = false;
onClose();
} catch (e: any) {
console.error("Failed to create room:", e);
toasts.error(e.message || "Failed to create room");
} catch (e: unknown) {
log.error('Failed to create room', { error: e });
toasts.error(getErrorMessage(e, 'Failed to create room'));
} finally {
isCreating = false;
}

View File

@@ -2,6 +2,9 @@
import { Button, Input } from "$lib/components/ui";
import { createSpace, getSpaces } from "$lib/matrix";
import { toasts } from "$lib/stores/ui";
import { createLogger, getErrorMessage } from "$lib/utils/logger";
const log = createLogger('matrix:space');
import { syncRoomsFromEvent } from "$lib/stores/matrix";
interface Props {
@@ -45,9 +48,9 @@
spaceTopic = "";
isPublic = false;
onClose();
} catch (e: any) {
console.error("Failed to create space:", e);
toasts.error(e.message || "Failed to create space");
} catch (e: unknown) {
log.error('Failed to create space', { error: e });
toasts.error(getErrorMessage(e, 'Failed to create space'));
} finally {
isCreating = false;
}

View File

@@ -20,6 +20,9 @@
import EmojiPicker from "$lib/components/ui/EmojiPicker.svelte";
import { convertEmojiShortcodes } from "$lib/utils/emojiData";
import { getTwemojiUrl } from "$lib/utils/twemoji";
import { createLogger, getErrorMessage } from "$lib/utils/logger";
const log = createLogger('matrix:input');
// Emoji detection regex
const emojiRegex =
@@ -134,11 +137,11 @@
}
// Send typing indicator
setTyping(roomId, true).catch(console.error);
setTyping(roomId, true).catch((e) => log.error('Failed to send typing', { error: e }));
// Stop typing after 3 seconds of no input
typingTimeout = setTimeout(() => {
setTyping(roomId, false).catch(console.error);
setTyping(roomId, false).catch((e) => log.error('Failed to stop typing', { error: e }));
}, 3000);
}
@@ -416,7 +419,7 @@
clearTimeout(typingTimeout);
typingTimeout = null;
}
setTyping(roomId, false).catch(console.error);
setTyping(roomId, false).catch((e) => log.error('Failed to stop typing', { error: e }));
// Create a temporary event ID for the pending message
const tempEventId = `pending-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
@@ -462,11 +465,11 @@
// If no event ID returned, just mark as not pending
confirmPendingMessage(roomId, tempEventId, tempEventId);
}
} catch (e: any) {
console.error("Failed to send message:", e);
} catch (e: unknown) {
log.error('Failed to send message', { error: e });
// Remove the pending message on failure
removePendingMessage(roomId, tempEventId);
toasts.error(e.message || "Failed to send message");
toasts.error(getErrorMessage(e, 'Failed to send message'));
} finally {
isSending = false;
// Refocus after DOM settles from optimistic update
@@ -497,9 +500,9 @@
const contentUri = await uploadFile(file);
await sendFileMessage(roomId, file, contentUri);
toasts.success("File sent!");
} catch (e: any) {
console.error("Failed to upload file:", e);
toasts.error(e.message || "Failed to upload file");
} catch (e: unknown) {
log.error('Failed to upload file', { error: e });
toasts.error(getErrorMessage(e, 'Failed to upload file'));
} finally {
isUploading = false;
}

View File

@@ -2,6 +2,9 @@
import { Avatar } from "$lib/components/ui";
import { setRoomName, setRoomTopic, setRoomAvatar } from "$lib/matrix";
import { toasts } from "$lib/stores/ui";
import { createLogger } from "$lib/utils/logger";
const log = createLogger('matrix:settings');
import { syncRoomsFromEvent } from "$lib/stores/matrix";
import type { RoomSummary } from "$lib/matrix/types";
@@ -55,7 +58,7 @@
toasts.success("Room settings updated");
onClose();
} catch (e) {
console.error("Failed to update room settings:", e);
log.error('Failed to update room settings', { error: e });
toasts.error("Failed to update room settings");
} finally {
isSaving = false;

View File

@@ -2,6 +2,9 @@
import { Avatar } from '$lib/components/ui';
import { searchUsers, createDirectMessage } from '$lib/matrix';
import { toasts } from '$lib/stores/ui';
import { createLogger, getErrorMessage } from '$lib/utils/logger';
const log = createLogger('matrix:dm');
interface Props {
onClose: () => void;
@@ -29,7 +32,7 @@
try {
searchResults = await searchUsers(searchQuery);
} catch (e) {
console.error('Search failed:', e);
log.error('Search failed', { error: e });
} finally {
isSearching = false;
}
@@ -43,9 +46,9 @@
toasts.success('Direct message started!');
onDMCreated(roomId);
onClose();
} catch (e: any) {
console.error('Failed to create DM:', e);
toasts.error(e.message || 'Failed to start direct message');
} catch (e: unknown) {
log.error('Failed to create DM', { error: e });
toasts.error(getErrorMessage(e, 'Failed to start direct message'));
} finally {
isCreating = false;
}

View File

@@ -1,6 +1,9 @@
<script lang="ts">
import { syncState, syncError, clearState } from "$lib/stores/matrix";
import { clearAllCache } from "$lib/cache";
import { createLogger } from "$lib/utils/logger";
const log = createLogger('matrix:sync');
interface Props {
onHardRefresh?: () => void;
@@ -43,7 +46,7 @@
// Reload the page for clean state
window.location.reload();
} catch (error) {
console.error("[SyncRecovery] Hard refresh failed:", error);
log.error('Hard refresh failed', { error });
isRefreshing = false;
}
}

View File

@@ -3,6 +3,9 @@
import { createDirectMessage } from '$lib/matrix';
import { userPresence } from '$lib/stores/matrix';
import { toasts } from '$lib/stores/ui';
import { createLogger } from '$lib/utils/logger';
const log = createLogger('matrix:profile');
import type { RoomMember } from '$lib/matrix/types';
interface Props {
@@ -35,7 +38,7 @@
onStartDM?.(roomId);
onClose();
} catch (e) {
console.error('Failed to start DM:', e);
log.error('Failed to start DM', { error: e });
toasts.error('Failed to start direct message');
} finally {
isStartingDM = false;

View File

@@ -318,7 +318,7 @@
{#if showAddItemModal}
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div class="fixed inset-0 z-[60] bg-black/60 flex items-center justify-center p-4" onclick={() => (showAddItemModal = false)} onkeydown={(e) => e.key === 'Escape' && (showAddItemModal = false)}>
<!-- svelte-ignore a11y_no_static_element_interactions -->
<!-- svelte-ignore a11y_no_static_element_interactions a11y_click_events_have_key_events -->
<div class="bg-surface rounded-2xl border border-light/10 p-5 w-full max-w-md space-y-4" onclick={(e) => e.stopPropagation()}>
<h3 class="text-body font-heading text-white">{editingItem ? 'Edit' : 'Add'} Budget Item</h3>
@@ -384,7 +384,7 @@
{#if showAddCategoryModal}
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div class="fixed inset-0 z-[60] bg-black/60 flex items-center justify-center p-4" onclick={() => (showAddCategoryModal = false)} onkeydown={(e) => e.key === 'Escape' && (showAddCategoryModal = false)}>
<!-- svelte-ignore a11y_no_static_element_interactions -->
<!-- svelte-ignore a11y_no_static_element_interactions a11y_click_events_have_key_events -->
<div class="bg-surface rounded-2xl border border-light/10 p-5 w-full max-w-sm space-y-4" onclick={(e) => e.stopPropagation()}>
<h3 class="text-body font-heading text-white">Add Category</h3>
@@ -399,10 +399,11 @@
<div class="flex gap-1.5">
{#each CATEGORY_COLORS as color}
<button
class="w-6 h-6 rounded-full border-2 transition-all {newCategoryColor === color ? 'border-white scale-110' : 'border-transparent'}"
style="background-color: {color}"
onclick={() => (newCategoryColor = color)}
></button>
class="w-6 h-6 rounded-full border-2 transition-all {newCategoryColor === color ? 'border-white scale-110' : 'border-transparent'}"
style="background-color: {color}"
onclick={() => (newCategoryColor = color)}
aria-label="Select color {color}"
></button>
{/each}
</div>
</div>

View File

@@ -422,7 +422,7 @@
{#if showAddSponsorModal}
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div class="fixed inset-0 z-[60] bg-black/60 flex items-center justify-center p-4" onclick={() => (showAddSponsorModal = false)} onkeydown={(e) => e.key === 'Escape' && (showAddSponsorModal = false)}>
<!-- svelte-ignore a11y_no_static_element_interactions -->
<!-- svelte-ignore a11y_no_static_element_interactions a11y_click_events_have_key_events -->
<div class="bg-surface rounded-2xl border border-light/10 p-5 w-full max-w-md space-y-4 max-h-[80vh] overflow-auto" onclick={(e) => e.stopPropagation()}>
<h3 class="text-body font-heading text-white">{editingSponsor ? 'Edit' : 'Add'} Sponsor</h3>
@@ -508,7 +508,7 @@
{#if showAddTierModal}
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div class="fixed inset-0 z-[60] bg-black/60 flex items-center justify-center p-4" onclick={() => (showAddTierModal = false)} onkeydown={(e) => e.key === 'Escape' && (showAddTierModal = false)}>
<!-- svelte-ignore a11y_no_static_element_interactions -->
<!-- svelte-ignore a11y_no_static_element_interactions a11y_click_events_have_key_events -->
<div class="bg-surface rounded-2xl border border-light/10 p-5 w-full max-w-sm space-y-4" onclick={(e) => e.stopPropagation()}>
<h3 class="text-body font-heading text-white">Manage Tiers</h3>
@@ -528,10 +528,11 @@
<div class="flex gap-1.5">
{#each TIER_COLORS as color}
<button
class="w-6 h-6 rounded-full border-2 transition-all {tierColor === color ? 'border-white scale-110' : 'border-transparent'}"
style="background-color: {color}"
onclick={() => (tierColor = color)}
></button>
class="w-6 h-6 rounded-full border-2 transition-all {tierColor === color ? 'border-white scale-110' : 'border-transparent'}"
style="background-color: {color}"
onclick={() => (tierColor = color)}
aria-label="Select color {color}"
></button>
{/each}
</div>
</div>

View File

@@ -16,6 +16,9 @@ import {
type PinnedEventsContent,
type RoomAvatarContent,
} from './sdk-types';
import { createLogger } from '$lib/utils/logger';
const log = createLogger('matrix:client');
// Matrix message content types
interface MessageContent extends IContent {
@@ -81,7 +84,7 @@ export interface LoginWithPasswordParams {
*/
export async function initMatrixClient(credentials: LoginCredentials): Promise<MatrixClient> {
if (client) {
console.warn('Matrix client already initialized, stopping existing client');
log.warn('Matrix client already initialized, stopping existing client');
await stopClient();
}
@@ -103,11 +106,11 @@ export async function initMatrixClient(credentials: LoginCredentials): Promise<M
// Check if crypto module is available before trying to init
if (typeof client.initRustCrypto === 'function') {
await client.initRustCrypto();
console.log('E2EE crypto initialized successfully');
log.info('E2EE crypto initialized successfully');
}
} catch (e) {
// This is expected in dev mode - WASM loading can be problematic
console.info('Crypto not available - encrypted rooms will show encrypted messages');
log.info('Crypto not available - encrypted rooms will show encrypted messages');
}
// Start the client (begins sync loop)
@@ -204,7 +207,7 @@ export async function logout(): Promise<void> {
try {
await client.logout();
} catch (e) {
console.error('Error during logout:', e);
log.error('Error during logout', { error: e });
}
await stopClient();
}
@@ -551,7 +554,7 @@ export async function setRoomNotificationLevel(roomId: string, level: Notificati
}
}
} catch (e) {
console.error('Failed to set notification level:', e);
log.error('Failed to set notification level', { error: e });
throw e;
}
}
@@ -628,7 +631,7 @@ export async function loadMoreMessages(roomId: string, limit = 50): Promise<{ ha
return { hasMore, loaded };
} catch (e) {
console.error('Failed to load more messages:', e);
log.error('Failed to load more messages', { error: e });
return { hasMore: false, loaded: 0 };
}
}
@@ -697,7 +700,7 @@ export async function sendFileMessage(
content.info.w = dimensions.width;
content.info.h = dimensions.height;
} catch (e) {
console.warn('Failed to get image dimensions:', e);
log.warn('Failed to get image dimensions', { error: e });
}
}
@@ -782,7 +785,7 @@ export async function getAuthenticatedMediaUrl(mxcUrl: string): Promise<string |
return blobUrl;
} catch (e) {
console.error('Failed to fetch authenticated media:', e);
log.error('Failed to fetch authenticated media', { error: e });
// Fallback to unauthenticated URL
return client.mxcUrlToHttp(mxcUrl);
}
@@ -834,7 +837,7 @@ export async function getAuthenticatedThumbnailUrl(
return blobUrl;
} catch (e) {
console.error('Failed to fetch authenticated thumbnail:', e);
log.error('Failed to fetch authenticated thumbnail', { error: e });
return client.mxcUrlToHttp(mxcUrl, width, height, 'scale');
}
}
@@ -936,7 +939,7 @@ export async function searchUsers(query: string, limit = 10): Promise<Array<{
avatarUrl: user.avatar_url ? client!.mxcUrlToHttp(user.avatar_url, 40, 40, 'crop') : null,
}));
} catch (e) {
console.error('User search failed:', e);
log.error('User search failed', { error: e });
return [];
}
}
@@ -1080,7 +1083,7 @@ export async function setPresence(presence: 'online' | 'offline' | 'unavailable'
try {
await client.setPresence({ presence, status_msg: statusMsg });
} catch (e) {
console.error('Failed to set presence:', e);
log.error('Failed to set presence', { error: e });
}
}

View File

@@ -109,7 +109,7 @@ function loadTheme(): ThemeState {
return { ...defaultTheme, ...JSON.parse(stored) };
}
} catch (e) {
console.warn('Failed to load theme:', e);
// Theme load failure is non-critical, fall through to default
}
return defaultTheme;
}

View File

@@ -195,6 +195,19 @@ export function clearRecentLogs() {
* Format recent logs as a copyable string for bug reports.
* User can paste this to you for debugging.
*/
/**
* Safely extract an error message from an unknown caught value.
* Use in catch blocks: `catch (e: unknown) { toasts.error(getErrorMessage(e, 'fallback')) }`
*/
export function getErrorMessage(e: unknown, fallback = 'An unexpected error occurred'): string {
if (e instanceof Error) return e.message;
if (typeof e === 'string') return e;
if (e && typeof e === 'object' && 'message' in e && typeof (e as { message: unknown }).message === 'string') {
return (e as { message: string }).message;
}
return fallback;
}
export function dumpLogs(): string {
return recentLogs
.map((e) => {

View File

@@ -45,6 +45,9 @@
import { clearBlobUrlCache } from "$lib/cache/mediaCache";
import type { Message } from "$lib/matrix/types";
import type { SupabaseClient } from "@supabase/supabase-js";
import { createLogger, getErrorMessage } from "$lib/utils/logger";
const log = createLogger('chat:page');
const supabase = getContext<SupabaseClient>("supabase");
let data = $derived(page.data);
@@ -120,7 +123,7 @@
await initCache();
await cleanupCache(7 * 24 * 60 * 60 * 1000);
} catch (e) {
console.warn("Cache initialization failed:", e);
log.warn('Cache initialization failed', { error: e });
}
// Try to load credentials from Supabase
@@ -141,7 +144,7 @@
isInitializing = false;
}
} catch (e) {
console.error("Failed to load Matrix credentials:", e);
log.error('Failed to load Matrix credentials', { error: e });
showJoinScreen = true;
isInitializing = false;
}
@@ -164,7 +167,7 @@
// Check if org has a Matrix Space, auto-create if not
await ensureOrgSpace(credentials);
} catch (e: unknown) {
console.error("Failed to init Matrix client:", e);
log.error('Failed to init Matrix client', { error: e });
toasts.error(m.chat_join_error());
showJoinScreen = true;
} finally {
@@ -196,7 +199,7 @@
}
}
} catch (e) {
console.warn("Failed to ensure org space:", e);
log.warn('Failed to ensure org space', { error: e });
}
}
@@ -223,8 +226,8 @@
if (result.provisioned) {
toasts.success(m.chat_join_success());
}
} catch (e: any) {
toasts.error(e.message || m.chat_join_error());
} catch (e: unknown) {
toasts.error(getErrorMessage(e, m.chat_join_error()));
} finally {
isProvisioning = false;
}
@@ -297,8 +300,8 @@
await editMessage($selectedRoomId, editingMsg.eventId, newContent);
editingMsg = null;
toasts.success("Message edited");
} catch (e: any) {
toasts.error(e.message || "Failed to edit message");
} catch (e: unknown) {
toasts.error(getErrorMessage(e, 'Failed to edit message'));
}
}
@@ -312,8 +315,8 @@
try {
await deleteMessage($selectedRoomId, messageId);
toasts.success("Message deleted");
} catch (e: any) {
toasts.error(e.message || "Failed to delete message");
} catch (e: unknown) {
toasts.error(getErrorMessage(e, 'Failed to delete message'));
}
}
@@ -355,8 +358,8 @@
const contentUri = await uploadFile(file);
await sendFileMessage($selectedRoomId, file, contentUri);
toasts.success("File sent!");
} catch (e: any) {
toasts.error(e.message || "Failed to upload file");
} catch (e: unknown) {
toasts.error(getErrorMessage(e, 'Failed to upload file'));
} finally {
isUploadingDrop = false;
}
@@ -369,8 +372,8 @@
const result = await loadMoreMessages($selectedRoomId);
loadRoomMessages($selectedRoomId);
if (!result.hasMore) toasts.info("No more messages to load");
} catch (e: any) {
console.error("Failed to load more messages:", e);
} catch (e: unknown) {
log.error('Failed to load more messages', { error: e });
} finally {
isLoadingMore = false;
}

View File

@@ -22,7 +22,7 @@ export const load: PageServerLoad = async ({ params, locals, url }) => {
try {
const events = await fetchEvents(locals.supabase, org.id, statusFilter);
return { events, statusFilter };
} catch (e: any) {
} catch (e: unknown) {
log.error('Failed to load events', { error: e, data: { orgId: org.id } });
return { events: [], statusFilter };
}

View File

@@ -6,6 +6,7 @@
import type { SupabaseClient } from "@supabase/supabase-js";
import type { Database } from "$lib/supabase/types";
import { toasts } from "$lib/stores/ui";
import { getErrorMessage } from "$lib/utils/logger";
import * as m from "$lib/paraglide/messages";
interface EventItem {
@@ -100,8 +101,8 @@
showCreateModal = false;
resetForm();
goto(`/${data.org.slug}/events/${created.slug}`);
} catch (e: any) {
toasts.error(e.message || "Failed to create event");
} catch (e: unknown) {
toasts.error(getErrorMessage(e, 'Failed to create event'));
} finally {
creating = false;
}

View File

@@ -23,8 +23,8 @@ export const load: LayoutServerLoad = async ({ params, locals, parent }) => {
]);
return { event, eventMembers: members, eventRoles: roles, eventDepartments: departments };
} catch (e: any) {
if (e?.status === 404) throw e;
} catch (e: unknown) {
if (e && typeof e === 'object' && 'status' in e && (e as { status: number }).status === 404) throw e;
log.error('Failed to load event', { error: e, data: { orgId, eventSlug: params.eventSlug } });
error(500, 'Failed to load event');
}

View File

@@ -5,6 +5,7 @@
import type { SupabaseClient } from "@supabase/supabase-js";
import type { Database } from "$lib/supabase/types";
import { toasts } from "$lib/stores/ui";
import { getErrorMessage } from "$lib/utils/logger";
import type { Event, EventMemberWithDetails, EventRole, EventDepartment } from "$lib/api/events";
import * as m from "$lib/paraglide/messages";
@@ -173,8 +174,8 @@
goto(`/${data.org.slug}/events/${data.event.slug}`, {
invalidateAll: true,
});
} catch (e: any) {
toasts.error(e.message || "Failed to update event");
} catch (e: unknown) {
toasts.error(getErrorMessage(e, 'Failed to update event'));
} finally {
saving = false;
}
@@ -192,8 +193,8 @@
toasts.success(m.events_deleted());
goto(`/${data.org.slug}/events`);
} catch (e: any) {
toasts.error(e.message || "Failed to delete event");
} catch (e: unknown) {
toasts.error(getErrorMessage(e, 'Failed to delete event'));
} finally {
deleting = false;
}

View File

@@ -54,7 +54,7 @@ export const load: PageServerLoad = async ({ params, locals, parent }) => {
sponsors,
sponsorDeliverables,
};
} catch (e: any) {
} catch (e: unknown) {
log.error('Failed to load department dashboard', { error: e, data: { deptId: params.deptId } });
error(500, 'Failed to load department dashboard');
}

View File

@@ -4,6 +4,7 @@
import type { SupabaseClient } from "@supabase/supabase-js";
import type { Database } from "$lib/supabase/types";
import { toasts } from "$lib/stores/ui";
import { getErrorMessage } from "$lib/utils/logger";
import type {
Event,
EventMemberWithDetails,
@@ -260,8 +261,8 @@
selectedRoleId = "";
selectedDeptIds = [];
addNotes = "";
} catch (e: any) {
toasts.error(e.message || "Failed to add member");
} catch (e: unknown) {
toasts.error(getErrorMessage(e, 'Failed to add member'));
} finally {
adding = false;
}
@@ -327,8 +328,8 @@
toasts.success(m.team_updated());
editingMember = null;
} catch (e: any) {
toasts.error(e.message || "Failed to update member");
} catch (e: unknown) {
toasts.error(getErrorMessage(e, 'Failed to update member'));
} finally {
updatingMember = false;
}
@@ -349,8 +350,8 @@
teamMembers = teamMembers.filter((tm) => tm.id !== memberToRemove!.id);
toasts.success(m.team_removed({ name }));
memberToRemove = null;
} catch (e: any) {
toasts.error(e.message || "Failed to remove member");
} catch (e: unknown) {
toasts.error(getErrorMessage(e, 'Failed to remove member'));
} finally {
removing = false;
}
@@ -398,8 +399,8 @@
toasts.success(m.team_dept_created());
}
showDeptModal = false;
} catch (e: any) {
toasts.error(e.message || "Failed to save department");
} catch (e: unknown) {
toasts.error(getErrorMessage(e, 'Failed to save department'));
} finally {
savingDept = false;
}
@@ -419,8 +420,8 @@
departments: tm.departments.filter((d) => d.id !== dept.id),
}));
toasts.success(m.team_dept_deleted());
} catch (e: any) {
toasts.error(e.message || "Failed to delete department");
} catch (e: unknown) {
toasts.error(getErrorMessage(e, 'Failed to delete department'));
}
}
@@ -464,8 +465,8 @@
toasts.success(m.team_role_created());
}
showRoleModal = false;
} catch (e: any) {
toasts.error(e.message || "Failed to save role");
} catch (e: unknown) {
toasts.error(getErrorMessage(e, 'Failed to save role'));
} finally {
savingRole = false;
}
@@ -486,8 +487,8 @@
: tm,
);
toasts.success(m.team_role_deleted());
} catch (e: any) {
toasts.error(e.message || "Failed to delete role");
} catch (e: unknown) {
toasts.error(getErrorMessage(e, 'Failed to delete role'));
}
}

View File

@@ -621,8 +621,9 @@
<Input label="Name" name="name" bind:value={editEventModal.name} />
<Input label="Slug" name="slug" bind:value={editEventModal.slug} />
<div>
<label class="block text-body-sm text-light/60 mb-1">Status</label>
<label for="event-status" class="block text-body-sm text-light/60 mb-1">Status</label>
<select
id="event-status"
name="status"
bind:value={editEventModal.status}
class="w-full bg-dark/50 border border-light/10 rounded-xl px-3 py-2 text-body-sm text-white focus:outline-none focus:border-primary/50"
@@ -634,8 +635,9 @@
</div>
<div class="grid grid-cols-2 gap-3">
<div>
<label class="block text-body-sm text-light/60 mb-1">Start Date</label>
<label for="event-start-date" class="block text-body-sm text-light/60 mb-1">Start Date</label>
<input
id="event-start-date"
type="date"
name="start_date"
bind:value={editEventModal.start_date}
@@ -643,8 +645,9 @@
/>
</div>
<div>
<label class="block text-body-sm text-light/60 mb-1">End Date</label>
<label for="event-end-date" class="block text-body-sm text-light/60 mb-1">End Date</label>
<input
id="event-end-date"
type="date"
name="end_date"
bind:value={editEventModal.end_date}

View File

@@ -1,6 +1,9 @@
import { json } from '@sveltejs/kit';
import { env } from '$env/dynamic/private';
import type { RequestHandler } from './$types';
import { createLogger } from '$lib/utils/logger';
const log = createLogger('api:matrix-provision');
/**
* POST /api/matrix-provision
@@ -83,7 +86,7 @@ export const POST: RequestHandler = async ({ request, locals }) => {
if (!registerRes.ok) {
const err = await registerRes.json().catch(() => ({}));
console.error('Matrix register failed:', registerRes.status, err);
log.error('Matrix register failed', { data: { status: registerRes.status }, error: err });
return json({ error: 'Failed to create Matrix account' }, { status: 500 });
}
@@ -104,7 +107,7 @@ export const POST: RequestHandler = async ({ request, locals }) => {
if (!loginRes.ok) {
const err = await loginRes.json().catch(() => ({}));
console.error('Matrix login failed:', loginRes.status, err);
log.error('Matrix login failed', { data: { status: loginRes.status }, error: err });
return json({ error: 'Failed to login to Matrix account' }, { status: 500 });
}
@@ -118,7 +121,7 @@ export const POST: RequestHandler = async ({ request, locals }) => {
try {
await setMatrixAvatar(homeserverUrl, accessToken, profile.avatar_url);
} catch (e) {
console.warn('Failed to set Matrix avatar:', e);
log.warn('Failed to set Matrix avatar', { error: e });
}
}
@@ -138,7 +141,7 @@ export const POST: RequestHandler = async ({ request, locals }) => {
);
if (upsertError) {
console.error('Failed to store Matrix credentials:', upsertError);
log.error('Failed to store Matrix credentials', { error: upsertError });
return json({ error: 'Failed to store credentials' }, { status: 500 });
}
@@ -152,7 +155,7 @@ export const POST: RequestHandler = async ({ request, locals }) => {
provisioned: true,
});
} catch (e) {
console.error('Matrix provisioning error:', e);
log.error('Matrix provisioning error', { error: e });
return json({ error: 'Matrix provisioning failed' }, { status: 500 });
}
};

View File

@@ -1,5 +1,8 @@
import { json } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
import { createLogger, getErrorMessage } from '$lib/utils/logger';
const log = createLogger('api:matrix-space');
/**
* GET: Retrieve the Matrix Space ID for an org
@@ -140,9 +143,9 @@ export const POST: RequestHandler = async ({ request, locals }) => {
}
return json({ spaceId, created: true });
} catch (e: any) {
console.error('Failed to create Matrix Space:', e);
return json({ error: e.message || 'Failed to create Matrix Space' }, { status: 500 });
} catch (e: unknown) {
log.error('Failed to create Matrix Space', { error: e });
return json({ error: getErrorMessage(e, 'Failed to create Matrix Space') }, { status: 500 });
}
}