@svadmin/ui 0.38.7 → 0.39.0
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.
- package/dist/components/AdminApp.svelte +3 -2
- package/dist/components/ApiSettings.svelte +86 -1
- package/dist/components/ForgotPasswordPage.svelte +5 -8
- package/dist/components/LoginPage.svelte +5 -8
- package/dist/components/RegisterPage.svelte +5 -8
- package/dist/components/Sidebar.svelte +10 -4
- package/dist/components/SvadminLogo.svelte +16 -0
- package/dist/components/SvadminLogo.svelte.d.ts +7 -0
- package/dist/components/UpdatePasswordPage.svelte +5 -8
- package/dist/components/account/CompanyProfilePage.svelte +56 -1
- package/dist/components/account/ImportMembersPage.svelte +31 -0
- package/dist/components/account/SettingsEnterprisePage.svelte +172 -19
- package/dist/components/account/SettingsPlainPage.svelte +121 -17
- package/dist/components/account/SettingsSidebarPage.svelte +282 -70
- package/dist/components/account/TeamMembersPage.svelte +68 -2
- package/dist/components/account/UserProfilePage.svelte +206 -0
- package/dist/components/account/UserProfilePage.svelte.d.ts +4 -0
- package/dist/components/network/TeamCrewTablePage.svelte +17 -1
- package/dist/components/network/UserCardsNFTPage.svelte +5 -0
- package/dist/components/profile/ActivityTimeline.svelte +24 -2
- package/dist/components/profile/ActivityTimeline.svelte.d.ts +1 -0
- package/dist/components/profile/ProfileVariantSections.svelte +452 -0
- package/dist/components/profile/ProfileVariantSections.svelte.d.ts +8 -0
- package/dist/components/profile/ProjectsGrid.svelte +20 -6
- package/dist/components/profile/PublicProfilePage.svelte +42 -21
- package/dist/components/profile/PublicProfilePage.svelte.d.ts +1 -0
- package/dist/components/profile/TeamsShowcase.svelte +31 -12
- package/dist/components/profile/TeamsShowcase.svelte.d.ts +1 -0
- package/dist/components/ui/alert/alert.svelte.d.ts +14 -14
- package/dist/components/ui/avatar/avatar.svelte.d.ts +14 -14
- package/dist/components/ui/badge/badge.svelte.d.ts +20 -20
- package/dist/components/ui/button/button.svelte.d.ts +44 -44
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/package.json +13 -13
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { useTranslation } from '@svadmin/core/i18n';
|
|
3
|
+
import * as Card from '../ui/card/index.js';
|
|
4
|
+
import { Badge } from '../ui/badge/index.js';
|
|
5
|
+
import { Button } from '../ui/button/index.js';
|
|
6
|
+
import { Switch } from '../ui/switch/index.js';
|
|
7
|
+
import {
|
|
8
|
+
Briefcase, Calendar, FileText, Image, FileArchive, Link2, Loader2,
|
|
9
|
+
Star, Award, Medal, Crown,
|
|
10
|
+
} from '@lucide/svelte';
|
|
11
|
+
import type { Component } from 'svelte';
|
|
12
|
+
|
|
13
|
+
const i18n = useTranslation();
|
|
14
|
+
|
|
15
|
+
let availableToHire = $state(true);
|
|
16
|
+
let saving = $state(false);
|
|
17
|
+
|
|
18
|
+
async function handleSave() {
|
|
19
|
+
saving = true;
|
|
20
|
+
await new Promise((r) => setTimeout(r, 800));
|
|
21
|
+
saving = false;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const infoRows = [
|
|
25
|
+
{ label: 'profile.name', value: 'Alex Chen' },
|
|
26
|
+
{ label: 'account.phone', value: '+86 138 **** 9527' },
|
|
27
|
+
{ label: 'account.dateOfBirth', value: '1995-04-18' },
|
|
28
|
+
{ label: 'account.address', value: 'Shanghai, CN' },
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
const badges: { name: string; Icon: Component; tone: string }[] = [
|
|
32
|
+
{ name: 'Top Contributor', Icon: Medal, tone: 'bg-amber-500/10 text-amber-600' },
|
|
33
|
+
{ name: 'Early Adopter', Icon: Star, tone: 'bg-blue-500/10 text-blue-600' },
|
|
34
|
+
{ name: 'Community Mentor', Icon: Award, tone: 'bg-violet-500/10 text-violet-600' },
|
|
35
|
+
{ name: 'Launch Partner', Icon: Crown, tone: 'bg-emerald-500/10 text-emerald-600' },
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
interface Connection {
|
|
39
|
+
id: string;
|
|
40
|
+
name: string;
|
|
41
|
+
detail: string;
|
|
42
|
+
connected: boolean;
|
|
43
|
+
}
|
|
44
|
+
let connections = $state<Connection[]>([
|
|
45
|
+
{ id: 'repo', name: 'Source Control', detail: 'alexchen', connected: true },
|
|
46
|
+
{ id: 'chat', name: 'ChatOps', detail: '@alex.chen', connected: true },
|
|
47
|
+
{ id: 'drive', name: 'Cloud Drive', detail: 'alex@example.com', connected: false },
|
|
48
|
+
]);
|
|
49
|
+
|
|
50
|
+
const files: { name: string; size: string; Icon: Component; tone: string }[] = [
|
|
51
|
+
{ name: 'portfolio-2026.pdf', size: '2.1 MB', Icon: FileText, tone: 'bg-red-500/10 text-red-600' },
|
|
52
|
+
{ name: 'avatar-pack.zip', size: '8.4 MB', Icon: FileArchive, tone: 'bg-amber-500/10 text-amber-600' },
|
|
53
|
+
{ name: 'cover-photo.png', size: '1.2 MB', Icon: Image, tone: 'bg-pink-500/10 text-pink-600' },
|
|
54
|
+
];
|
|
55
|
+
|
|
56
|
+
const calendars = [
|
|
57
|
+
{ name: 'Work Calendar', detail: 'alex@nebulalabs.io', primary: true },
|
|
58
|
+
{ name: 'Personal Calendar', detail: 'alex@example.com', primary: false },
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
function toggleConnection(id: string, connected: boolean) {
|
|
62
|
+
connections = connections.map((c) => (c.id === id ? { ...c, connected } : c));
|
|
63
|
+
}
|
|
64
|
+
</script>
|
|
65
|
+
|
|
66
|
+
<div class="space-y-6" data-svadmin-content-page="account">
|
|
67
|
+
<div class="flex items-start justify-between gap-4">
|
|
68
|
+
<div>
|
|
69
|
+
<h2 class="text-xl font-semibold text-foreground">{i18n.t('account.userProfile')}</h2>
|
|
70
|
+
<p class="mt-1 text-sm text-muted-foreground">{i18n.t('account.userProfileDescription')}</p>
|
|
71
|
+
</div>
|
|
72
|
+
<Button onclick={handleSave} disabled={saving} size="sm">
|
|
73
|
+
{#if saving}<Loader2 class="h-4 w-4 animate-spin mr-2" />{/if}
|
|
74
|
+
{i18n.t('common.save')}
|
|
75
|
+
</Button>
|
|
76
|
+
</div>
|
|
77
|
+
|
|
78
|
+
<div class="grid gap-4 lg:grid-cols-3">
|
|
79
|
+
<div class="space-y-4 lg:col-span-2">
|
|
80
|
+
<!-- Personal Info -->
|
|
81
|
+
<Card.Card class="border-border/60">
|
|
82
|
+
<Card.CardHeader class="pb-3">
|
|
83
|
+
<Card.CardTitle class="text-base">{i18n.t('account.personalInfo')}</Card.CardTitle>
|
|
84
|
+
</Card.CardHeader>
|
|
85
|
+
<Card.CardContent class="p-0">
|
|
86
|
+
<div class="divide-y">
|
|
87
|
+
{#each infoRows as row (row.label)}
|
|
88
|
+
<div class="flex items-center justify-between px-6 py-3 text-sm">
|
|
89
|
+
<span class="text-muted-foreground">{i18n.t(row.label)}</span>
|
|
90
|
+
<span class="font-medium text-foreground">{row.value}</span>
|
|
91
|
+
</div>
|
|
92
|
+
{/each}
|
|
93
|
+
</div>
|
|
94
|
+
</Card.CardContent>
|
|
95
|
+
</Card.Card>
|
|
96
|
+
|
|
97
|
+
<!-- Work -->
|
|
98
|
+
<Card.Card class="border-border/60">
|
|
99
|
+
<Card.CardHeader class="pb-3">
|
|
100
|
+
<Card.CardTitle class="flex items-center gap-2 text-base">
|
|
101
|
+
<Briefcase class="h-4 w-4 text-muted-foreground" />{i18n.t('account.work')}
|
|
102
|
+
</Card.CardTitle>
|
|
103
|
+
</Card.CardHeader>
|
|
104
|
+
<Card.CardContent class="space-y-4">
|
|
105
|
+
<div class="flex items-center justify-between gap-4">
|
|
106
|
+
<div class="space-y-1">
|
|
107
|
+
<p class="text-sm font-medium text-foreground">{i18n.t('account.availableToHire')}</p>
|
|
108
|
+
<p class="text-xs text-muted-foreground">{i18n.t('account.availableNow')}</p>
|
|
109
|
+
</div>
|
|
110
|
+
<Switch bind:checked={availableToHire} />
|
|
111
|
+
</div>
|
|
112
|
+
<div class="flex flex-wrap gap-1.5">
|
|
113
|
+
{#each ['TypeScript', 'Svelte', 'Node.js', 'Design Systems'] as skill (skill)}
|
|
114
|
+
<Badge variant="secondary" class="text-xs">{skill}</Badge>
|
|
115
|
+
{/each}
|
|
116
|
+
</div>
|
|
117
|
+
</Card.CardContent>
|
|
118
|
+
</Card.Card>
|
|
119
|
+
|
|
120
|
+
<!-- Connections -->
|
|
121
|
+
<Card.Card class="border-border/60">
|
|
122
|
+
<Card.CardHeader class="pb-3">
|
|
123
|
+
<Card.CardTitle class="flex items-center gap-2 text-base">
|
|
124
|
+
<Link2 class="h-4 w-4 text-muted-foreground" />{i18n.t('account.connections')}
|
|
125
|
+
</Card.CardTitle>
|
|
126
|
+
</Card.CardHeader>
|
|
127
|
+
<Card.CardContent class="p-0">
|
|
128
|
+
<div class="divide-y">
|
|
129
|
+
{#each connections as conn (conn.id)}
|
|
130
|
+
<div class="flex items-center justify-between gap-4 px-6 py-3">
|
|
131
|
+
<div class="min-w-0">
|
|
132
|
+
<p class="text-sm font-medium text-foreground">{conn.name}</p>
|
|
133
|
+
<p class="truncate text-xs text-muted-foreground">{conn.detail}</p>
|
|
134
|
+
</div>
|
|
135
|
+
<Switch checked={conn.connected} onCheckedChange={(checked) => toggleConnection(conn.id, checked)} />
|
|
136
|
+
</div>
|
|
137
|
+
{/each}
|
|
138
|
+
</div>
|
|
139
|
+
</Card.CardContent>
|
|
140
|
+
</Card.Card>
|
|
141
|
+
</div>
|
|
142
|
+
|
|
143
|
+
<div class="space-y-4">
|
|
144
|
+
<!-- Badges -->
|
|
145
|
+
<Card.Card class="border-border/60">
|
|
146
|
+
<Card.CardHeader class="pb-3">
|
|
147
|
+
<Card.CardTitle class="text-base">{i18n.t('account.badges')}</Card.CardTitle>
|
|
148
|
+
</Card.CardHeader>
|
|
149
|
+
<Card.CardContent>
|
|
150
|
+
<div class="grid grid-cols-2 gap-2">
|
|
151
|
+
{#each badges as badge (badge.name)}
|
|
152
|
+
<div class="flex items-center gap-2 rounded-lg border border-border/60 p-2.5">
|
|
153
|
+
<div class="flex h-8 w-8 shrink-0 items-center justify-center rounded-lg {badge.tone}">
|
|
154
|
+
<badge.Icon class="h-4 w-4" />
|
|
155
|
+
</div>
|
|
156
|
+
<span class="text-xs font-medium text-foreground">{badge.name}</span>
|
|
157
|
+
</div>
|
|
158
|
+
{/each}
|
|
159
|
+
</div>
|
|
160
|
+
</Card.CardContent>
|
|
161
|
+
</Card.Card>
|
|
162
|
+
|
|
163
|
+
<!-- Calendar Accounts -->
|
|
164
|
+
<Card.Card class="border-border/60">
|
|
165
|
+
<Card.CardHeader class="pb-3">
|
|
166
|
+
<Card.CardTitle class="flex items-center gap-2 text-base">
|
|
167
|
+
<Calendar class="h-4 w-4 text-muted-foreground" />{i18n.t('account.calendarAccounts')}
|
|
168
|
+
</Card.CardTitle>
|
|
169
|
+
</Card.CardHeader>
|
|
170
|
+
<Card.CardContent class="space-y-3">
|
|
171
|
+
{#each calendars as cal (cal.name)}
|
|
172
|
+
<div class="flex items-center justify-between gap-2">
|
|
173
|
+
<div class="min-w-0">
|
|
174
|
+
<p class="truncate text-sm font-medium text-foreground">{cal.name}</p>
|
|
175
|
+
<p class="truncate text-xs text-muted-foreground">{cal.detail}</p>
|
|
176
|
+
</div>
|
|
177
|
+
{#if cal.primary}
|
|
178
|
+
<Badge variant="secondary" class="shrink-0 text-[10px]">{i18n.t('account.active')}</Badge>
|
|
179
|
+
{/if}
|
|
180
|
+
</div>
|
|
181
|
+
{/each}
|
|
182
|
+
</Card.CardContent>
|
|
183
|
+
</Card.Card>
|
|
184
|
+
|
|
185
|
+
<!-- My Files -->
|
|
186
|
+
<Card.Card class="border-border/60">
|
|
187
|
+
<Card.CardHeader class="pb-3">
|
|
188
|
+
<Card.CardTitle class="text-base">{i18n.t('account.myFiles')}</Card.CardTitle>
|
|
189
|
+
</Card.CardHeader>
|
|
190
|
+
<Card.CardContent class="space-y-2.5">
|
|
191
|
+
{#each files as file (file.name)}
|
|
192
|
+
<div class="flex items-center gap-3">
|
|
193
|
+
<div class="flex h-9 w-9 shrink-0 items-center justify-center rounded-lg {file.tone}">
|
|
194
|
+
<file.Icon class="h-4 w-4" />
|
|
195
|
+
</div>
|
|
196
|
+
<div class="min-w-0 flex-1">
|
|
197
|
+
<p class="truncate text-sm font-medium text-foreground">{file.name}</p>
|
|
198
|
+
<p class="text-xs text-muted-foreground">{file.size}</p>
|
|
199
|
+
</div>
|
|
200
|
+
</div>
|
|
201
|
+
{/each}
|
|
202
|
+
</Card.CardContent>
|
|
203
|
+
</Card.Card>
|
|
204
|
+
</div>
|
|
205
|
+
</div>
|
|
206
|
+
</div>
|
|
@@ -30,8 +30,22 @@
|
|
|
30
30
|
{ id: '6', name: 'Emma Davis', email: 'emma@acme.com', role: 'Engineering Manager', department: 'Engineering', status: 'active', joinedAt: '2022-02-14', projects: 15 },
|
|
31
31
|
{ id: '7', name: 'James Wilson', email: 'james@acme.com', role: 'DevOps Engineer', department: 'Infrastructure', status: 'active', joinedAt: '2023-08-01', projects: 7 },
|
|
32
32
|
{ id: '8', name: 'Yuki Tanaka', email: 'yuki@acme.com', role: 'Frontend Engineer', department: 'Engineering', status: 'away', joinedAt: '2023-05-12', projects: 9 },
|
|
33
|
+
{ id: '9', name: 'Priya Nair', email: 'priya@acme.com', role: 'Data Scientist', department: 'Data', status: 'active', joinedAt: '2023-09-18', projects: 5 },
|
|
34
|
+
{ id: '10', name: 'Carlos Mendez', email: 'carlos@acme.com', role: 'Mobile Engineer', department: 'Engineering', status: 'active', joinedAt: '2022-07-25', projects: 11 },
|
|
35
|
+
{ id: '11', name: 'Hana Sato', email: 'hana@acme.com', role: 'UX Researcher', department: 'Design', status: 'away', joinedAt: '2024-01-15', projects: 3 },
|
|
36
|
+
{ id: '12', name: 'Oscar Lund', email: 'oscar@acme.com', role: 'Security Engineer', department: 'Infrastructure', status: 'active', joinedAt: '2023-03-30', projects: 6 },
|
|
37
|
+
{ id: '13', name: 'Mia Torres', email: 'mia@acme.com', role: 'Content Strategist', department: 'Marketing', status: 'offline', joinedAt: '2024-02-11', projects: 2 },
|
|
38
|
+
{ id: '14', name: 'Chen Wei', email: 'chen@acme.com', role: 'Platform Engineer', department: 'Engineering', status: 'active', joinedAt: '2022-10-08', projects: 13 },
|
|
39
|
+
{ id: '15', name: 'Ava Novak', email: 'ava@acme.com', role: 'Product Designer', department: 'Design', status: 'active', joinedAt: '2023-06-19', projects: 7 },
|
|
40
|
+
{ id: '16', name: 'Liam Ortiz', email: 'liam@acme.com', role: 'QA Automation', department: 'Engineering', status: 'away', joinedAt: '2024-04-02', projects: 4 },
|
|
41
|
+
{ id: '17', name: 'Sofia Petrova', email: 'sofia@acme.com', role: 'Data Engineer', department: 'Data', status: 'active', joinedAt: '2023-11-27', projects: 8 },
|
|
42
|
+
{ id: '18', name: 'David Kim', email: 'david@acme.com', role: 'Solutions Architect', department: 'Infrastructure', status: 'active', joinedAt: '2022-05-16', projects: 10 },
|
|
43
|
+
{ id: '19', name: 'Elena Marsh', email: 'elena@acme.com', role: 'Engineering Manager', department: 'Engineering', status: 'active', joinedAt: '2021-12-06', projects: 14 },
|
|
44
|
+
{ id: '20', name: 'Noah Fischer', email: 'noah@acme.com', role: 'Support Lead', department: 'Support', status: 'offline', joinedAt: '2024-05-20', projects: 1 },
|
|
33
45
|
];
|
|
34
46
|
|
|
47
|
+
const totalCrew = 34;
|
|
48
|
+
|
|
35
49
|
const filtered = $derived(
|
|
36
50
|
searchQuery
|
|
37
51
|
? crew.filter(m => m.name.toLowerCase().includes(searchQuery.toLowerCase()) || m.email.toLowerCase().includes(searchQuery.toLowerCase()) || m.department.toLowerCase().includes(searchQuery.toLowerCase()))
|
|
@@ -77,7 +91,7 @@
|
|
|
77
91
|
<tr class="border-b bg-muted/30">
|
|
78
92
|
<th class="px-4 py-3 text-left text-xs font-semibold text-muted-foreground">{i18n.t('account.member')}</th>
|
|
79
93
|
<th class="px-4 py-3 text-left text-xs font-semibold text-muted-foreground">{i18n.t('account.role')}</th>
|
|
80
|
-
<th class="px-4 py-3 text-left text-xs font-semibold text-muted-foreground">
|
|
94
|
+
<th class="px-4 py-3 text-left text-xs font-semibold text-muted-foreground">{i18n.t('account.department')}</th>
|
|
81
95
|
<th class="px-4 py-3 text-left text-xs font-semibold text-muted-foreground">{i18n.t('account.status')}</th>
|
|
82
96
|
<th class="px-4 py-3 text-left text-xs font-semibold text-muted-foreground">{i18n.t('publicProfile.projects')}</th>
|
|
83
97
|
<th class="px-4 py-3 text-left text-xs font-semibold text-muted-foreground">{i18n.t('account.joined')}</th>
|
|
@@ -154,4 +168,6 @@
|
|
|
154
168
|
</div>
|
|
155
169
|
</Card.CardContent>
|
|
156
170
|
</Card.Card>
|
|
171
|
+
|
|
172
|
+
<p class="text-sm text-muted-foreground">{i18n.t('network.showingUsersOf', { shown: filtered.length, total: totalCrew })}</p>
|
|
157
173
|
</div>
|
|
@@ -30,6 +30,9 @@
|
|
|
30
30
|
{ id: '4', name: 'SoundWave NFT', username: '@soundwave', bio: 'Music-backed NFTs with on-chain audio', collectionCount: 23, floorPrice: '0.3 ETH', volume: '89.4 ETH', verified: true, tags: ['Music', 'Audio'] },
|
|
31
31
|
{ id: '5', name: 'GameAssets DAO', username: '@gameassets', bio: 'In-game items and collectibles for Web3 gaming', collectionCount: 156, floorPrice: '0.05 ETH', volume: '412.8 ETH', verified: true, tags: ['Gaming', 'Items'] },
|
|
32
32
|
{ id: '6', name: 'PhotoVerse', username: '@photoverse', bio: 'Curated photography NFTs from world artists', collectionCount: 31, floorPrice: '0.15 ETH', volume: '67.2 ETH', verified: false, tags: ['Photo', 'Curated'] },
|
|
33
|
+
{ id: '7', name: 'CryptoKicks', username: '@cryptokicks', bio: 'Limited-edition digital sneakers and wearables', collectionCount: 64, floorPrice: '0.4 ETH', volume: '156.9 ETH', verified: true, tags: ['Fashion', 'Wearables'] },
|
|
34
|
+
{ id: '8', name: 'ChainChronicles', username: '@chainchron', bio: 'Story-driven collectible cards with on-chain lore', collectionCount: 88, floorPrice: '0.25 ETH', volume: '203.4 ETH', verified: false, tags: ['Cards', 'Story'] },
|
|
35
|
+
{ id: '9', name: 'AIArtifacts', username: '@aiartifacts', bio: 'AI-generated sculptures minted as unique tokens', collectionCount: 12, floorPrice: '2.1 ETH', volume: '512.6 ETH', verified: true, tags: ['AI', '3D'] },
|
|
33
36
|
];
|
|
34
37
|
|
|
35
38
|
const filtered = $derived(
|
|
@@ -64,6 +67,8 @@
|
|
|
64
67
|
<Input placeholder={i18n.t('common.search')} bind:value={searchQuery} class="pl-9" />
|
|
65
68
|
</div>
|
|
66
69
|
|
|
70
|
+
<p class="text-sm font-medium text-muted-foreground">{i18n.t('network.showingUsers', { count: filtered.length })}</p>
|
|
71
|
+
|
|
67
72
|
<div class="grid gap-4 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-3">
|
|
68
73
|
{#each filtered as user (user.id)}
|
|
69
74
|
<Card.Card class="overflow-hidden border-border/60 hover:border-primary/30 transition-colors">
|
|
@@ -19,9 +19,12 @@
|
|
|
19
19
|
|
|
20
20
|
interface Props {
|
|
21
21
|
activities?: ActivityItem[];
|
|
22
|
+
showAutoRefresh?: boolean;
|
|
22
23
|
}
|
|
23
24
|
|
|
24
|
-
let { activities = [] }: Props = $props();
|
|
25
|
+
let { activities = [], showAutoRefresh = true }: Props = $props();
|
|
26
|
+
|
|
27
|
+
let autoRefresh = $state(false);
|
|
25
28
|
|
|
26
29
|
const typeConfig: Record<string, { icon: Component; color: string; action: string }> = {
|
|
27
30
|
'posted': { icon: MessageSquare, color: 'bg-blue-500/10 text-blue-500', action: i18n.t('publicProfile.activityPosted') },
|
|
@@ -33,7 +36,26 @@
|
|
|
33
36
|
</script>
|
|
34
37
|
|
|
35
38
|
<div class="space-y-4">
|
|
36
|
-
<
|
|
39
|
+
<div class="flex items-center justify-between gap-3">
|
|
40
|
+
<h3 class="text-lg font-semibold text-foreground">{i18n.t('publicProfile.activity')}</h3>
|
|
41
|
+
{#if showAutoRefresh}
|
|
42
|
+
<div class="flex items-center gap-2 text-xs text-muted-foreground">
|
|
43
|
+
<span>{i18n.t('publicProfile.autoRefresh')}:</span>
|
|
44
|
+
<div class="flex rounded-md border border-border/60 p-0.5">
|
|
45
|
+
<button
|
|
46
|
+
type="button"
|
|
47
|
+
class="rounded px-2 py-0.5 text-xs font-medium transition-colors {autoRefresh ? 'bg-primary text-primary-foreground' : 'text-muted-foreground hover:text-foreground'}"
|
|
48
|
+
onclick={() => autoRefresh = true}
|
|
49
|
+
>{i18n.t('common.on')}</button>
|
|
50
|
+
<button
|
|
51
|
+
type="button"
|
|
52
|
+
class="rounded px-2 py-0.5 text-xs font-medium transition-colors {autoRefresh ? 'text-muted-foreground hover:text-foreground' : 'bg-primary text-primary-foreground'}"
|
|
53
|
+
onclick={() => autoRefresh = false}
|
|
54
|
+
>{i18n.t('common.off')}</button>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
{/if}
|
|
58
|
+
</div>
|
|
37
59
|
|
|
38
60
|
{#if activities.length === 0}
|
|
39
61
|
<div class="rounded-xl border border-dashed border-border/60 p-8 text-center">
|