@svadmin/lite 0.3.4 → 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/package.json +7 -4
  2. package/src/components/LiteAlert.svelte +0 -19
  3. package/src/components/LiteArrayField.svelte +0 -113
  4. package/src/components/LiteAuditLog.svelte +0 -104
  5. package/src/components/LiteBreadcrumbs.svelte +0 -39
  6. package/src/components/LiteChatDialog.svelte +0 -101
  7. package/src/components/LiteConfirmDialog.svelte +0 -60
  8. package/src/components/LiteEmptyState.svelte +0 -39
  9. package/src/components/LiteForm.svelte +0 -138
  10. package/src/components/LiteLayout.svelte +0 -106
  11. package/src/components/LiteLogin.svelte +0 -41
  12. package/src/components/LitePagination.svelte +0 -73
  13. package/src/components/LitePermissionMatrix.svelte +0 -147
  14. package/src/components/LiteSearch.svelte +0 -41
  15. package/src/components/LiteShow.svelte +0 -61
  16. package/src/components/LiteShowField.svelte +0 -51
  17. package/src/components/LiteStatsCard.svelte +0 -70
  18. package/src/components/LiteTable.svelte +0 -132
  19. package/src/components/LiteTabs.svelte +0 -57
  20. package/src/components/advanced/LiteAutoSaveIndicator.svelte +0 -26
  21. package/src/components/advanced/LiteDraggableHeader.svelte +0 -33
  22. package/src/components/advanced/LiteDrawerForm.svelte +0 -42
  23. package/src/components/advanced/LiteInlineEdit.svelte +0 -32
  24. package/src/components/advanced/LiteModalForm.svelte +0 -44
  25. package/src/components/advanced/LiteToast.svelte +0 -34
  26. package/src/components/advanced/LiteUndoableNotification.svelte +0 -25
  27. package/src/components/advanced/LiteVirtualTable.svelte +0 -44
  28. package/src/components/buttons/LiteCloneButton.svelte +0 -33
  29. package/src/components/buttons/LiteCreateButton.svelte +0 -31
  30. package/src/components/buttons/LiteDeleteButton.svelte +0 -57
  31. package/src/components/buttons/LiteEditButton.svelte +0 -33
  32. package/src/components/buttons/LiteExportButton.svelte +0 -31
  33. package/src/components/buttons/LiteImportButton.svelte +0 -50
  34. package/src/components/buttons/LiteListButton.svelte +0 -31
  35. package/src/components/buttons/LiteRefreshButton.svelte +0 -27
  36. package/src/components/buttons/LiteSaveButton.svelte +0 -27
  37. package/src/components/buttons/LiteShowButton.svelte +0 -33
  38. package/src/components/fields/LiteBooleanField.svelte +0 -41
  39. package/src/components/fields/LiteDateField.svelte +0 -51
  40. package/src/components/fields/LiteEmailField.svelte +0 -40
  41. package/src/components/fields/LiteFileField.svelte +0 -53
  42. package/src/components/fields/LiteImageField.svelte +0 -57
  43. package/src/components/fields/LiteJsonField.svelte +0 -43
  44. package/src/components/fields/LiteMarkdownField.svelte +0 -33
  45. package/src/components/fields/LiteMultiSelectField.svelte +0 -57
  46. package/src/components/fields/LiteNumberField.svelte +0 -34
  47. package/src/components/fields/LiteRelationField.svelte +0 -66
  48. package/src/components/fields/LiteRichTextField.svelte +0 -45
  49. package/src/components/fields/LiteSelectField.svelte +0 -47
  50. package/src/components/fields/LiteTagField.svelte +0 -44
  51. package/src/components/fields/LiteTextField.svelte +0 -34
  52. package/src/components/fields/LiteUrlField.svelte +0 -40
  53. package/src/components/layout/LiteAuthenticated.svelte +0 -23
  54. package/src/components/layout/LiteCanAccess.svelte +0 -27
  55. package/src/components/layout/LiteCatchAllNavigate.svelte +0 -20
  56. package/src/components/layout/LiteErrorBoundary.svelte +0 -20
  57. package/src/components/layout/LiteErrorComponent.svelte +0 -37
  58. package/src/components/layout/LiteHeader.svelte +0 -19
  59. package/src/components/layout/LiteNavigateToResource.svelte +0 -25
  60. package/src/components/layout/LiteSidebar.svelte +0 -93
  61. package/src/components/pages/LiteCreatePage.svelte +0 -39
  62. package/src/components/pages/LiteEditPage.svelte +0 -54
  63. package/src/components/pages/LiteForgotPasswordPage.svelte +0 -60
  64. package/src/components/pages/LiteListPage.svelte +0 -81
  65. package/src/components/pages/LiteProfilePage.svelte +0 -61
  66. package/src/components/pages/LiteRegisterPage.svelte +0 -64
  67. package/src/components/pages/LiteShowPage.svelte +0 -61
  68. package/src/components/pages/LiteUpdatePasswordPage.svelte +0 -51
  69. package/src/components/widgets/LiteAnomalyBadge.svelte +0 -40
  70. package/src/components/widgets/LiteBarChart.svelte +0 -45
  71. package/src/components/widgets/LiteInsightCard.svelte +0 -28
  72. package/src/components/widgets/LiteLineChart.svelte +0 -48
  73. package/src/components/widgets/LitePieChart.svelte +0 -44
  74. package/src/lite.css +0 -708
  75. package/static/enhance.js +0 -56
