negodesign 0.0.30 → 0.0.32

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 (102) hide show
  1. package/dist/components/NegoDesign.svelte +2 -10
  2. package/dist/components/NegoDesign.svelte.d.ts +2 -7
  3. package/dist/components/core/banner/CtaCardBanner.svelte +1 -1
  4. package/dist/components/core/banner/types.d.ts +16 -6
  5. package/dist/components/core/card/types.d.ts +94 -0
  6. package/dist/components/core/carousel/grid/media/types.d.ts +11 -1
  7. package/dist/components/core/carousel/grid/media/ui/CarouselGridMedia.svelte +2 -2
  8. package/dist/components/core/carousel/grid/media/ui/CarouselGridMedia.svelte.d.ts +2 -2
  9. package/dist/components/core/carousel/grid/profile/types.d.ts +11 -1
  10. package/dist/components/core/carousel/grid/profile/ui/CarouselGridProfile.svelte +2 -2
  11. package/dist/components/core/carousel/grid/profile/ui/CarouselGridProfile.svelte.d.ts +2 -2
  12. package/dist/components/core/carousel/highlights/types.d.ts +11 -0
  13. package/dist/components/core/carousel/promotion/types.d.ts +10 -0
  14. package/dist/components/core/carousel/types.d.ts +56 -0
  15. package/dist/components/core/datatable/data/data-table.d.ts +25 -0
  16. package/dist/components/core/footer/types.d.ts +28 -0
  17. package/dist/components/core/nav/data/nav-menu-sidebar.d.ts +29 -0
  18. package/dist/components/core/nav/data/nav-menu.d.ts +43 -0
  19. package/dist/components/core/nav/data/nav-user-sidebar.d.ts +14 -0
  20. package/dist/components/core/nav/ui/menu-links.svelte +1 -1
  21. package/dist/components/core/panel/CarouselSlot.svelte +1 -1
  22. package/dist/components/core/panel/type.d.ts +11 -0
  23. package/dist/components/core/search/types.d.ts +17 -5
  24. package/dist/components/core/sidebar/types.d.ts +19 -0
  25. package/dist/components/core/sidebar/types.js +1 -0
  26. package/dist/components/core/tabs/data/TabModel.d.ts +11 -0
  27. package/dist/components/core/tabs/types.d.ts +11 -0
  28. package/dist/components/core/tabs/types.js +1 -0
  29. package/dist/components/pages/admin/01/ui/types.d.ts +21 -0
  30. package/dist/components/pages/admin/01/ui/types.js +1 -0
  31. package/dist/components/pages/product-details/01/ProductDetails01.svelte +71 -0
  32. package/dist/components/pages/product-details/01/ProductDetails01.svelte.d.ts +11 -0
  33. package/dist/components/pages/product-details/02/ProductDetails02.svelte +88 -0
  34. package/dist/components/pages/product-details/02/ProductDetails02.svelte.d.ts +11 -0
  35. package/dist/components/pages/product-details/03/ProductDetails03.svelte +77 -0
  36. package/dist/components/pages/product-details/03/ProductDetails03.svelte.d.ts +11 -0
  37. package/dist/components/pages/product-details/04/ProductDetails04.svelte +65 -0
  38. package/dist/components/pages/product-details/04/ProductDetails04.svelte.d.ts +11 -0
  39. package/dist/components/pages/product-details/ProductDetails.svelte +38 -0
  40. package/dist/components/pages/product-details/ProductDetails.svelte.d.ts +4 -0
  41. package/dist/components/pages/product-details/shared/ProductDetailActions.svelte +82 -0
  42. package/dist/components/pages/product-details/shared/ProductDetailActions.svelte.d.ts +13 -0
  43. package/dist/components/pages/product-details/shared/ProductDetailBreadcrumb.svelte +46 -0
  44. package/dist/components/pages/product-details/shared/ProductDetailBreadcrumb.svelte.d.ts +8 -0
  45. package/dist/components/pages/product-details/shared/ProductDetailDescription.svelte +38 -0
  46. package/dist/components/pages/product-details/shared/ProductDetailDescription.svelte.d.ts +8 -0
  47. package/dist/components/pages/product-details/shared/ProductDetailFeatures.svelte +40 -0
  48. package/dist/components/pages/product-details/shared/ProductDetailFeatures.svelte.d.ts +7 -0
  49. package/dist/components/pages/product-details/shared/ProductDetailFilesVertical.svelte +72 -0
  50. package/dist/components/pages/product-details/shared/ProductDetailFilesVertical.svelte.d.ts +9 -0
  51. package/dist/components/pages/product-details/shared/ProductDetailHeader.svelte +41 -0
  52. package/dist/components/pages/product-details/shared/ProductDetailHeader.svelte.d.ts +9 -0
  53. package/dist/components/pages/product-details/shared/ProductDetailImage.svelte +70 -0
  54. package/dist/components/pages/product-details/shared/ProductDetailImage.svelte.d.ts +9 -0
  55. package/dist/components/pages/product-details/shared/ProductDetailMap.svelte +57 -0
  56. package/dist/components/pages/product-details/shared/ProductDetailMap.svelte.d.ts +9 -0
  57. package/dist/components/pages/product-details/shared/ProductDetailPrice.svelte +44 -0
  58. package/dist/components/pages/product-details/shared/ProductDetailPrice.svelte.d.ts +9 -0
  59. package/dist/components/pages/product-details/shared/ProductDetailRating.svelte +42 -0
  60. package/dist/components/pages/product-details/shared/ProductDetailRating.svelte.d.ts +8 -0
  61. package/dist/components/pages/product-details/shared/ProductDetailReviews.svelte +70 -0
  62. package/dist/components/pages/product-details/shared/ProductDetailReviews.svelte.d.ts +8 -0
  63. package/dist/components/pages/product-details/shared/ProductDetailTabs.svelte +96 -0
  64. package/dist/components/pages/product-details/shared/ProductDetailTabs.svelte.d.ts +12 -0
  65. package/dist/components/pages/product-details/shared/ProductDetailTags.svelte +35 -0
  66. package/dist/components/pages/product-details/shared/ProductDetailTags.svelte.d.ts +8 -0
  67. package/dist/components/pages/product-details/shared/ProductPurchasePanel.svelte +58 -0
  68. package/dist/components/pages/product-details/shared/ProductPurchasePanel.svelte.d.ts +11 -0
  69. package/dist/components/pages/product-details/types.d.ts +170 -0
  70. package/dist/components/pages/product-details/types.js +1 -0
  71. package/dist/components/pages/profile-user/01/ProfileUser01.svelte +113 -0
  72. package/dist/components/pages/profile-user/01/ProfileUser01.svelte.d.ts +27 -0
  73. package/dist/components/pages/profile-user/02/ProfileUser02.svelte +83 -0
  74. package/dist/components/pages/profile-user/02/ProfileUser02.svelte.d.ts +20 -0
  75. package/dist/components/pages/profile-user/03/ProfileUser03.svelte +85 -0
  76. package/dist/components/pages/profile-user/03/ProfileUser03.svelte.d.ts +20 -0
  77. package/dist/components/pages/profile-user/ProfileUser.svelte +53 -0
  78. package/dist/components/pages/profile-user/ProfileUser.svelte.d.ts +4 -0
  79. package/dist/components/pages/profile-user/shared/ProfileUserAddress.svelte +84 -0
  80. package/dist/components/pages/profile-user/shared/ProfileUserAddress.svelte.d.ts +8 -0
  81. package/dist/components/pages/profile-user/shared/ProfileUserHeader.svelte +104 -0
  82. package/dist/components/pages/profile-user/shared/ProfileUserHeader.svelte.d.ts +9 -0
  83. package/dist/components/pages/profile-user/shared/ProfileUserResetPassword.svelte +116 -0
  84. package/dist/components/pages/profile-user/shared/ProfileUserResetPassword.svelte.d.ts +7 -0
  85. package/dist/components/pages/profile-user/shared/ProfileUserSetting.svelte +176 -0
  86. package/dist/components/pages/profile-user/shared/ProfileUserSetting.svelte.d.ts +14 -0
  87. package/dist/components/pages/profile-user/shared/ProfileUserTabs.svelte +78 -0
  88. package/dist/components/pages/profile-user/shared/ProfileUserTabs.svelte.d.ts +22 -0
  89. package/dist/components/pages/profile-user/types.d.ts +144 -0
  90. package/dist/components/pages/profile-user/types.js +1 -0
  91. package/dist/components/types.d.ts +6 -0
  92. package/dist/components/types.js +1 -0
  93. package/dist/globals.css +210 -3
  94. package/dist/i18n/langs/en.d.ts +83 -0
  95. package/dist/i18n/langs/en.js +83 -0
  96. package/dist/i18n/langs/pt.d.ts +83 -0
  97. package/dist/i18n/langs/pt.js +83 -0
  98. package/dist/i18n/translations.d.ts +166 -0
  99. package/dist/index.d.ts +190 -25
  100. package/dist/index.js +190 -25
  101. package/dist/types/index.d.ts +159 -5
  102. package/package.json +1 -1
