9eec21a5b2
Backend API (38 routes): - providers: full CRUD + test connection + list collections + API key masking - trackers: full CRUD + trigger + history + test-periodic/memory - tracking-configs: full CRUD with Pydantic models, provider_type filter - template-configs: full CRUD + preview + preview-raw with two-pass validation - targets: full CRUD + test notification + config masking - telegram-bots: full CRUD + chat discovery + token endpoint - users: full admin CRUD + password reset + self-delete protection - status: dashboard endpoint with providers/trackers/targets/events counts Frontend pages updated: - Dashboard with animated stat cards and event timeline - Providers with proper components, delete confirm, snackbar - Trackers/targets/tracking-configs/template-configs/telegram-bots/users all use PageHeader, Card, Loading, MdiIcon with correct i18n keys Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
52 lines
1.7 KiB
Svelte
52 lines
1.7 KiB
Svelte
<script lang="ts">
|
|
import { onMount } from 'svelte';
|
|
import { api } from '$lib/api';
|
|
import { t } from '$lib/i18n';
|
|
import PageHeader from '$lib/components/PageHeader.svelte';
|
|
import Card from '$lib/components/Card.svelte';
|
|
import Loading from '$lib/components/Loading.svelte';
|
|
import MdiIcon from '$lib/components/MdiIcon.svelte';
|
|
|
|
let configs = $state<any[]>([]);
|
|
let loaded = $state(false);
|
|
|
|
onMount(async () => {
|
|
try { configs = await api('/template-configs'); } catch {}
|
|
loaded = true;
|
|
});
|
|
</script>
|
|
|
|
<PageHeader title={t('templateConfig.title')} description={t('templateConfig.description')} />
|
|
|
|
{#if !loaded}
|
|
<Loading />
|
|
{:else if configs.length === 0}
|
|
<Card>
|
|
<div class="flex flex-col items-center py-8 gap-3" style="color: var(--color-muted-foreground);">
|
|
<div style="opacity: 0.4;"><MdiIcon name="mdiFileDocumentEdit" size={40} /></div>
|
|
<p class="text-sm">{t('templateConfig.noConfigs')}</p>
|
|
</div>
|
|
</Card>
|
|
{:else}
|
|
<div class="grid gap-4 sm:grid-cols-2 stagger-children">
|
|
{#each configs as config}
|
|
<Card hover>
|
|
<div class="flex items-center gap-3">
|
|
<div class="flex items-center justify-center w-10 h-10 rounded-lg"
|
|
style="background: var(--color-accent); color: var(--color-accent-foreground);">
|
|
<MdiIcon name={config.icon || 'mdiFileDocumentEdit'} size={20} />
|
|
</div>
|
|
<div>
|
|
<h3 class="font-medium text-sm">{config.name}</h3>
|
|
<p class="text-xs" style="color: var(--color-muted-foreground);">{config.description || config.provider_type}</p>
|
|
</div>
|
|
{#if config.user_id === 0}
|
|
<span class="ml-auto text-xs px-2 py-0.5 rounded-full"
|
|
style="background: var(--color-muted); color: var(--color-muted-foreground);">System</span>
|
|
{/if}
|
|
</div>
|
|
</Card>
|
|
{/each}
|
|
</div>
|
|
{/if}
|