@@ -1,45 +0,0 @@
1
- <script lang="ts">
2
- import type { FieldDefinition } from '@svadmin/core';
3
-
4
- interface Props {
5
- field: FieldDefinition;
6
- value?: unknown;
7
- error?: string[];
8
- mode?: 'show' | 'edit' | 'create';
9
- }
10
-
11
- let { field, value, error = [], mode = 'show' }: Props = $props();
12
- let hasError = $derived(error.length > 0);
13
-
14
- </script>
15
-
16
- {#if mode === 'show'}
17
- <!-- SSR fallback for rich text: render raw HTML if safe, or escaped.
18
- We use standard HTML output for SSR. If it includes scripts,
19
- backend should have sanitized it. -->
20
- <div style="padding: 16px; border: 1px solid #e2e8f0; border-radius: 6px; max-height: 500px; overflow-y: auto; background: #fff;" class="prose">
21
- {@html String(value ?? '—')}
22
- </div>
23
- {:else}
24
- <div class="lite-markdown-editor">
25
- <div style="padding: 8px 12px; border: 1px solid #cbd5e1; border-bottom: none; border-radius: 6px 6px 0 0; background: #f8fafc; color: #64748b; font-size: 12px; display: flex; gap: 12px; font-weight: 500;">
26
- <span>Markdown is supported</span>
27
- <span style="color: #94a3b8;">**bold**</span>
28
- <span style="color: #94a3b8; font-style: italic;">*italic*</span>
29
- <span style="color: #94a3b8;"># heading</span>
30
- </div>
31
- <textarea
32
- name={field.key}
33
- id={field.key}
34
- class="lite-input {hasError ? 'lite-input-error' : ''}"
35
- style="min-height: 280px; font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace; font-size: 13px; line-height: 1.6; padding: 16px; border-radius: 0 0 6px 6px; resize: vertical;"
36
- placeholder="Wait... Rich Text Editor is disabled in lite mode.&#10;&#10;You can write standard HTML or use Markdown syntax here. Content will be safely rendered on the server."
37
- {...field.required ? { required: true } : {}}
38
- >{String(value ?? '')}</textarea>
39
- {#if hasError}
40
- {#each error as err}
41
- <div class="lite-error-text">{err}</div>
42
- {/each}
43
- {/if}
44
- </div>
45
- {/if}
@@ -1,47 +0,0 @@
1
- <script lang="ts">
2
- import type { FieldDefinition } from '@svadmin/core';
3
- import { t } from '@svadmin/core/i18n';
4
-
5
- interface Props {
6
- field: FieldDefinition;
7
- value?: unknown;
8
- error?: string[];
9
- mode?: 'show' | 'edit' | 'create';
10
- }
11
-
12
- let { field, value, error = [], mode = 'show' }: Props = $props();
13
- let hasError = $derived(error.length > 0);
14
-
15
- function displaySelect(v: unknown): string {
16
- if (v == null) return '—';
17
- const opt = field.options?.find(o => String(o.value) === String(v));
18
- return opt?.label ?? String(v);
19
- }
20
- </script>
21
-
22
- {#if mode === 'show'}
23
- <span class="lite-badge">{displaySelect(value)}</span>
24
- {:else}
25
- <div>
26
- <select
27
- name={field.key}
28
- id={field.key}
29
- class="lite-select {hasError ? 'lite-input-error' : ''}"
30
- {...field.required ? { required: true } : {}}
31
- >
32
- <option value="">-- {t('common.select') || 'Select'} --</option>
33
- {#if field.options}
34
- {#each field.options as opt}
35
- <option value={String(opt.value)} selected={String(value) === String(opt.value)}>
36
- {opt.label}
37
- </option>
38
- {/each}
39
- {/if}
40
- </select>
41
- {#if hasError}
42
- {#each error as err}
43
- <div class="lite-error-text">{err}</div>
44
- {/each}
45
- {/if}
46
- </div>
47
- {/if}
@@ -1,44 +0,0 @@
1
- <script lang="ts">
2
- import type { FieldDefinition } from '@svadmin/core';
3
-
4
- interface Props {
5
- field: FieldDefinition;
6
- value?: unknown;
7
- error?: string[];
8
- mode?: 'show' | 'edit' | 'create';
9
- }
10
-
11
- let { field, value, error = [], mode = 'show' }: Props = $props();
12
- let hasError = $derived(error.length > 0);
13
- const tags = $derived(Array.isArray(value) ? value.map(String) : []);
14
- </script>
15
-
16
- {#if mode === 'show'}
17
- <div style="display:flex; gap: 4px; flex-wrap: wrap;">
18
- {#each tags as tag}
19
- <span class="lite-badge">{tag}</span>
20
- {:else}
21
- <span>—</span>
22
- {/each}
23
- </div>
24
- {:else}
25
- <div>
26
- <!-- For SSR without JS, we just accept a comma-separated string -->
27
- <input
28
- type="text"
29
- name={field.key}
30
- id={field.key}
31
- value={tags.join(', ')}
32
- class="lite-input {hasError ? 'lite-input-error' : ''}"
33
- placeholder="Comma separated tags (e.g. admin, user, internal)"
34
- />
35
- <span style="font-size: 11px; color: #6b7280; display: block; margin-top: 4px;">
36
- Separate tags with commas.
37
- </span>
38
- {#if hasError}
39
- {#each error as err}
40
- <div class="lite-error-text">{err}</div>
41
- {/each}
42
- {/if}
43
- </div>
44
- {/if}
@@ -1,34 +0,0 @@
1
- <script lang="ts">
2
- import type { FieldDefinition } from '@svadmin/core';
3
-
4
- interface Props {
5
- field: FieldDefinition;
6
- value?: unknown;
7
- error?: string[];
8
- mode?: 'show' | 'edit' | 'create';
9
- }
10
-
11
- let { field, value, error = [], mode = 'show' }: Props = $props();
12
- let hasError = $derived(error.length > 0);
13
- </script>
14
-
15
- {#if mode === 'show'}
16
- <span>{value == null ? '—' : String(value)}</span>
17
- {:else}
18
- <div>
19
- <input
20
- type="text"
21
- name={field.key}
22
- id={field.key}
23
- value={String(value ?? '')}
24
- class="lite-input {hasError ? 'lite-input-error' : ''}"
25
- placeholder={(field as any).placeholder ?? field.label}
26
- {...field.required ? { required: true } : {}}
27
- />
28
- {#if hasError}
29
- {#each error as err}
30
- <div class="lite-error-text">{err}</div>
31
- {/each}
32
- {/if}
33
- </div>
34
- {/if}
@@ -1,40 +0,0 @@
1
- <script lang="ts">
2
- import type { FieldDefinition } from '@svadmin/core';
3
-
4
- interface Props {
5
- field: FieldDefinition;
6
- value?: unknown;
7
- error?: string[];
8
- mode?: 'show' | 'edit' | 'create';
9
- }
10
-
11
- let { field, value, error = [], mode = 'show' }: Props = $props();
12
- let hasError = $derived(error.length > 0);
13
- </script>
14
-
15
- {#if mode === 'show'}
16
- <span>
17
- {#if value}
18
- <a href="{String(value)}" target="_blank" rel="noopener noreferrer">{value}</a>
19
- {:else}
20
-
21
- {/if}
22
- </span>
23
- {:else}
24
- <div>
25
- <input
26
- type="url"
27
- name={field.key}
28
- id={field.key}
29
- value={String(value ?? '')}
30
- class="lite-input {hasError ? 'lite-input-error' : ''}"
31
- placeholder={(field as any).placeholder ?? field.label}
32
- {...field.required ? { required: true } : {}}
33
- />
34
- {#if hasError}
35
- {#each error as err}
36
- <div class="lite-error-text">{err}</div>
37
- {/each}
38
- {/if}
39
- </div>
40
- {/if}
@@ -1,23 +0,0 @@
1
- <script lang="ts">
2
- import type { Snippet } from 'svelte';
3
-
4
- interface Props {
5
- /** True if server layout load confirms authentication */
6
- isAuthenticated?: boolean;
7
- loginUrl?: string;
8
- children?: Snippet;
9
- }
10
-
11
- let { isAuthenticated = false, loginUrl = '/lite/login', children }: Props = $props();
12
- </script>
13
-
14
- {#if isAuthenticated}
15
- {#if children}
16
- {@render children()}
17
- {/if}
18
- {:else}
19
- <div style="padding: 40px; text-align: center; color: #475569;">
20
- <h2>Authentication Required</h2>
21
- <p>Please <a href={loginUrl} style="color: #2563eb;">login here</a> to access this page.</p>
22
- </div>
23
- {/if}
@@ -1,27 +0,0 @@
1
- <script lang="ts">
2
- import type { Snippet } from 'svelte';
3
-
4
- interface Props {
5
- /** Whether the user has access (computed from server load function) */
6
- allowed: boolean;
7
- children?: Snippet;
8
- fallback?: Snippet;
9
- }
10
-
11
- let { allowed, children, fallback }: Props = $props();
12
- </script>
13
-
14
- {#if allowed}
15
- {#if children}
16
- {@render children()}
17
- {/if}
18
- {:else}
19
- {#if fallback}
20
- {@render fallback()}
21
- {:else}
22
- <div style="padding: 24px; background: #fff1f2; color: #be123c; border-radius: 6px; border: 1px solid #fecdd3;">
23
- <h3>Access Denied</h3>
24
- <p>You do not have permission to view this content.</p>
25
- </div>
26
- {/if}
27
- {/if}
@@ -1,20 +0,0 @@
1
- <script lang="ts">
2
- import { onMount } from 'svelte';
3
-
4
- interface Props {
5
- basePath?: string;
6
- defaultResource?: string;
7
- }
8
-
9
- let { basePath = '/lite', defaultResource = '' }: Props = $props();
10
- const target = $derived(`${basePath}${defaultResource ? '/' + defaultResource : ''}`);
11
-
12
- onMount(() => {
13
- window.location.href = target;
14
- });
15
- </script>
16
-
17
- <noscript>
18
- <meta http-equiv="refresh" content={`0; url=${target}`} />
19
- </noscript>
20
- <p>Redirecting...</p>
@@ -1,20 +0,0 @@
1
- <script lang="ts">
2
- /**
3
- * SSR Error Boundary.
4
- * Since native Svelte <svelte:boundary> relies on CSR to catch JS exceptions,
5
- * this component delegates error handling upstream to the SvelteKit +error.svelte mechanism.
6
- * In CSR disabled environments, returning just the slot is standard practice.
7
- */
8
- import type { Snippet } from 'svelte';
9
-
10
- interface Props {
11
- children?: Snippet;
12
- }
13
-
14
- let { children }: Props = $props();
15
- </script>
16
-
17
- <!-- The error interception must be handled by the backend SSR framework (e.g. SvelteKit) -->
18
- {#if children}
19
- {@render children()}
20
- {/if}
@@ -1,37 +0,0 @@
1
- <script lang="ts">
2
- import { t } from '@svadmin/core/i18n';
3
- import { AlertTriangle } from '@lucide/svelte';
4
-
5
- interface Props {
6
- title?: string;
7
- message?: string;
8
- code?: string | number;
9
- homeUrl?: string;
10
- }
11
-
12
- let {
13
- title = 'An error occurred',
14
- message = 'Something went wrong while processing your request.',
15
- code = 500,
16
- homeUrl = '/lite',
17
- }: Props = $props();
18
- </script>
19
-
20
- <div style="min-height: 50vh; display: flex; align-items: center; justify-content: center; padding: 20px;">
21
- <div class="lite-card" style="max-width: 480px; width: 100%; text-align: center; padding: 40px;">
22
- <AlertTriangle style="width: 48px; height: 48px; color: #ef4444; margin: 0 auto 16px;" />
23
-
24
- <h1 style="font-size: 24px; font-weight: 600; color: #0f172a; margin: 0 0 8px;">
25
- {#if code}
26
- <span style="color: #ef4444; margin-right: 8px;">{code}</span>
27
- {/if}
28
- {title}
29
- </h1>
30
-
31
- <p style="color: #64748b; font-size: 15px; margin: 0 0 24px; line-height: 1.5;">{message}</p>
32
-
33
- <a href={homeUrl} class="lite-btn lite-btn-primary" style="display: inline-block;">
34
- {t('common.returnHome') || 'Return to Home'}
35
- </a>
36
- </div>
37
- </div>
@@ -1,19 +0,0 @@
1
- <script lang="ts">
2
- import type { Snippet } from 'svelte';
3
-
4
- interface Props {
5
- title?: string;
6
- children?: Snippet;
7
- }
8
-
9
- let { title = '', children }: Props = $props();
10
- </script>
11
-
12
- <header class="lite-header" style="padding: 16px 24px; background: white; border-bottom: 1px solid #e2e8f0; display: flex; justify-content: space-between; align-items: center;">
13
- <h2 style="margin: 0; font-size: 18px; font-weight: 600; color: #0f172a;">{title}</h2>
14
- <div style="display: flex; gap: 12px; align-items: center;">
15
- {#if children}
16
- {@render children()}
17
- {/if}
18
- </div>
19
- </header>
@@ -1,25 +0,0 @@
1
- <script lang="ts">
2
- /**
3
- * SSR redirection helper component
4
- * Normally redirection is done via +page.server.ts load() function in SvelteKit.
5
- * This component will do a client-side fallback redirect if rendered.
6
- */
7
- import { onMount } from 'svelte';
8
-
9
- interface Props {
10
- resource: string;
11
- basePath?: string;
12
- }
13
-
14
- let { resource, basePath = '/lite' }: Props = $props();
15
-
16
- onMount(() => {
17
- // Only fires if JS somehow runs, otherwise server should have redirected.
18
- window.location.href = `${basePath}/${resource}`;
19
- });
20
- </script>
21
-
22
- <noscript>
23
- <meta http-equiv="refresh" content={`0; url=${basePath}/${resource}`} />
24
- </noscript>
25
- <p>Redirecting to {resource}...</p>
@@ -1,93 +0,0 @@
1
- <script lang="ts">
2
- import type { ResourceDefinition, MenuItem } from '@svadmin/core';
3
-
4
- interface Props {
5
- resources: ResourceDefinition[];
6
- currentResource?: string;
7
- brandName?: string;
8
- userName?: string;
9
- basePath?: string;
10
- menu?: MenuItem[];
11
- }
12
-
13
- let {
14
- resources,
15
- currentResource = '',
16
- brandName = 'Admin',
17
- userName = '',
18
- basePath = '/lite',
19
- menu,
20
- }: Props = $props();
21
-
22
- const menuResources = $derived(
23
- resources.filter((r: ResourceDefinition) => r.showInMenu !== false)
24
- );
25
-
26
- function isActive(href: string | undefined): boolean {
27
- if (!href) return false;
28
- return currentResource === href.replace(basePath + '/', '');
29
- }
30
-
31
- function hasActiveChild(children?: MenuItem[]): boolean {
32
- if (!children) return false;
33
- return children.some(c => isActive(c.href ?? `${basePath}/${c.name}`));
34
- }
35
- </script>
36
-
37
- <nav class="lite-sidebar">
38
- <div class="lite-sidebar-brand">{brandName}</div>
39
- {#if menu && menu.length > 0}
40
- {#each menu as item}
41
- {#if item.children && item.children.length > 0}
42
- <details class="lite-menu-group" open={hasActiveChild(item.children)}>
43
- <summary class="lite-menu-parent">{item.label ?? item.name}</summary>
44
- {#each item.children as child}
45
- {#if child.children && child.children.length > 0}
46
- <details class="lite-menu-group" style="margin-left:12px" open={hasActiveChild(child.children)}>
47
- <summary class="lite-menu-parent">{child.label ?? child.name}</summary>
48
- {#each child.children as grandchild}
49
- <a
50
- href={grandchild.href ?? `${basePath}/${grandchild.name}`}
51
- class={isActive(grandchild.href ?? `${basePath}/${grandchild.name}`) ? 'active' : ''}
52
- target={grandchild.target === '_blank' ? '_blank' : undefined}
53
- style="padding-left:40px"
54
- >{grandchild.label ?? grandchild.name}</a>
55
- {/each}
56
- </details>
57
- {:else}
58
- <a
59
- href={child.href ?? `${basePath}/${child.name}`}
60
- class={isActive(child.href ?? `${basePath}/${child.name}`) ? 'active' : ''}
61
- target={child.target === '_blank' ? '_blank' : undefined}
62
- style="padding-left:28px"
63
- >{child.label ?? child.name}</a>
64
- {/if}
65
- {/each}
66
- </details>
67
- {:else}
68
- <a
69
- href={item.href ?? `${basePath}/${item.name}`}
70
- class={isActive(item.href ?? `${basePath}/${item.name}`) ? 'active' : ''}
71
- target={item.target === '_blank' ? '_blank' : undefined}
72
- >{item.label ?? item.name}</a>
73
- {/if}
74
- {/each}
75
- {:else}
76
- {#each menuResources as res}
77
- <a
78
- href={`${basePath}/${res.name}`}
79
- class={res.name === currentResource ? 'active' : ''}
80
- >
81
- {res.label ?? res.name}
82
- </a>
83
- {/each}
84
- {/if}
85
- {#if userName}
86
- <div style="position:absolute;bottom:0;left:0;right:0;padding:12px 16px;border-top:1px solid #334155;font-size:12px;color:#94a3b8;">
87
- {userName}
88
- <form method="POST" action={`${basePath}/login?/logout`} style="display:inline;margin-left:8px;">
89
- <button type="submit" class="lite-btn lite-btn-sm" style="color:#94a3b8;border-color:#475569;background:transparent;padding:2px 8px;">Logout</button>
90
- </form>
91
- </div>
92
- {/if}
93
- </nav>
@@ -1,39 +0,0 @@
1
- <script lang="ts">
2
- import type { ResourceDefinition } from '@svadmin/core';
3
- import { t } from '@svadmin/core/i18n';
4
- import LiteForm from '../LiteForm.svelte';
5
- import LiteListButton from '../buttons/LiteListButton.svelte';
6
-
7
- interface Props {
8
- resource: ResourceDefinition;
9
- errors?: Record<string, string[]>;
10
- values?: Record<string, unknown>;
11
- basePath?: string;
12
- }
13
-
14
- let {
15
- resource,
16
- errors = {},
17
- values = {},
18
- basePath = '/lite',
19
- }: Props = $props();
20
- </script>
21
-
22
- <div class="lite-page">
23
- <div class="lite-page-header">
24
- <h1 class="lite-page-title">{t('common.create') || 'Create'} {resource.label || resource.name}</h1>
25
- <div class="lite-page-actions">
26
- <LiteListButton resource={resource.name} {basePath} />
27
- </div>
28
- </div>
29
-
30
- <LiteForm
31
- fields={resource.fields}
32
- mode="create"
33
- {resource}
34
- {errors}
35
- {values}
36
- action="?/create"
37
- cancelUrl={`${basePath}/${resource.name}`}
38
- />
39
- </div>
@@ -1,54 +0,0 @@
1
- <script lang="ts">
2
- import type { ResourceDefinition } from '@svadmin/core';
3
- import { t } from '@svadmin/core/i18n';
4
- import LiteForm from '../LiteForm.svelte';
5
- import LiteListButton from '../buttons/LiteListButton.svelte';
6
- import LiteShowButton from '../buttons/LiteShowButton.svelte';
7
- import LiteDeleteButton from '../buttons/LiteDeleteButton.svelte';
8
-
9
- interface Props {
10
- resource: ResourceDefinition;
11
- record: Record<string, unknown>;
12
- errors?: Record<string, string[]>;
13
- basePath?: string;
14
- canDelete?: boolean;
15
- canShow?: boolean;
16
- }
17
-
18
- let {
19
- resource,
20
- record,
21
- errors = {},
22
- basePath = '/lite',
23
- canDelete = true,
24
- canShow = true,
25
- }: Props = $props();
26
-
27
- let pk = $derived(resource.primaryKey ?? 'id');
28
- let idStr = $derived(String(record[pk]));
29
- </script>
30
-
31
- <div class="lite-page">
32
- <div class="lite-page-header">
33
- <h1 class="lite-page-title">{t('common.edit') || 'Edit'} {resource.label || resource.name} #{idStr}</h1>
34
- <div class="lite-page-actions">
35
- {#if canShow}
36
- <LiteShowButton resource={resource.name} recordItemId={idStr} {basePath} />
37
- {/if}
38
- <LiteListButton resource={resource.name} {basePath} />
39
- {#if canDelete}
40
- <LiteDeleteButton resource={resource.name} recordItemId={idStr} redirectUrl={`${basePath}/${resource.name}`} {basePath} />
41
- {/if}
42
- </div>
43
- </div>
44
-
45
- <LiteForm
46
- fields={resource.fields}
47
- mode="edit"
48
- {resource}
49
- {errors}
50
- values={record}
51
- action="?/update"
52
- cancelUrl={`${basePath}/${resource.name}`}
53
- />
54
- </div>
@@ -1,60 +0,0 @@
1
- <script lang="ts">
2
- interface Props {
3
- title?: string;
4
- description?: string;
5
- action?: string;
6
- loginUrl?: string;
7
- errors?: string[];
8
- successMessage?: string;
9
- }
10
-
11
- let {
12
- title = 'Forgot Password',
13
- description = 'Enter your email to receive a password reset link',
14
- action = '?/forgot_password',
15
- loginUrl = '/lite/login',
16
- errors = [],
17
- successMessage = '',
18
- }: Props = $props();
19
- </script>
20
-
21
- <div style="min-height: 100vh; display: flex; align-items: center; justify-content: center; background: #f8fafc; padding: 20px;">
22
- <div class="lite-card" style="width: 100%; max-width: 400px; padding: 32px;">
23
- <div style="text-align: center; margin-bottom: 24px;">
24
- <h1 style="font-size: 24px; font-weight: 600; color: #0f172a; margin: 0 0 8px;">{title}</h1>
25
- <p style="font-size: 14px; color: #64748b; margin: 0;">{description}</p>
26
- </div>
27
-
28
- <!-- Native form action -->
29
- <form method="POST" {action} style="display: flex; flex-direction: column; gap: 16px;">
30
- <div class="lite-form-group">
31
- <label for="email">Email</label>
32
- <input type="email" id="email" name="email" class="lite-input" required />
33
- </div>
34
-
35
- {#if errors.length > 0}
36
- <div style="padding: 12px; background: #fef2f2; border-radius: 6px; color: #ef4444; font-size: 13px;">
37
- <ul style="margin: 0; padding-left: 20px;">
38
- {#each errors as err}
39
- <li>{err}</li>
40
- {/each}
41
- </ul>
42
- </div>
43
- {/if}
44
-
45
- {#if successMessage}
46
- <div style="padding: 12px; background: #ecfdf5; border-radius: 6px; color: #10b981; font-size: 13px;">
47
- {successMessage}
48
- </div>
49
- {/if}
50
-
51
- <button type="submit" class="lite-btn lite-btn-primary" style="width: 100%; justify-content: center; padding: 10px;">
52
- Send Reset Link
53
- </button>
54
-
55
- <div style="text-align: center; font-size: 13px; color: #64748b; margin-top: 8px;">
56
- Remember your password? <a href={loginUrl} style="color: #2563eb; text-decoration: none;">Back to Login</a>
57
- </div>
58
- </form>
59
- </div>
60
- </div>