@@ -0,0 +1,83 @@
1
+ <script lang="ts" module>
2
+ /**
3
+ * Variante 02 da página de perfil. Reutiliza header,
4
+ * tabs underline, moradas, segurança e definições.
5
+ * @component
6
+ */
7
+ </script>
8
+
9
+ <script lang="ts">
10
+ import { t } from "../../../../i18n";
11
+ import type { ProfileUserData } from "../types";
12
+ import ProfileUserHeader from "../shared/ProfileUserHeader.svelte";
13
+ import ProfileUserTabs from "../shared/ProfileUserTabs.svelte";
14
+ import ProfileUserAddress from "../shared/ProfileUserAddress.svelte";
15
+ import ProfileUserResetPassword from "../shared/ProfileUserResetPassword.svelte";
16
+ import ProfileUserSetting from "../shared/ProfileUserSetting.svelte";
17
+
18
+ let {
19
+ data,
20
+ activeTab = $bindable(),
21
+ isLoading = false,
22
+ onAddAddress,
23
+ onChangePassword,
24
+ onLoginAsUser,
25
+ tabs: customTabs,
26
+ }: {
27
+ data: ProfileUserData;
28
+ activeTab?: string;
29
+ isLoading?: boolean;
30
+ onAddAddress?: () => void;
31
+ onChangePassword?: (payload: {
32
+ currentPassword: string;
33
+ newPassword: string;
34
+ confirmPassword: string;
35
+ }) => void;
36
+ onLoginAsUser?: (id: string | number) => void;
37
+ tabs?: { id: string; label: string }[];
38
+ } = $props();
39
+
40
+ const defaultTabs = $derived(
41
+ customTabs?.length
42
+ ? customTabs
43
+ : [
44
+ { id: "addresses", label: $t("profile-user.variant1.tabs.addresses") || "Moradas" },
45
+ { id: "security", label: $t("profile-user.variant2.tabs.security") || "Segurança" },
46
+ { id: "settings", label: $t("profile-user.variant1.tabs.settings") || "Definições" },
47
+ ]
48
+ );
49
+
50
+ const currentTab = $derived(activeTab ?? defaultTabs[0]?.id ?? "addresses");
51
+ const fullName = $derived(data.fullName ?? `${data.firstName} ${data.lastName}`);
52
+ </script>
53
+
54
+ <div class="bg-background">
55
+ <ProfileUserHeader {data} {isLoading} {fullName} {onLoginAsUser} />
56
+
57
+ <div class="mx-auto max-w-5xl px-6 pb-12">
58
+ <ProfileUserTabs
59
+ tabs={defaultTabs}
60
+ bind:activeTab
61
+ {isLoading}
62
+ />
63
+
64
+ <div class="flex flex-col gap-6">
65
+ {#if currentTab === "addresses"}
66
+ <ProfileUserAddress
67
+ addresses={data.addresses}
68
+ {isLoading}
69
+ {onAddAddress}
70
+ />
71
+ {:else if currentTab === "security"}
72
+ <ProfileUserResetPassword {isLoading} {onChangePassword} />
73
+ {:else if currentTab === "settings"}
74
+ <ProfileUserSetting
75
+ notificationPref={data.notificationPref}
76
+ enableNotification={data.enableNotification}
77
+ marketingPrefs={data.marketingPrefs}
78
+ {isLoading}
79
+ />
80
+ {/if}
81
+ </div>
82
+ </div>
83
+ </div>
@@ -0,0 +1,20 @@
1
+ import type { ProfileUserData } from "../types";
2
+ type $$ComponentProps = {
3
+ data: ProfileUserData;
4
+ activeTab?: string;
5
+ isLoading?: boolean;
6
+ onAddAddress?: () => void;
7
+ onChangePassword?: (payload: {
8
+ currentPassword: string;
9
+ newPassword: string;
10
+ confirmPassword: string;
11
+ }) => void;
12
+ onLoginAsUser?: (id: string | number) => void;
13
+ tabs?: {
14
+ id: string;
15
+ label: string;
16
+ }[];
17
+ };
18
+ declare const ProfileUser02: import("svelte").Component<$$ComponentProps, {}, "activeTab">;
19
+ type ProfileUser02 = ReturnType<typeof ProfileUser02>;
20
+ export default ProfileUser02;
@@ -0,0 +1,85 @@
1
+ <script lang="ts" module>
2
+ /**
3
+ * Variante 03 da página de perfil. Reutiliza header, tabs pill,
4
+ * moradas, segurança e definições.
5
+ * Todos os textos parametrizáveis com defaults via i18n.
6
+ * @component
7
+ */
8
+ </script>
9
+
10
+ <script lang="ts">
11
+ import { t } from "../../../../i18n";
12
+ import type { ProfileUserData } from "../types";
13
+ import ProfileUserHeader from "../shared/ProfileUserHeader.svelte";
14
+ import ProfileUserTabs from "../shared/ProfileUserTabs.svelte";
15
+ import ProfileUserAddress from "../shared/ProfileUserAddress.svelte";
16
+ import ProfileUserResetPassword from "../shared/ProfileUserResetPassword.svelte";
17
+ import ProfileUserSetting from "../shared/ProfileUserSetting.svelte";
18
+
19
+ let {
20
+ data,
21
+ activeTab = $bindable(),
22
+ isLoading = false,
23
+ onAddAddress,
24
+ onChangePassword,
25
+ onLoginAsUser,
26
+ tabs: customTabs,
27
+ }: {
28
+ data: ProfileUserData;
29
+ activeTab?: string;
30
+ isLoading?: boolean;
31
+ onAddAddress?: () => void;
32
+ onChangePassword?: (payload: {
33
+ currentPassword: string;
34
+ newPassword: string;
35
+ confirmPassword: string;
36
+ }) => void;
37
+ onLoginAsUser?: (id: string | number) => void;
38
+ tabs?: { id: string; label: string }[];
39
+ } = $props();
40
+
41
+ const defaultTabs = $derived(
42
+ customTabs?.length
43
+ ? customTabs
44
+ : [
45
+ { id: "addresses", label: $t("profile-user.variant1.tabs.addresses") || "Moradas" },
46
+ { id: "security", label: $t("profile-user.variant2.tabs.security") || "Segurança" },
47
+ { id: "settings", label: $t("profile-user.variant1.tabs.settings") || "Definições" },
48
+ ]
49
+ );
50
+
51
+ const currentTab = $derived(activeTab ?? defaultTabs[0]?.id ?? "addresses");
52
+ const fullName = $derived(data.fullName ?? `${data.firstName} ${data.lastName}`);
53
+ </script>
54
+
55
+ <div class="bg-background">
56
+ <ProfileUserHeader {data} {isLoading} {fullName} {onLoginAsUser} />
57
+
58
+ <div class="mx-auto max-w-7xl px-6">
59
+ <ProfileUserTabs
60
+ tabs={defaultTabs}
61
+ bind:activeTab
62
+ style="pill"
63
+ {isLoading}
64
+ />
65
+
66
+ <div class="pb-12">
67
+ {#if currentTab === "addresses"}
68
+ <ProfileUserAddress
69
+ addresses={data.addresses}
70
+ {isLoading}
71
+ {onAddAddress}
72
+ />
73
+ {:else if currentTab === "security"}
74
+ <ProfileUserResetPassword {isLoading} {onChangePassword} />
75
+ {:else if currentTab === "settings"}
76
+ <ProfileUserSetting
77
+ notificationPref={data.notificationPref}
78
+ enableNotification={data.enableNotification}
79
+ marketingPrefs={data.marketingPrefs}
80
+ {isLoading}
81
+ />
82
+ {/if}
83
+ </div>
84
+ </div>
85
+ </div>
@@ -0,0 +1,20 @@
1
+ import type { ProfileUserData } from "../types";
2
+ type $$ComponentProps = {
3
+ data: ProfileUserData;
4
+ activeTab?: string;
5
+ isLoading?: boolean;
6
+ onAddAddress?: () => void;
7
+ onChangePassword?: (payload: {
8
+ currentPassword: string;
9
+ newPassword: string;
10
+ confirmPassword: string;
11
+ }) => void;
12
+ onLoginAsUser?: (id: string | number) => void;
13
+ tabs?: {
14
+ id: string;
15
+ label: string;
16
+ }[];
17
+ };
18
+ declare const ProfileUser03: import("svelte").Component<$$ComponentProps, {}, "activeTab">;
19
+ type ProfileUser03 = ReturnType<typeof ProfileUser03>;
20
+ export default ProfileUser03;
@@ -0,0 +1,53 @@
1
+ <script lang="ts" module>
2
+ /**
3
+ * Página de perfil do utilizador com seleção de layout.
4
+ * Permite escolher entre três variantes.
5
+ * - **1**: Header com avatar à esquerda, tabs para moradas e definições.
6
+ * - **2**: Header com avatar à esquerda, tabs para segurança.
7
+ * - **3**: Header com avatar à esquerda, tabs pill para moradas, segurança e definições.
8
+ *
9
+ * @component
10
+ */
11
+ </script>
12
+
13
+ <script lang="ts">
14
+ import type { ProfileUserProps } from "./types";
15
+ import ProfileUser01 from "./01/ProfileUser01.svelte";
16
+ import ProfileUser02 from "./02/ProfileUser02.svelte";
17
+ import ProfileUser03 from "./03/ProfileUser03.svelte";
18
+
19
+ let {
20
+ varient = 1,
21
+ data,
22
+ activeTab,
23
+ isLoading = false,
24
+ tabs,
25
+ ...restProps
26
+ }: ProfileUserProps = $props();
27
+ </script>
28
+
29
+ {#if varient === 2}
30
+ <ProfileUser02
31
+ {data}
32
+ {activeTab}
33
+ {isLoading}
34
+ {tabs}
35
+ {...restProps}
36
+ />
37
+ {:else if varient === 3}
38
+ <ProfileUser03
39
+ {data}
40
+ {activeTab}
41
+ {isLoading}
42
+ {tabs}
43
+ {...restProps}
44
+ />
45
+ {:else}
46
+ <ProfileUser01
47
+ {data}
48
+ {activeTab}
49
+ {isLoading}
50
+ {tabs}
51
+ {...restProps}
52
+ />
53
+ {/if}
@@ -0,0 +1,4 @@
1
+ import type { ProfileUserProps } from "./types";
2
+ declare const ProfileUser: import("svelte").Component<ProfileUserProps, {}, "">;
3
+ type ProfileUser = ReturnType<typeof ProfileUser>;
4
+ export default ProfileUser;
@@ -0,0 +1,84 @@
1
+ <script lang="ts" module>
2
+ /**
3
+ * Lista de moradas do utilizador com opção de adicionar e badge para default.
4
+ * Extraído da variante 1. Todos os textos são parametrizáveis com defaults via i18n.
5
+ * @component
6
+ */
7
+ </script>
8
+
9
+ <script lang="ts">
10
+ import { MapPin } from "@hugeicons/core-free-icons";
11
+ import { HugeiconsIcon } from "@hugeicons/svelte";
12
+ import PlusIcon from "@lucide/svelte/icons/plus";
13
+ import Badge from "../../../ui/badge/badge.svelte";
14
+ import Button from "../../../ui/button/button.svelte";
15
+ import Skeleton from "../../../ui/skeleton/skeleton.svelte";
16
+ import { cn } from "../../../../utils.js";
17
+ import { t } from "../../../../i18n";
18
+ import type { ProfileUserAddress, ProfileUserAddressProps } from "../types";
19
+
20
+ let {
21
+ addresses,
22
+ isLoading = false,
23
+ onAddAddress,
24
+ className,
25
+ title = $t("profile-user.variant1.addresses.title"),
26
+ addLabel = $t("profile-user.variant1.addresses.add"),
27
+ defaultBadge = $t("profile-user.variant1.addresses.defaultBadge"),
28
+ emptyText = $t("profile-user.variant1.addresses.empty"),
29
+ }: ProfileUserAddressProps & {
30
+ addresses?: ProfileUserAddress[];
31
+ isLoading?: boolean;
32
+ } = $props();
33
+ </script>
34
+
35
+ <section
36
+ class={cn("rounded-lg border bg-card p-6", className)}
37
+ data-slot="profile-user-address"
38
+ >
39
+ <div class="mb-6 flex items-center justify-between">
40
+ <h3 class="text-lg font-semibold">{title}</h3>
41
+ <Button variant="ghost" size="sm" onclick={onAddAddress}>
42
+ <PlusIcon class="size-4" />
43
+ {addLabel}
44
+ </Button>
45
+ </div>
46
+
47
+ {#if isLoading}
48
+ <div class="grid gap-4 md:grid-cols-2">
49
+ {#each Array.from({ length: 2 }) as _, i (i)}
50
+ <Skeleton class="h-32 w-full rounded-md" />
51
+ {/each}
52
+ </div>
53
+ {:else if addresses && addresses.length > 0}
54
+ <div class="grid gap-4 md:grid-cols-2">
55
+ {#each addresses as address (address.id)}
56
+ <div
57
+ class={cn(
58
+ "rounded-md border p-4 transition-colors",
59
+ address.isDefault ? "border-primary bg-primary/5" : ""
60
+ )}
61
+ >
62
+ <div class="mb-2 flex items-center justify-between">
63
+ <span class="font-medium">{address.label}</span>
64
+ {#if address.isDefault}
65
+ <Badge>{defaultBadge}</Badge>
66
+ {/if}
67
+ </div>
68
+ <div class="flex flex-col gap-1 text-sm text-muted-foreground">
69
+ <p class="flex items-start gap-1.5">
70
+ <HugeiconsIcon icon={MapPin} class="mt-0.5 size-4 shrink-0" />
71
+ {address.street}
72
+ {#if address.apartment}, {address.apartment}{/if}
73
+ </p>
74
+ {#if address.state || address.zip}
75
+ <p class="pl-5.5">{address.state ?? ""} {address.zip ?? ""}</p>
76
+ {/if}
77
+ </div>
78
+ </div>
79
+ {/each}
80
+ </div>
81
+ {:else}
82
+ <p class="text-sm text-muted-foreground">{emptyText}</p>
83
+ {/if}
84
+ </section>
@@ -0,0 +1,8 @@
1
+ import type { ProfileUserAddress, ProfileUserAddressProps } from "../types";
2
+ type $$ComponentProps = ProfileUserAddressProps & {
3
+ addresses?: ProfileUserAddress[];
4
+ isLoading?: boolean;
5
+ };
6
+ declare const ProfileUserAddress: import("svelte").Component<$$ComponentProps, {}, "">;
7
+ type ProfileUserAddress = ReturnType<typeof ProfileUserAddress>;
8
+ export default ProfileUserAddress;
@@ -0,0 +1,104 @@
1
+ <script lang="ts" module>
2
+ /**
3
+ * Header da página de perfil: gradiente amarelo/laranja, avatar à esquerda,
4
+ * nome + status, role, email/telefone e botão "LOGIN AS USER".
5
+ * @component
6
+ */
7
+ </script>
8
+
9
+ <script lang="ts">
10
+ import {
11
+ BadgeCheckIcon,
12
+ Mail01Icon,
13
+ UserIcon,
14
+ } from "@hugeicons/core-free-icons";
15
+ import { HugeiconsIcon } from "@hugeicons/svelte";
16
+ import Avatar from "../../../ui/avatar/avatar.svelte";
17
+ import AvatarImage from "../../../ui/avatar/avatar-image.svelte";
18
+ import Badge from "../../../ui/badge/badge.svelte";
19
+ import Button from "../../../ui/button/button.svelte";
20
+ import Skeleton from "../../../ui/skeleton/skeleton.svelte";
21
+ import { t } from "../../../../i18n";
22
+ import type { ProfileUserData, ProfileUserHeaderProps } from "../types";
23
+
24
+ let {
25
+ data,
26
+ isLoading = false,
27
+ fullName,
28
+ onLoginAsUser,
29
+ statusDefault = $t("profile-user.variant1.statusActive"),
30
+ roleDefault = $t("profile-user.variant1.roleDefault"),
31
+ loginAsUserLabel = $t("profile-user.variant1.actionLoginAsUser"),
32
+ }: ProfileUserHeaderProps & {
33
+ data: ProfileUserData;
34
+ isLoading?: boolean;
35
+ fullName: string;
36
+ } = $props();
37
+ </script>
38
+
39
+ <header
40
+ class="bg-linear-to-r from-blue-400 to-blue-500 px-6 py-10 text-white"
41
+ data-slot="profile-user-header"
42
+ >
43
+ <div class="mx-auto max-w-7xl">
44
+ <div
45
+ class="flex flex-col gap-6 md:flex-row md:items-center md:justify-between"
46
+ >
47
+ <div class="flex items-center gap-5">
48
+ {#if isLoading}
49
+ <Skeleton class="size-24 rounded-full" />
50
+ {:else}
51
+ <Avatar size="lg" class="size-24 ring-4 ring-white/30">
52
+ <AvatarImage src={data.avatarUrl} alt={fullName} />
53
+ </Avatar>
54
+ {/if}
55
+ <div class="flex flex-col gap-2">
56
+ {#if isLoading}
57
+ <Skeleton class="h-8 w-48 rounded-md bg-white/30" />
58
+ <Skeleton class="h-5 w-36 rounded-md bg-white/20" />
59
+ <Skeleton class="h-4 w-44 rounded-md bg-white/20" />
60
+ {:else}
61
+ <div class="flex items-center gap-2">
62
+ <h1 class="text-2xl font-bold text-white">{fullName}</h1>
63
+ <Badge
64
+ variant="secondary"
65
+ class="bg-white/20 text-white hover:bg-white/30"
66
+ >
67
+ <HugeiconsIcon icon={BadgeCheckIcon} />
68
+ {data.status ?? statusDefault}
69
+ </Badge>
70
+ </div>
71
+ <p class="text-base font-medium text-white/90">
72
+ {data.role ?? roleDefault}
73
+ </p>
74
+ <div class="flex items-center gap-4 text-sm text-white/80">
75
+ <span class="flex items-center gap-1.5">
76
+ <HugeiconsIcon icon={Mail01Icon} class="size-4" />
77
+ {data.email}
78
+ </span>
79
+ {#if data.phone}
80
+ <span class="flex items-center gap-1.5">
81
+ <HugeiconsIcon icon={UserIcon} class="size-4" />
82
+ {data.phone}
83
+ </span>
84
+ {/if}
85
+ </div>
86
+ {/if}
87
+ </div>
88
+ </div>
89
+ <div>
90
+ {#if isLoading}
91
+ <Skeleton class="h-9 w-36 rounded-md bg-white/30" />
92
+ {:else}
93
+ <Button
94
+ variant="outline"
95
+ class="border-white/30 bg-white/10 text-white hover:bg-white/20 hover:text-white"
96
+ onclick={() => onLoginAsUser?.(data.id)}
97
+ >
98
+ {loginAsUserLabel}
99
+ </Button>
100
+ {/if}
101
+ </div>
102
+ </div>
103
+ </div>
104
+ </header>
@@ -0,0 +1,9 @@
1
+ import type { ProfileUserData, ProfileUserHeaderProps } from "../types";
2
+ type $$ComponentProps = ProfileUserHeaderProps & {
3
+ data: ProfileUserData;
4
+ isLoading?: boolean;
5
+ fullName: string;
6
+ };
7
+ declare const ProfileUserHeader: import("svelte").Component<$$ComponentProps, {}, "">;
8
+ type ProfileUserHeader = ReturnType<typeof ProfileUserHeader>;
9
+ export default ProfileUserHeader;
@@ -0,0 +1,116 @@
1
+ <script lang="ts" module>
2
+ /**
3
+ * Formulário de alteração de senha da variante 2 (aba "Security").
4
+ * Contém campos Current password, New password e Confirm new password,
5
+ * além dos botões Update Password e Cancel.
6
+ * @component
7
+ */
8
+ </script>
9
+
10
+ <script lang="ts">
11
+ import Button from "../../../ui/button/button.svelte";
12
+ import Input from "../../../ui/input/input.svelte";
13
+ import Label from "../../../ui/label/label.svelte";
14
+ import Skeleton from "../../../ui/skeleton/skeleton.svelte";
15
+ import { cn } from "../../../../utils.js";
16
+ import { t } from "../../../../i18n";
17
+ import type { ProfileUserResetPasswordProps } from "../types";
18
+
19
+ let {
20
+ isLoading = false,
21
+ className,
22
+ onChangePassword,
23
+ onCancel,
24
+ title = $t("profile-user.resetPassword.title"),
25
+ currentLabel = $t("profile-user.resetPassword.current.label"),
26
+ currentPlaceholder = $t("profile-user.resetPassword.current.placeholder"),
27
+ newLabel = $t("profile-user.resetPassword.new.label"),
28
+ newPlaceholder = $t("profile-user.resetPassword.new.placeholder"),
29
+ confirmLabel = $t("profile-user.resetPassword.confirm.label"),
30
+ confirmPlaceholder = $t("profile-user.resetPassword.confirm.placeholder"),
31
+ submitLabel = $t("profile-user.resetPassword.submit"),
32
+ cancelLabel = $t("profile-user.resetPassword.cancel"),
33
+ }: ProfileUserResetPasswordProps & {
34
+ isLoading?: boolean;
35
+ } = $props();
36
+
37
+ let currentPassword = $state("");
38
+ let newPassword = $state("");
39
+ let confirmPassword = $state("");
40
+
41
+ const handleSubmit = () => {
42
+ onChangePassword?.({
43
+ currentPassword,
44
+ newPassword,
45
+ confirmPassword,
46
+ });
47
+ };
48
+
49
+ const handleCancel = () => {
50
+ currentPassword = "";
51
+ newPassword = "";
52
+ confirmPassword = "";
53
+ onCancel?.();
54
+ };
55
+ </script>
56
+
57
+ <section class={cn("rounded-lg border bg-card p-6", className)} data-slot="profile-user-reset-password">
58
+ <h3 class="mb-6 text-lg font-semibold">{title}</h3>
59
+
60
+ <form
61
+ class="flex max-w-md flex-col gap-5"
62
+ onsubmit={(e) => {
63
+ e.preventDefault();
64
+ handleSubmit();
65
+ }}
66
+ >
67
+ <div class="flex flex-col gap-2">
68
+ <Label for="currentPassword">{currentLabel}</Label>
69
+ {#if isLoading}
70
+ <Skeleton class="h-9 w-full rounded-md" />
71
+ {:else}
72
+ <Input
73
+ id="currentPassword"
74
+ type="password"
75
+ bind:value={currentPassword}
76
+ placeholder={currentPlaceholder}
77
+ />
78
+ {/if}
79
+ </div>
80
+
81
+ <div class="flex flex-col gap-2">
82
+ <Label for="newPassword">{newLabel}</Label>
83
+ {#if isLoading}
84
+ <Skeleton class="h-9 w-full rounded-md" />
85
+ {:else}
86
+ <Input
87
+ id="newPassword"
88
+ type="password"
89
+ bind:value={newPassword}
90
+ placeholder={newPlaceholder}
91
+ />
92
+ {/if}
93
+ </div>
94
+
95
+ <div class="flex flex-col gap-2">
96
+ <Label for="confirmPassword">{confirmLabel}</Label>
97
+ {#if isLoading}
98
+ <Skeleton class="h-9 w-full rounded-md" />
99
+ {:else}
100
+ <Input
101
+ id="confirmPassword"
102
+ type="password"
103
+ bind:value={confirmPassword}
104
+ placeholder={confirmPlaceholder}
105
+ />
106
+ {/if}
107
+ </div>
108
+
109
+ <div class="flex gap-3 pt-2">
110
+ <Button type="submit" disabled={isLoading}>{submitLabel}</Button>
111
+ <Button type="button" variant="outline" onclick={handleCancel} disabled={isLoading}>
112
+ {cancelLabel}
113
+ </Button>
114
+ </div>
115
+ </form>
116
+ </section>
@@ -0,0 +1,7 @@
1
+ import type { ProfileUserResetPasswordProps } from "../types";
2
+ type $$ComponentProps = ProfileUserResetPasswordProps & {
3
+ isLoading?: boolean;
4
+ };
5
+ declare const ProfileUserResetPassword: import("svelte").Component<$$ComponentProps, {}, "">;
6
+ type ProfileUserResetPassword = ReturnType<typeof ProfileUserResetPassword>;
7
+ export default ProfileUserResetPassword;