@mimi-ng/cli 0.2.0 → 0.4.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/README.md +35 -2
- package/dist/init/css.js +1 -1
- package/dist/init/index.js +25 -0
- package/dist/init/paths.js +20 -0
- package/dist/registry.json +385 -14
- package/dist/templates/blocks/login-01/index.ts +1 -0
- package/dist/templates/blocks/login-01/login-01.html +174 -0
- package/dist/templates/blocks/login-01/login-01.ts +105 -0
- package/dist/templates/blocks/login-02/index.ts +1 -0
- package/dist/templates/blocks/login-02/login-02.html +186 -0
- package/dist/templates/blocks/login-02/login-02.ts +92 -0
- package/dist/templates/blocks/otp-01/index.ts +1 -0
- package/dist/templates/blocks/otp-01/otp-01.html +166 -0
- package/dist/templates/blocks/otp-01/otp-01.ts +212 -0
- package/dist/templates/blocks/pricing-01/index.ts +1 -0
- package/dist/templates/blocks/pricing-01/pricing-01.html +173 -0
- package/dist/templates/blocks/pricing-01/pricing-01.ts +178 -0
- package/dist/templates/blocks/settings-01/index.ts +1 -0
- package/dist/templates/blocks/settings-01/settings-01.html +424 -0
- package/dist/templates/blocks/settings-01/settings-01.ts +382 -0
- package/dist/templates/blocks/signup-01/index.ts +1 -0
- package/dist/templates/blocks/signup-01/signup-01.html +332 -0
- package/dist/templates/blocks/signup-01/signup-01.ts +176 -0
- package/dist/templates/components/calendar/calendar-texts.ts +72 -0
- package/dist/templates/components/calendar/calendar.ts +588 -0
- package/dist/templates/components/calendar/dates.ts +181 -0
- package/dist/templates/components/calendar/index.ts +3 -0
- package/dist/templates/components/chip/chip-texts.ts +40 -0
- package/dist/templates/components/chip/chip.ts +116 -0
- package/dist/templates/components/chip/index.ts +2 -0
- package/dist/templates/components/color-picker/color-picker-texts.ts +57 -0
- package/dist/templates/components/color-picker/color-picker.ts +718 -0
- package/dist/templates/components/color-picker/color.ts +157 -0
- package/dist/templates/components/color-picker/index.ts +3 -0
- package/dist/templates/components/combobox/combobox-texts.ts +70 -0
- package/dist/templates/components/combobox/combobox.ts +798 -0
- package/dist/templates/components/combobox/index.ts +2 -0
- package/dist/templates/components/date-picker/date-picker.ts +240 -0
- package/dist/templates/components/date-picker/index.ts +3 -0
- package/dist/templates/components/date-range/date-range.ts +308 -0
- package/dist/templates/components/date-range/index.ts +1 -0
- package/dist/templates/components/file-upload/file-upload-texts.ts +77 -0
- package/dist/templates/components/file-upload/file-upload.ts +698 -0
- package/dist/templates/components/file-upload/index.ts +2 -0
- package/dist/templates/components/input-mask/index.ts +1 -0
- package/dist/templates/components/input-mask/input-mask.ts +319 -0
- package/dist/templates/components/input-otp/index.ts +1 -0
- package/dist/templates/components/input-otp/input-otp.ts +212 -0
- package/dist/templates/components/number-input/index.ts +2 -0
- package/dist/templates/components/number-input/number-input-texts.ts +46 -0
- package/dist/templates/components/number-input/number-input.ts +450 -0
- package/dist/templates/components/option-list/index.ts +11 -0
- package/dist/templates/components/option-list/option-list.ts +518 -0
- package/dist/templates/components/password/index.ts +2 -0
- package/dist/templates/components/password/password-texts.ts +68 -0
- package/dist/templates/components/password/password.ts +363 -0
- package/dist/templates/components/popover/popover.ts +12 -4
- package/dist/templates/components/progress/index.ts +1 -0
- package/dist/templates/components/progress/progress.ts +217 -0
- package/dist/templates/components/select/select.ts +3 -2
- package/dist/templates/components/slider/index.ts +2 -0
- package/dist/templates/components/slider/slider-texts.ts +26 -0
- package/dist/templates/components/slider/slider.ts +425 -0
- package/dist/templates/components/tabs/tabs.ts +88 -23
- package/dist/templates/components/tags-input/index.ts +2 -0
- package/dist/templates/components/tags-input/tags-input-texts.ts +44 -0
- package/dist/templates/components/tags-input/tags-input.ts +303 -0
- package/dist/templates/components/toggle-group/index.ts +1 -0
- package/dist/templates/components/toggle-group/toggle-group.ts +406 -0
- package/dist/templates/theme/provider.ts +13 -0
- package/dist/templates/theme/theme-base.css +103 -0
- package/dist/templates/theme/types.ts +216 -0
- package/dist/templates/utils/overlay.ts +17 -4
- package/dist/ui/index.js +232 -10
- package/dist/ui/schema.json +82 -2
- package/dist/utils/project.js +35 -0
- package/dist/utils/tailwind.js +80 -0
- package/dist/utils/write-files.js +49 -9
- package/package.json +1 -1
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
<header class="flex flex-col gap-1 border-b px-4 pt-5 pb-3.5 md:px-10 md:pt-7 md:pb-5">
|
|
2
|
+
<h1 class="text-2xl font-extrabold tracking-[-0.025em] md:text-[28px]">Settings</h1>
|
|
3
|
+
<p class="text-sm text-muted-foreground">Manage your profile, notifications and security.</p>
|
|
4
|
+
</header>
|
|
5
|
+
|
|
6
|
+
<div class="flex-1 md:px-10 md:pt-7 md:pb-10">
|
|
7
|
+
<!-- Una sola lista de pestañas: vertical en escritorio, píldoras horizontales en móvil (B.10). -->
|
|
8
|
+
<mimi-tabs
|
|
9
|
+
aria-label="Settings sections"
|
|
10
|
+
[orientation]="wide() ? 'vertical' : 'horizontal'"
|
|
11
|
+
[class]="wide() ? sideNavClasses : pillNavClasses"
|
|
12
|
+
[panelClass]="panelClasses"
|
|
13
|
+
[style.gap.px]="wide() ? 40 : 0"
|
|
14
|
+
[value]="tab()"
|
|
15
|
+
(valueChange)="selectTab($event)"
|
|
16
|
+
>
|
|
17
|
+
@for (item of tabs; track item.value) {
|
|
18
|
+
<ng-template [mimiTabLabel]="item.value">
|
|
19
|
+
<svg
|
|
20
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
21
|
+
width="17"
|
|
22
|
+
height="17"
|
|
23
|
+
viewBox="0 0 24 24"
|
|
24
|
+
fill="none"
|
|
25
|
+
stroke="currentColor"
|
|
26
|
+
stroke-width="2"
|
|
27
|
+
stroke-linecap="round"
|
|
28
|
+
stroke-linejoin="round"
|
|
29
|
+
aria-hidden="true"
|
|
30
|
+
>
|
|
31
|
+
@switch (item.value) {
|
|
32
|
+
@case ('profile') {
|
|
33
|
+
<!-- Lucide user-round (ISC) -->
|
|
34
|
+
<circle cx="12" cy="8" r="5" />
|
|
35
|
+
<path d="M20 21a8 8 0 0 0-16 0" />
|
|
36
|
+
}
|
|
37
|
+
@case ('notifications') {
|
|
38
|
+
<!-- Lucide bell (ISC) -->
|
|
39
|
+
<path d="M10.268 21a2 2 0 0 0 3.464 0" />
|
|
40
|
+
<path
|
|
41
|
+
d="M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326"
|
|
42
|
+
/>
|
|
43
|
+
}
|
|
44
|
+
@case ('security') {
|
|
45
|
+
<!-- Lucide shield (ISC) -->
|
|
46
|
+
<path
|
|
47
|
+
d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"
|
|
48
|
+
/>
|
|
49
|
+
}
|
|
50
|
+
@case ('billing') {
|
|
51
|
+
<!-- Lucide credit-card (ISC) -->
|
|
52
|
+
<rect width="20" height="14" x="2" y="5" rx="2" />
|
|
53
|
+
<line x1="2" x2="22" y1="10" y2="10" />
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
</svg>
|
|
57
|
+
{{ item.label }}
|
|
58
|
+
</ng-template>
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
<!-- Perfil -->
|
|
62
|
+
<ng-template mimiTab="profile" label="Profile">
|
|
63
|
+
<mimi-card>
|
|
64
|
+
<div class="flex flex-col gap-0.5 px-5 pt-5 pb-1">
|
|
65
|
+
<h2 class="text-base font-bold">Public profile</h2>
|
|
66
|
+
<p class="text-[13.5px] text-muted-foreground">Visible to people on your team.</p>
|
|
67
|
+
</div>
|
|
68
|
+
<div class="flex flex-col gap-4 px-5 py-4">
|
|
69
|
+
<div class="flex flex-wrap items-center gap-3.5">
|
|
70
|
+
<mimi-avatar size="lg">
|
|
71
|
+
@if (profile().avatarSrc; as src) {
|
|
72
|
+
<img mimiAvatarImage [src]="src" [alt]="model().name" />
|
|
73
|
+
}
|
|
74
|
+
<mimi-avatar-fallback class="bg-info-soft font-bold text-info-soft-foreground">{{
|
|
75
|
+
profile().initials
|
|
76
|
+
}}</mimi-avatar-fallback>
|
|
77
|
+
</mimi-avatar>
|
|
78
|
+
<button
|
|
79
|
+
mimiBtn
|
|
80
|
+
type="button"
|
|
81
|
+
variant="outline"
|
|
82
|
+
tone="secondary"
|
|
83
|
+
size="sm"
|
|
84
|
+
(click)="avatarChange.emit()"
|
|
85
|
+
>
|
|
86
|
+
<svg
|
|
87
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
88
|
+
width="14"
|
|
89
|
+
height="14"
|
|
90
|
+
viewBox="0 0 24 24"
|
|
91
|
+
fill="none"
|
|
92
|
+
stroke="currentColor"
|
|
93
|
+
stroke-width="2"
|
|
94
|
+
stroke-linecap="round"
|
|
95
|
+
stroke-linejoin="round"
|
|
96
|
+
aria-hidden="true"
|
|
97
|
+
>
|
|
98
|
+
<!-- Lucide upload (ISC) -->
|
|
99
|
+
<path d="M12 3v12" />
|
|
100
|
+
<path d="m17 8-5-5-5 5" />
|
|
101
|
+
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
|
|
102
|
+
</svg>
|
|
103
|
+
Change photo
|
|
104
|
+
</button>
|
|
105
|
+
<button
|
|
106
|
+
mimiBtn
|
|
107
|
+
type="button"
|
|
108
|
+
variant="ghost"
|
|
109
|
+
tone="danger"
|
|
110
|
+
size="sm"
|
|
111
|
+
(click)="avatarRemove.emit()"
|
|
112
|
+
>
|
|
113
|
+
Remove
|
|
114
|
+
</button>
|
|
115
|
+
</div>
|
|
116
|
+
|
|
117
|
+
<div class="grid grid-cols-1 gap-3.5 md:grid-cols-2">
|
|
118
|
+
<mimi-form-field label="Name">
|
|
119
|
+
<input mimiInput autocomplete="name" [formField]="settings.name" />
|
|
120
|
+
</mimi-form-field>
|
|
121
|
+
<mimi-form-field>
|
|
122
|
+
<label [attr.for]="id + '-username'" class="text-sm font-medium">Username</label>
|
|
123
|
+
<!-- Prefijo fijo con los colores de Input (no hay un grupo de input con prefijo). -->
|
|
124
|
+
<div
|
|
125
|
+
class="flex h-[var(--mimi-control-height,2.5rem)] items-center overflow-hidden rounded-[var(--mimi-radius)] border border-input bg-input-background mimi-transition focus-within:border-ring focus-within:ring-3 focus-within:ring-ring-soft has-[[aria-invalid=true]]:border-destructive"
|
|
126
|
+
>
|
|
127
|
+
<span
|
|
128
|
+
aria-hidden="true"
|
|
129
|
+
class="flex h-full items-center border-e border-input bg-muted px-2.5 text-[13px] text-muted-foreground"
|
|
130
|
+
>example.com/</span
|
|
131
|
+
>
|
|
132
|
+
<input
|
|
133
|
+
mimiInput
|
|
134
|
+
autocomplete="username"
|
|
135
|
+
class="h-full min-w-0 flex-1 rounded-none border-0 bg-transparent px-2.5 shadow-none focus-visible:ring-0"
|
|
136
|
+
[id]="id + '-username'"
|
|
137
|
+
[formField]="settings.username"
|
|
138
|
+
/>
|
|
139
|
+
</div>
|
|
140
|
+
</mimi-form-field>
|
|
141
|
+
</div>
|
|
142
|
+
|
|
143
|
+
<mimi-form-field class="relative">
|
|
144
|
+
<label [attr.for]="id + '-bio'" class="text-sm font-medium">Bio</label>
|
|
145
|
+
<!-- El contador describe el campo y no se anuncia con cada tecla (no es una región viva). -->
|
|
146
|
+
<span
|
|
147
|
+
[id]="bioId"
|
|
148
|
+
class="absolute top-0 right-0 text-xs text-muted-foreground tabular-nums"
|
|
149
|
+
>{{ model().bio.length }}/160</span
|
|
150
|
+
>
|
|
151
|
+
<textarea
|
|
152
|
+
mimiTextarea
|
|
153
|
+
rows="3"
|
|
154
|
+
[id]="id + '-bio'"
|
|
155
|
+
[attr.aria-describedby]="bioId"
|
|
156
|
+
[formField]="settings.bio"
|
|
157
|
+
></textarea>
|
|
158
|
+
</mimi-form-field>
|
|
159
|
+
</div>
|
|
160
|
+
</mimi-card>
|
|
161
|
+
|
|
162
|
+
<mimi-card>
|
|
163
|
+
<h2 class="px-5 pt-5 pb-2 text-base font-bold">Preferences</h2>
|
|
164
|
+
@for (row of profileSwitches; track row.key) {
|
|
165
|
+
<!-- Una fila con interruptor: el título lo nombra y la descripción lo describe. -->
|
|
166
|
+
<div class="flex items-center justify-between gap-4 border-t px-5 py-3.5">
|
|
167
|
+
<span class="flex flex-col leading-[1.4]">
|
|
168
|
+
<label [attr.for]="id + '-' + row.key" class="cursor-pointer text-sm font-medium">{{
|
|
169
|
+
row.label
|
|
170
|
+
}}</label>
|
|
171
|
+
<span [id]="id + '-' + row.key + '-desc'" class="text-[13px] text-muted-foreground">{{
|
|
172
|
+
row.description
|
|
173
|
+
}}</span>
|
|
174
|
+
</span>
|
|
175
|
+
<mimi-switch
|
|
176
|
+
[id]="id + '-' + row.key"
|
|
177
|
+
[attr.data-describedby]="id + '-' + row.key + '-desc'"
|
|
178
|
+
[formField]="field(row.key)"
|
|
179
|
+
/>
|
|
180
|
+
</div>
|
|
181
|
+
}
|
|
182
|
+
</mimi-card>
|
|
183
|
+
</ng-template>
|
|
184
|
+
|
|
185
|
+
<!-- Notificaciones -->
|
|
186
|
+
<ng-template mimiTab="notifications" label="Notifications">
|
|
187
|
+
@for (group of notificationGroups; track group.title) {
|
|
188
|
+
<mimi-card>
|
|
189
|
+
<div class="flex items-center gap-2.5 px-5 pt-[18px] pb-2.5">
|
|
190
|
+
<svg
|
|
191
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
192
|
+
width="17"
|
|
193
|
+
height="17"
|
|
194
|
+
viewBox="0 0 24 24"
|
|
195
|
+
fill="none"
|
|
196
|
+
stroke="currentColor"
|
|
197
|
+
stroke-width="2"
|
|
198
|
+
stroke-linecap="round"
|
|
199
|
+
stroke-linejoin="round"
|
|
200
|
+
aria-hidden="true"
|
|
201
|
+
class="text-muted-foreground"
|
|
202
|
+
>
|
|
203
|
+
@if (group.icon === 'mail') {
|
|
204
|
+
<!-- Lucide mail (ISC) -->
|
|
205
|
+
<path d="m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7" />
|
|
206
|
+
<rect x="2" y="4" width="20" height="16" rx="2" />
|
|
207
|
+
} @else {
|
|
208
|
+
<!-- Lucide smartphone (ISC) -->
|
|
209
|
+
<rect width="14" height="20" x="5" y="2" rx="2" ry="2" />
|
|
210
|
+
<path d="M12 18h.01" />
|
|
211
|
+
}
|
|
212
|
+
</svg>
|
|
213
|
+
<h2 class="text-base font-bold">{{ group.title }}</h2>
|
|
214
|
+
</div>
|
|
215
|
+
@for (row of group.rows; track row.key) {
|
|
216
|
+
<div class="flex items-center justify-between gap-4 border-t px-5 py-3.5">
|
|
217
|
+
<span class="flex flex-col leading-[1.4]">
|
|
218
|
+
<label [attr.for]="id + '-' + row.key" class="cursor-pointer text-sm font-medium">{{
|
|
219
|
+
row.label
|
|
220
|
+
}}</label>
|
|
221
|
+
<span
|
|
222
|
+
[id]="id + '-' + row.key + '-desc'"
|
|
223
|
+
class="text-[13px] text-muted-foreground"
|
|
224
|
+
>{{ row.description }}</span
|
|
225
|
+
>
|
|
226
|
+
</span>
|
|
227
|
+
<mimi-switch
|
|
228
|
+
[id]="id + '-' + row.key"
|
|
229
|
+
[attr.data-describedby]="id + '-' + row.key + '-desc'"
|
|
230
|
+
[formField]="field(row.key)"
|
|
231
|
+
/>
|
|
232
|
+
</div>
|
|
233
|
+
}
|
|
234
|
+
</mimi-card>
|
|
235
|
+
}
|
|
236
|
+
</ng-template>
|
|
237
|
+
|
|
238
|
+
<!-- Seguridad -->
|
|
239
|
+
<ng-template mimiTab="security" label="Security">
|
|
240
|
+
<mimi-card class="gap-3.5 p-5">
|
|
241
|
+
<div class="flex items-center justify-between gap-3">
|
|
242
|
+
<div class="flex flex-col gap-0.5">
|
|
243
|
+
<h2 class="flex flex-wrap items-center gap-2 text-base font-bold">
|
|
244
|
+
<label [attr.for]="id + '-twoFactor'" class="cursor-pointer"
|
|
245
|
+
>Two-step verification</label
|
|
246
|
+
>
|
|
247
|
+
<span mimiBadge variant="soft" tone="success">Recommended</span>
|
|
248
|
+
</h2>
|
|
249
|
+
<p [id]="id + '-twoFactor-desc'" class="text-[13.5px] text-muted-foreground">
|
|
250
|
+
Ask for a code from your app when signing in.
|
|
251
|
+
</p>
|
|
252
|
+
</div>
|
|
253
|
+
<mimi-switch
|
|
254
|
+
[id]="id + '-twoFactor'"
|
|
255
|
+
[attr.data-describedby]="id + '-twoFactor-desc'"
|
|
256
|
+
[formField]="settings.twoFactor"
|
|
257
|
+
/>
|
|
258
|
+
</div>
|
|
259
|
+
<mimi-separator />
|
|
260
|
+
<h3 class="text-sm font-bold">Active sessions</h3>
|
|
261
|
+
<ul class="flex flex-col gap-3">
|
|
262
|
+
@for (session of sessions(); track session.id) {
|
|
263
|
+
<li class="flex items-center gap-3">
|
|
264
|
+
<span
|
|
265
|
+
aria-hidden="true"
|
|
266
|
+
class="inline-flex size-9 shrink-0 items-center justify-center rounded-[var(--mimi-radius-sm)] bg-muted"
|
|
267
|
+
>
|
|
268
|
+
<svg
|
|
269
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
270
|
+
width="17"
|
|
271
|
+
height="17"
|
|
272
|
+
viewBox="0 0 24 24"
|
|
273
|
+
fill="none"
|
|
274
|
+
stroke="currentColor"
|
|
275
|
+
stroke-width="2"
|
|
276
|
+
stroke-linecap="round"
|
|
277
|
+
stroke-linejoin="round"
|
|
278
|
+
>
|
|
279
|
+
@if (session.kind === 'mobile') {
|
|
280
|
+
<!-- Lucide smartphone (ISC) -->
|
|
281
|
+
<rect width="14" height="20" x="5" y="2" rx="2" ry="2" />
|
|
282
|
+
<path d="M12 18h.01" />
|
|
283
|
+
} @else {
|
|
284
|
+
<!-- Lucide monitor (ISC) -->
|
|
285
|
+
<rect width="20" height="14" x="2" y="3" rx="2" />
|
|
286
|
+
<line x1="8" x2="16" y1="21" y2="21" />
|
|
287
|
+
<line x1="12" x2="12" y1="17" y2="21" />
|
|
288
|
+
}
|
|
289
|
+
</svg>
|
|
290
|
+
</span>
|
|
291
|
+
<span class="flex min-w-0 flex-1 flex-col leading-[1.35]">
|
|
292
|
+
<span class="text-sm font-medium">{{ session.device }}</span>
|
|
293
|
+
<span class="text-[12.5px] text-muted-foreground">{{ session.detail }}</span>
|
|
294
|
+
</span>
|
|
295
|
+
@if (session.current) {
|
|
296
|
+
<span mimiBadge variant="soft" tone="info">This session</span>
|
|
297
|
+
} @else {
|
|
298
|
+
<button
|
|
299
|
+
mimiBtn
|
|
300
|
+
type="button"
|
|
301
|
+
variant="outline"
|
|
302
|
+
tone="secondary"
|
|
303
|
+
size="sm"
|
|
304
|
+
[attr.aria-label]="'Sign out of ' + session.device"
|
|
305
|
+
(click)="sessionEnd.emit(session.id)"
|
|
306
|
+
>
|
|
307
|
+
Sign out
|
|
308
|
+
</button>
|
|
309
|
+
}
|
|
310
|
+
</li>
|
|
311
|
+
}
|
|
312
|
+
</ul>
|
|
313
|
+
</mimi-card>
|
|
314
|
+
|
|
315
|
+
<section
|
|
316
|
+
[attr.aria-labelledby]="id + '-danger'"
|
|
317
|
+
class="flex flex-wrap items-center justify-between gap-4 rounded-card border border-[color:color-mix(in_oklab,var(--mimi-destructive)_40%,var(--mimi-border))] bg-destructive-soft-bg p-5"
|
|
318
|
+
>
|
|
319
|
+
<div class="flex flex-col gap-0.5 text-destructive-soft-foreground">
|
|
320
|
+
<h2 [id]="id + '-danger'" class="text-base font-bold">Delete account</h2>
|
|
321
|
+
<p class="text-[13.5px]">Your data is deleted after 30 days. This can't be undone.</p>
|
|
322
|
+
</div>
|
|
323
|
+
<button mimiBtn type="button" tone="danger" size="sm" (click)="deleteAccount.emit()">
|
|
324
|
+
<svg
|
|
325
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
326
|
+
width="15"
|
|
327
|
+
height="15"
|
|
328
|
+
viewBox="0 0 24 24"
|
|
329
|
+
fill="none"
|
|
330
|
+
stroke="currentColor"
|
|
331
|
+
stroke-width="2"
|
|
332
|
+
stroke-linecap="round"
|
|
333
|
+
stroke-linejoin="round"
|
|
334
|
+
aria-hidden="true"
|
|
335
|
+
>
|
|
336
|
+
<!-- Lucide trash (ISC) -->
|
|
337
|
+
<path d="M10 11v6" />
|
|
338
|
+
<path d="M14 11v6" />
|
|
339
|
+
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6" />
|
|
340
|
+
<path d="M3 6h18" />
|
|
341
|
+
<path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
|
|
342
|
+
</svg>
|
|
343
|
+
Delete account
|
|
344
|
+
</button>
|
|
345
|
+
</section>
|
|
346
|
+
</ng-template>
|
|
347
|
+
|
|
348
|
+
<!-- Facturación -->
|
|
349
|
+
<ng-template mimiTab="billing" label="Billing">
|
|
350
|
+
<mimi-card class="gap-3.5 p-5">
|
|
351
|
+
<div class="flex flex-wrap items-center justify-between gap-3">
|
|
352
|
+
<div class="flex flex-col gap-0.5">
|
|
353
|
+
<h2 class="text-[13px] font-normal text-muted-foreground">Current plan</h2>
|
|
354
|
+
<span class="text-[22px] font-extrabold">{{ price() }}</span>
|
|
355
|
+
</div>
|
|
356
|
+
<button mimiBtn type="button" size="sm" (click)="changePlan.emit()">Change plan</button>
|
|
357
|
+
</div>
|
|
358
|
+
<div class="flex flex-col gap-1.5">
|
|
359
|
+
<div class="flex justify-between text-[13px]">
|
|
360
|
+
<span [id]="id + '-seats'">Seats used</span>
|
|
361
|
+
<span class="text-muted-foreground">{{ plan().seatsUsed }} of {{ plan().seats }}</span>
|
|
362
|
+
</div>
|
|
363
|
+
<mimi-progress
|
|
364
|
+
[aria-labelledby]="id + '-seats'"
|
|
365
|
+
[value]="plan().seatsUsed"
|
|
366
|
+
[max]="plan().seats"
|
|
367
|
+
/>
|
|
368
|
+
</div>
|
|
369
|
+
<span class="flex items-center gap-2 text-[13.5px] text-muted-foreground">
|
|
370
|
+
<svg
|
|
371
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
372
|
+
width="15"
|
|
373
|
+
height="15"
|
|
374
|
+
viewBox="0 0 24 24"
|
|
375
|
+
fill="none"
|
|
376
|
+
stroke="currentColor"
|
|
377
|
+
stroke-width="2"
|
|
378
|
+
stroke-linecap="round"
|
|
379
|
+
stroke-linejoin="round"
|
|
380
|
+
aria-hidden="true"
|
|
381
|
+
>
|
|
382
|
+
<!-- Lucide credit-card (ISC) -->
|
|
383
|
+
<rect width="20" height="14" x="2" y="5" rx="2" />
|
|
384
|
+
<line x1="2" x2="22" y1="10" y2="10" />
|
|
385
|
+
</svg>
|
|
386
|
+
{{ plan().card }} · next invoice on {{ nextInvoice() }}
|
|
387
|
+
</span>
|
|
388
|
+
</mimi-card>
|
|
389
|
+
</ng-template>
|
|
390
|
+
</mimi-tabs>
|
|
391
|
+
</div>
|
|
392
|
+
|
|
393
|
+
<!-- La barra de cambios: la región existe siempre, así el lector la anuncia al aparecer. -->
|
|
394
|
+
<div role="status" class="contents">
|
|
395
|
+
@if (changed()) {
|
|
396
|
+
<div
|
|
397
|
+
class="sticky bottom-0 flex items-center justify-between gap-3 border-t border-glass-border bg-glass px-5 py-3 backdrop-blur-glass [@media(prefers-reduced-transparency:reduce)]:bg-background"
|
|
398
|
+
>
|
|
399
|
+
<span class="text-[13.5px] font-medium">You have unsaved changes</span>
|
|
400
|
+
<div class="flex gap-2">
|
|
401
|
+
<button
|
|
402
|
+
mimiBtn
|
|
403
|
+
type="button"
|
|
404
|
+
variant="outline"
|
|
405
|
+
tone="secondary"
|
|
406
|
+
size="sm"
|
|
407
|
+
(click)="discard()"
|
|
408
|
+
>
|
|
409
|
+
Discard
|
|
410
|
+
</button>
|
|
411
|
+
<button
|
|
412
|
+
mimiBtn
|
|
413
|
+
type="button"
|
|
414
|
+
size="sm"
|
|
415
|
+
[attr.aria-disabled]="saving() ? 'true' : null"
|
|
416
|
+
[attr.aria-busy]="saving() ? 'true' : null"
|
|
417
|
+
(click)="save()"
|
|
418
|
+
>
|
|
419
|
+
{{ saving() ? 'Saving…' : 'Save' }}
|
|
420
|
+
</button>
|
|
421
|
+
</div>
|
|
422
|
+
</div>
|
|
423
|
+
}
|
|
424
|
+
</div>
|