This commit is contained in:
2026-05-08 09:06:14 +12:00
parent 1533b5aa9b
commit 9afc3170ff
22 changed files with 2710 additions and 549 deletions
+22 -20
View File
@@ -1,5 +1,6 @@
<script lang="ts">
import { api } from '$lib/api';
import { toast } from '$lib/toast';
import type { ClientAccessAccount, ClientAccessFeature, ClientAccessPowerBiExport } from '$lib/types';
let { data } = $props();
@@ -59,20 +60,19 @@
async function handleCreateUser(event: SubmitEvent) {
event.preventDefault();
formError = '';
formSuccess = '';
if (!selectedClientId) {
formError = 'Select a client before creating a user.';
toast.error('Select a client before creating a user.');
return;
}
if (!fullName.trim() || !email.trim()) {
formError = 'Name and email are required.';
toast.error('Name and email are required.');
return;
}
isSubmitting = true;
const tid = toast.loading('Creating user…');
try {
const updatedClient = await api.createClientUser({
client_account_id: selectedClientId,
@@ -89,9 +89,11 @@
role = 'viewer';
status = 'invited';
isNewUser = true;
formSuccess = 'User created and included in the export preview.';
toast.dismiss(tid);
toast.success('User created');
} catch (error) {
formError = error instanceof Error ? error.message : 'Unable to create client user';
toast.dismiss(tid);
toast.error(error instanceof Error ? error.message : 'Unable to create client user');
} finally {
isSubmitting = false;
}
@@ -99,16 +101,16 @@
async function updateUser(userId: number, payload: { role?: string; status?: string; is_new_user?: boolean }) {
savingUserId = userId;
formError = '';
formSuccess = '';
const tid = toast.loading('Updating user…');
try {
const updatedClient = await api.updateClientUser(userId, payload);
replaceClient(updatedClient);
await refreshExportPreview();
formSuccess = 'User access updated.';
toast.dismiss(tid);
toast.success('User access updated');
} catch (error) {
formError = error instanceof Error ? error.message : 'Unable to update client user';
toast.dismiss(tid);
toast.error(error instanceof Error ? error.message : 'Unable to update client user');
} finally {
savingUserId = null;
}
@@ -116,16 +118,16 @@
async function toggleFeature(feature: ClientAccessFeature) {
savingFeatureId = feature.id;
formError = '';
formSuccess = '';
const tid = toast.loading('Updating feature…');
try {
const updatedClient = await api.updateClientFeature(feature.id, { enabled: !feature.enabled });
replaceClient(updatedClient);
await refreshExportPreview();
formSuccess = `${feature.feature_name} ${feature.enabled ? 'disabled' : 'enabled'}.`;
toast.dismiss(tid);
toast.success(`${feature.feature_name} ${feature.enabled ? 'disabled' : 'enabled'}`);
} catch (error) {
formError = error instanceof Error ? error.message : 'Unable to update feature access';
toast.dismiss(tid);
toast.error(error instanceof Error ? error.message : 'Unable to update feature access');
} finally {
savingFeatureId = null;
}
@@ -596,7 +598,7 @@
flex-shrink: 0;
border-radius: 0.8rem;
color: #fff;
background: linear-gradient(135deg, var(--green) 0%, var(--green-deep) 100%);
background: var(--color-brand);
font-size: 0.76rem;
font-weight: 700;
letter-spacing: 0.04em;
@@ -682,8 +684,8 @@
border-radius: 0.85rem;
padding: 0.85rem 1rem;
color: #fff;
background: linear-gradient(135deg, var(--green) 0%, var(--green-deep) 100%);
box-shadow: 0 8px 20px rgba(34, 169, 94, 0.2);
background: var(--color-brand);
box-shadow: none;
font-weight: 600;
cursor: pointer;
}
@@ -795,7 +797,7 @@
.feature-toggle.enabled {
color: #fff;
border-color: transparent;
background: linear-gradient(135deg, var(--green) 0%, var(--green-deep) 100%);
background: var(--color-brand);
}
.feature-toggle:disabled {