negodesign 0.0.29 → 0.0.31
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/assets/lonely-404.mp4 +0 -0
- package/dist/components/core/banner/AdCardBanner.svelte.d.ts +4 -0
- package/dist/components/core/banner/CtaCardBanner.svelte +118 -0
- package/dist/components/core/banner/CtaCardBanner.svelte.d.ts +4 -0
- package/dist/components/core/banner/{BannerNotification.svelte → NotificationBanner.svelte} +4 -3
- package/dist/components/core/banner/NotificationBanner.svelte.d.ts +4 -0
- package/dist/components/core/banner/types.d.ts +38 -7
- package/dist/components/core/card/highlight/01/CardHighlight01.svelte +15 -26
- package/dist/components/core/card/highlight/02/CardHighlight02.svelte +13 -24
- package/dist/components/core/card/media/01/CardMedia01.svelte +2 -12
- package/dist/components/core/card/media/02/CardMedia02.svelte +2 -12
- package/dist/components/core/card/promotion/CardPromotion.svelte +5 -1
- package/dist/components/core/card/shared/CardButton.svelte +9 -3
- package/dist/components/core/card/shared/CardButton.svelte.d.ts +1 -1
- package/dist/components/core/card/shared/CardLogo.svelte +19 -0
- package/dist/components/core/card/shared/CardLogo.svelte.d.ts +7 -0
- package/dist/components/core/card/shared/CardThumbnailVideo.svelte +3 -0
- package/dist/components/core/card/types.d.ts +97 -0
- package/dist/components/core/carousel/grid/media/types.d.ts +11 -0
- package/dist/components/core/carousel/grid/media/ui/CarouselGridMedia.svelte +2 -1
- package/dist/components/core/carousel/grid/profile/types.d.ts +11 -0
- package/dist/components/core/carousel/grid/profile/ui/CarouselGridProfile.svelte +3 -5
- package/dist/components/core/carousel/grid/shared/ui/CarouselGridSlot.svelte +4 -9
- package/dist/components/core/carousel/grid/shared/ui/CarouselGridSlot.svelte.d.ts +1 -0
- package/dist/components/core/carousel/highlights/types.d.ts +11 -0
- package/dist/components/core/carousel/promotion/types.d.ts +10 -0
- package/dist/components/core/carousel/types.d.ts +56 -0
- package/dist/components/core/datatable/data/data-table.d.ts +25 -0
- package/dist/components/core/footer/types.d.ts +51 -0
- package/dist/components/core/footer/types.js +1 -0
- package/dist/components/core/footer/ui/01/Footer01.svelte +76 -0
- package/dist/components/core/footer/ui/01/Footer01.svelte.d.ts +4 -0
- package/dist/components/core/footer/ui/02/Footer02.svelte +53 -0
- package/dist/components/core/footer/ui/02/Footer02.svelte.d.ts +4 -0
- package/dist/components/core/footer/ui/Footer.svelte +18 -0
- package/dist/components/core/footer/ui/Footer.svelte.d.ts +7 -0
- package/dist/components/core/footer/ui/shared/FooterColumn.svelte +18 -0
- package/dist/components/core/footer/ui/shared/FooterColumn.svelte.d.ts +4 -0
- package/dist/components/core/footer/ui/shared/FooterNewsLetter.svelte +57 -0
- package/dist/components/core/footer/ui/shared/FooterNewsLetter.svelte.d.ts +9 -0
- package/dist/components/core/footer/ui/shared/FooterSocialIcon.svelte +62 -0
- package/dist/components/core/footer/ui/shared/FooterSocialIcon.svelte.d.ts +4 -0
- package/dist/components/core/nav/data/nav-menu-sidebar.d.ts +29 -0
- package/dist/components/core/nav/data/nav-menu.d.ts +43 -0
- package/dist/components/core/nav/data/nav-user-sidebar.d.ts +14 -0
- package/dist/components/core/nav/ui/menu-links.svelte +1 -1
- package/dist/components/core/panel/CarouselSlot.svelte +2 -2
- package/dist/components/core/panel/LeftHero.svelte +2 -2
- package/dist/components/core/panel/type.d.ts +11 -0
- package/dist/components/core/search/types.d.ts +17 -5
- package/dist/components/core/sidebar/types.d.ts +19 -0
- package/dist/components/core/sidebar/types.js +1 -0
- package/dist/components/core/tabs/data/TabModel.d.ts +11 -0
- package/dist/components/core/tabs/types.d.ts +11 -0
- package/dist/components/core/tabs/types.js +1 -0
- package/dist/components/pages/admin/01/ui/types.d.ts +21 -0
- package/dist/components/pages/admin/01/ui/types.js +1 -0
- package/dist/components/pages/product-details/01/ProductDetails01.svelte +71 -0
- package/dist/components/pages/product-details/01/ProductDetails01.svelte.d.ts +11 -0
- package/dist/components/pages/product-details/02/ProductDetails02.svelte +88 -0
- package/dist/components/pages/product-details/02/ProductDetails02.svelte.d.ts +11 -0
- package/dist/components/pages/product-details/03/ProductDetails03.svelte +77 -0
- package/dist/components/pages/product-details/03/ProductDetails03.svelte.d.ts +11 -0
- package/dist/components/pages/product-details/04/ProductDetails04.svelte +65 -0
- package/dist/components/pages/product-details/04/ProductDetails04.svelte.d.ts +11 -0
- package/dist/components/pages/product-details/ProductDetails.svelte +38 -0
- package/dist/components/pages/product-details/ProductDetails.svelte.d.ts +4 -0
- package/dist/components/pages/product-details/shared/ProductDetailActions.svelte +82 -0
- package/dist/components/pages/product-details/shared/ProductDetailActions.svelte.d.ts +13 -0
- package/dist/components/pages/product-details/shared/ProductDetailBreadcrumb.svelte +46 -0
- package/dist/components/pages/product-details/shared/ProductDetailBreadcrumb.svelte.d.ts +8 -0
- package/dist/components/pages/product-details/shared/ProductDetailDescription.svelte +38 -0
- package/dist/components/pages/product-details/shared/ProductDetailDescription.svelte.d.ts +8 -0
- package/dist/components/pages/product-details/shared/ProductDetailFeatures.svelte +40 -0
- package/dist/components/pages/product-details/shared/ProductDetailFeatures.svelte.d.ts +7 -0
- package/dist/components/pages/product-details/shared/ProductDetailFilesVertical.svelte +72 -0
- package/dist/components/pages/product-details/shared/ProductDetailFilesVertical.svelte.d.ts +9 -0
- package/dist/components/pages/product-details/shared/ProductDetailHeader.svelte +41 -0
- package/dist/components/pages/product-details/shared/ProductDetailHeader.svelte.d.ts +9 -0
- package/dist/components/pages/product-details/shared/ProductDetailImage.svelte +70 -0
- package/dist/components/pages/product-details/shared/ProductDetailImage.svelte.d.ts +9 -0
- package/dist/components/pages/product-details/shared/ProductDetailMap.svelte +57 -0
- package/dist/components/pages/product-details/shared/ProductDetailMap.svelte.d.ts +9 -0
- package/dist/components/pages/product-details/shared/ProductDetailPrice.svelte +44 -0
- package/dist/components/pages/product-details/shared/ProductDetailPrice.svelte.d.ts +9 -0
- package/dist/components/pages/product-details/shared/ProductDetailRating.svelte +42 -0
- package/dist/components/pages/product-details/shared/ProductDetailRating.svelte.d.ts +8 -0
- package/dist/components/pages/product-details/shared/ProductDetailReviews.svelte +70 -0
- package/dist/components/pages/product-details/shared/ProductDetailReviews.svelte.d.ts +8 -0
- package/dist/components/pages/product-details/shared/ProductDetailTabs.svelte +96 -0
- package/dist/components/pages/product-details/shared/ProductDetailTabs.svelte.d.ts +12 -0
- package/dist/components/pages/product-details/shared/ProductDetailTags.svelte +35 -0
- package/dist/components/pages/product-details/shared/ProductDetailTags.svelte.d.ts +8 -0
- package/dist/components/pages/product-details/shared/ProductPurchasePanel.svelte +58 -0
- package/dist/components/pages/product-details/shared/ProductPurchasePanel.svelte.d.ts +11 -0
- package/dist/components/pages/product-details/types.d.ts +170 -0
- package/dist/components/pages/product-details/types.js +1 -0
- package/dist/components/pages/profile-user/01/ProfileUser01.svelte +113 -0
- package/dist/components/pages/profile-user/01/ProfileUser01.svelte.d.ts +27 -0
- package/dist/components/pages/profile-user/02/ProfileUser02.svelte +83 -0
- package/dist/components/pages/profile-user/02/ProfileUser02.svelte.d.ts +20 -0
- package/dist/components/pages/profile-user/03/ProfileUser03.svelte +85 -0
- package/dist/components/pages/profile-user/03/ProfileUser03.svelte.d.ts +20 -0
- package/dist/components/pages/profile-user/ProfileUser.svelte +53 -0
- package/dist/components/pages/profile-user/ProfileUser.svelte.d.ts +4 -0
- package/dist/components/pages/profile-user/shared/ProfileUserAddress.svelte +84 -0
- package/dist/components/pages/profile-user/shared/ProfileUserAddress.svelte.d.ts +8 -0
- package/dist/components/pages/profile-user/shared/ProfileUserHeader.svelte +104 -0
- package/dist/components/pages/profile-user/shared/ProfileUserHeader.svelte.d.ts +9 -0
- package/dist/components/pages/profile-user/shared/ProfileUserResetPassword.svelte +116 -0
- package/dist/components/pages/profile-user/shared/ProfileUserResetPassword.svelte.d.ts +7 -0
- package/dist/components/pages/profile-user/shared/ProfileUserSetting.svelte +176 -0
- package/dist/components/pages/profile-user/shared/ProfileUserSetting.svelte.d.ts +14 -0
- package/dist/components/pages/profile-user/shared/ProfileUserTabs.svelte +78 -0
- package/dist/components/pages/profile-user/shared/ProfileUserTabs.svelte.d.ts +22 -0
- package/dist/components/pages/profile-user/types.d.ts +144 -0
- package/dist/components/pages/profile-user/types.js +1 -0
- package/dist/globals.css +319 -4
- package/dist/i18n/langs/en.d.ts +87 -0
- package/dist/i18n/langs/en.js +87 -0
- package/dist/i18n/langs/pt.d.ts +87 -0
- package/dist/i18n/langs/pt.js +93 -6
- package/dist/i18n/translations.d.ts +174 -0
- package/dist/index.d.ts +194 -27
- package/dist/index.js +194 -27
- package/dist/styles/globals.css +1 -1
- package/dist/types/index.d.ts +196 -5
- package/package.json +1 -1
- package/dist/components/core/banner/BannerNotification.svelte.d.ts +0 -4
- package/dist/components/core/banner/CardAdBanner.svelte.d.ts +0 -4
- /package/dist/components/core/banner/{CardAdBanner.svelte → AdCardBanner.svelte} +0 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
/**
|
|
3
|
+
* Painel de compra do produto: avaliação, preço e ações.
|
|
4
|
+
* Compõe ProductDetailRating, ProductDetailPrice e ProductDetailActions.
|
|
5
|
+
* @component
|
|
6
|
+
* @example
|
|
7
|
+
* ```svelte
|
|
8
|
+
* <ProductPurchasePanel {data} isLoading={true} />
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<script lang="ts">
|
|
14
|
+
import ProductDetailActions from "./ProductDetailActions.svelte";
|
|
15
|
+
import ProductDetailPrice from "./ProductDetailPrice.svelte";
|
|
16
|
+
import ProductDetailRating from "./ProductDetailRating.svelte";
|
|
17
|
+
import type { ProductDetailsData } from "../types";
|
|
18
|
+
|
|
19
|
+
let {
|
|
20
|
+
data,
|
|
21
|
+
isLoading = false,
|
|
22
|
+
onBuy,
|
|
23
|
+
onFavorite,
|
|
24
|
+
onCart,
|
|
25
|
+
}: {
|
|
26
|
+
data: ProductDetailsData;
|
|
27
|
+
isLoading?: boolean;
|
|
28
|
+
onBuy?: (id: string | number) => void;
|
|
29
|
+
onFavorite?: (id: string | number) => void;
|
|
30
|
+
onCart?: (id: string | number) => void;
|
|
31
|
+
} = $props();
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<div class="flex flex-col gap-4">
|
|
35
|
+
<ProductDetailRating
|
|
36
|
+
rating={data.rating}
|
|
37
|
+
reviewsCount={data.reviewsCount}
|
|
38
|
+
{isLoading}
|
|
39
|
+
/>
|
|
40
|
+
|
|
41
|
+
<ProductDetailPrice
|
|
42
|
+
newPrice={data.newPrice}
|
|
43
|
+
oldPrice={data.oldPrice}
|
|
44
|
+
currency={data.currency}
|
|
45
|
+
{isLoading}
|
|
46
|
+
/>
|
|
47
|
+
|
|
48
|
+
<ProductDetailActions
|
|
49
|
+
id={data.id}
|
|
50
|
+
buttonBuyText={data.buttonBuyText}
|
|
51
|
+
isFavorite={data.isFavorite}
|
|
52
|
+
isCart={data.isCart}
|
|
53
|
+
{isLoading}
|
|
54
|
+
{onBuy}
|
|
55
|
+
{onFavorite}
|
|
56
|
+
{onCart}
|
|
57
|
+
/>
|
|
58
|
+
</div>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ProductDetailsData } from "../types";
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
data: ProductDetailsData;
|
|
4
|
+
isLoading?: boolean;
|
|
5
|
+
onBuy?: (id: string | number) => void;
|
|
6
|
+
onFavorite?: (id: string | number) => void;
|
|
7
|
+
onCart?: (id: string | number) => void;
|
|
8
|
+
};
|
|
9
|
+
declare const ProductPurchasePanel: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
10
|
+
type ProductPurchasePanel = ReturnType<typeof ProductPurchasePanel>;
|
|
11
|
+
export default ProductPurchasePanel;
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import type { IconSvgElement } from "@hugeicons/svelte";
|
|
2
|
+
/**
|
|
3
|
+
* Item individual do breadcrumb de navegação.
|
|
4
|
+
* Representa um nível hierárquico na navegação da página
|
|
5
|
+
* (ex: Home / Turismo / Hotel Baía Azul).
|
|
6
|
+
*/
|
|
7
|
+
export interface ProductDetailsBreadcrumbItem {
|
|
8
|
+
/** Texto visível do item no breadcrumb. */
|
|
9
|
+
label: string;
|
|
10
|
+
/** URL de destino quando o item é clicável (último item geralmente não tem href). */
|
|
11
|
+
href?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Tag/badge associada ao produto.
|
|
15
|
+
* Usada para destacar categorias, localização ou características rápidas.
|
|
16
|
+
*/
|
|
17
|
+
export interface ProductDetailsTag {
|
|
18
|
+
/** Ícone opcional exibido antes do texto da tag. */
|
|
19
|
+
icon?: IconSvgElement;
|
|
20
|
+
/** Texto principal da tag (ex: "Luanda", "5 Estrelas"). */
|
|
21
|
+
text: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Imagem da galeria do produto.
|
|
25
|
+
* Cada imagem pode ter um texto alternativo para acessibilidade.
|
|
26
|
+
*/
|
|
27
|
+
export interface ProductDetailsImage {
|
|
28
|
+
/** Caminho ou URL completa da imagem (obrigatório). */
|
|
29
|
+
src: string;
|
|
30
|
+
/** Texto alternativo para acessibilidade (recomendado). */
|
|
31
|
+
alt?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Informações de localização do produto.
|
|
35
|
+
* Usada para exibir o mapa embed e detalhes do endereço.
|
|
36
|
+
*/
|
|
37
|
+
export interface ProductDetailsLocation {
|
|
38
|
+
/** Nome/título da localização (ex: "Morro da Luz"). */
|
|
39
|
+
label?: string;
|
|
40
|
+
/** Endereço completo ou parcial para exibição. */
|
|
41
|
+
address?: string;
|
|
42
|
+
/**
|
|
43
|
+
* URL do embed do mapa.
|
|
44
|
+
* Suporta OpenStreetMap, Google Maps e outros serviços de embed.
|
|
45
|
+
* Se não for fornecido, usa um mapa padrão.
|
|
46
|
+
*/
|
|
47
|
+
mapUrl?: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Avaliação de um cliente sobre o produto.
|
|
51
|
+
* Contém autor, classificação, data e comentário.
|
|
52
|
+
*/
|
|
53
|
+
export interface ProductDetailsReview {
|
|
54
|
+
/** Identificador único da avaliação (usado como key nos {#each}). */
|
|
55
|
+
id: string | number;
|
|
56
|
+
/** Nome do autor da avaliação. */
|
|
57
|
+
author: string;
|
|
58
|
+
/**
|
|
59
|
+
* Classificação numérica (ex: 4.5 de 5).
|
|
60
|
+
* Geralmente um valor entre 0 e 5.
|
|
61
|
+
*/
|
|
62
|
+
rating: number;
|
|
63
|
+
/** Data da avaliação (formato string, ex: "12/08/2024"). */
|
|
64
|
+
date?: string;
|
|
65
|
+
/** Comentário/texto completo da avaliação. */
|
|
66
|
+
comment: string;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Aba de conteúdo adicional no produto.
|
|
70
|
+
* Usada para organizar descrição, avaliações, detalhes técnicos, etc.
|
|
71
|
+
*/
|
|
72
|
+
export interface ProductDetailsTab {
|
|
73
|
+
/** Identificador único da aba (ex: "description", "reviews"). */
|
|
74
|
+
id: string;
|
|
75
|
+
/** Rótulo visível no botão da aba. */
|
|
76
|
+
label: string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Dados completos apresentados na página de detalhes do produto.
|
|
80
|
+
* Interface principal que agrega todas as informações necessárias
|
|
81
|
+
* para renderizar qualquer variante do componente.
|
|
82
|
+
*/
|
|
83
|
+
export interface ProductDetailsData {
|
|
84
|
+
/** Identificador único do produto. */
|
|
85
|
+
id: string | number;
|
|
86
|
+
/** Itens do breadcrumb de navegação. */
|
|
87
|
+
breadcrumb: ProductDetailsBreadcrumbItem[];
|
|
88
|
+
/** Título principal do produto (nome). */
|
|
89
|
+
title: string;
|
|
90
|
+
/** Subtítulo opcional (slogan ou descrição curta). */
|
|
91
|
+
subtitle?: string;
|
|
92
|
+
/** Descrição curta do produto. */
|
|
93
|
+
description: string;
|
|
94
|
+
/** Descrição longa/detalhada (opcional). */
|
|
95
|
+
longDescription?: string;
|
|
96
|
+
/** Lista de tags/categorias associadas ao produto. */
|
|
97
|
+
tags?: ProductDetailsTag[];
|
|
98
|
+
/** Galeria de imagens do produto. */
|
|
99
|
+
gallery: ProductDetailsImage[];
|
|
100
|
+
/** Informações de localização para exibir no mapa. */
|
|
101
|
+
location?: ProductDetailsLocation;
|
|
102
|
+
/**
|
|
103
|
+
* Classificação média do produto.
|
|
104
|
+
* Valor entre 0 e 5 (ex: 4.2).
|
|
105
|
+
*/
|
|
106
|
+
rating?: number;
|
|
107
|
+
/** Número total de avaliações recebidas. */
|
|
108
|
+
reviewsCount?: number;
|
|
109
|
+
/** Lista de avaliações individuais dos clientes. */
|
|
110
|
+
reviews?: ProductDetailsReview[];
|
|
111
|
+
/** Preço atual/promocional do produto. */
|
|
112
|
+
newPrice?: string | number;
|
|
113
|
+
/** Preço original (antes do desconto). */
|
|
114
|
+
oldPrice?: string | number;
|
|
115
|
+
/** Símbolo da moeda (ex: "Kz", "€", "$"). */
|
|
116
|
+
currency?: string;
|
|
117
|
+
/** Quantidade disponível em stock. */
|
|
118
|
+
quantityAvailable?: number;
|
|
119
|
+
/** Lista de características/features do produto (strings). */
|
|
120
|
+
features?: string[];
|
|
121
|
+
/**
|
|
122
|
+
* Abas de conteúdo personalizadas.
|
|
123
|
+
* Se não for fornecido, usa padrão: Descrição + Avaliações.
|
|
124
|
+
*/
|
|
125
|
+
tabs?: ProductDetailsTab[];
|
|
126
|
+
/** Texto customizado para o botão de compra (padrão: "Comprar"). */
|
|
127
|
+
buttonBuyText?: string;
|
|
128
|
+
/** Estado inicial do produto no carrinho. */
|
|
129
|
+
isCart?: boolean;
|
|
130
|
+
/** Estado inicial do produto nos favoritos. */
|
|
131
|
+
isFavorite?: boolean;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Propriedades do componente principal ProductDetails.
|
|
135
|
+
* Suporta quatro variantes de layout e callbacks de interação.
|
|
136
|
+
*/
|
|
137
|
+
export interface ProductDetailsProps {
|
|
138
|
+
/**
|
|
139
|
+
* Variante do layout da página de detalhes.
|
|
140
|
+
* - 1: Duas colunas (galeria à esquerda, info à direita)
|
|
141
|
+
* - 2: Galeria em destaque com conteúdo centralizado
|
|
142
|
+
* - 3: Painel de compra sticky no lado direito
|
|
143
|
+
* - 4: Abas de conteúdo (descrição e avaliações) abaixo da info
|
|
144
|
+
* @default 1
|
|
145
|
+
*/
|
|
146
|
+
varient?: 1 | 2 | 3 | 4;
|
|
147
|
+
/** Dados completos do produto a serem exibidos. */
|
|
148
|
+
data: ProductDetailsData;
|
|
149
|
+
/**
|
|
150
|
+
* Estado de carregamento.
|
|
151
|
+
* Quando true, todos os blocos exibem Skeletons no lugar do conteúdo.
|
|
152
|
+
* @default false
|
|
153
|
+
*/
|
|
154
|
+
isLoading?: boolean;
|
|
155
|
+
/**
|
|
156
|
+
* Callback executado quando o utilizador clica no botão de compra.
|
|
157
|
+
* Recebe o id do produto como argumento.
|
|
158
|
+
*/
|
|
159
|
+
onBuy?: (id: string | number) => void;
|
|
160
|
+
/**
|
|
161
|
+
* Callback executado quando o utilizador clica no botão de favorito.
|
|
162
|
+
* Recebe o id do produto como argumento.
|
|
163
|
+
*/
|
|
164
|
+
onFavorite?: (id: string | number) => void;
|
|
165
|
+
/**
|
|
166
|
+
* Callback executado quando o utilizador clica no botão de carrinho.
|
|
167
|
+
* Recebe o id do produto como argumento.
|
|
168
|
+
*/
|
|
169
|
+
onCart?: (id: string | number) => void;
|
|
170
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
/**
|
|
3
|
+
* Variante 01 da página de perfil. Reutiliza headers partilhados,
|
|
4
|
+
* tabs, 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
|
+
onLoginAsUser,
|
|
23
|
+
onAddAddress,
|
|
24
|
+
onChangePassword,
|
|
25
|
+
tabs: customTabs,
|
|
26
|
+
// Header V1
|
|
27
|
+
statusDefault = $t("profile-user.variant1.statusActive"),
|
|
28
|
+
roleDefault = $t("profile-user.variant1.roleAdministrator"),
|
|
29
|
+
loginAsUserLabel = $t("profile-user.variant1.loginAsUser"),
|
|
30
|
+
// Address
|
|
31
|
+
addressesTitle = $t("profile-user.variant1.addresses.title"),
|
|
32
|
+
addressesAddLabel = $t("profile-user.variant1.addresses.add"),
|
|
33
|
+
addressesDefaultBadge = $t("profile-user.variant1.addresses.defaultBadge"),
|
|
34
|
+
addressesEmptyText = $t("profile-user.variant1.addresses.empty"),
|
|
35
|
+
}: {
|
|
36
|
+
data: ProfileUserData;
|
|
37
|
+
activeTab?: string;
|
|
38
|
+
isLoading?: boolean;
|
|
39
|
+
onLoginAsUser?: (id: string | number) => void;
|
|
40
|
+
onAddAddress?: () => void;
|
|
41
|
+
onChangePassword?: (payload: {
|
|
42
|
+
currentPassword: string;
|
|
43
|
+
newPassword: string;
|
|
44
|
+
confirmPassword: string;
|
|
45
|
+
}) => void;
|
|
46
|
+
tabs?: { id: string; label: string }[];
|
|
47
|
+
// Header V1
|
|
48
|
+
statusDefault?: string;
|
|
49
|
+
roleDefault?: string;
|
|
50
|
+
loginAsUserLabel?: string;
|
|
51
|
+
// Address
|
|
52
|
+
addressesTitle?: string;
|
|
53
|
+
addressesAddLabel?: string;
|
|
54
|
+
addressesDefaultBadge?: string;
|
|
55
|
+
addressesEmptyText?: string;
|
|
56
|
+
} = $props();
|
|
57
|
+
|
|
58
|
+
const defaultTabs = $derived(
|
|
59
|
+
customTabs?.length
|
|
60
|
+
? customTabs
|
|
61
|
+
: [
|
|
62
|
+
{ id: "addresses", label: $t("profile-user.variant1.tabs.addresses") || "Moradas" },
|
|
63
|
+
{ id: "security", label: $t("profile-user.variant2.tabs.security") || "Segurança" },
|
|
64
|
+
{ id: "settings", label: $t("profile-user.variant1.tabs.settings") || "Definições" },
|
|
65
|
+
]
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
const currentTab = $derived(activeTab ?? defaultTabs[0]?.id ?? "addresses");
|
|
69
|
+
const fullName = $derived(data.fullName ?? `${data.firstName} ${data.lastName}`);
|
|
70
|
+
</script>
|
|
71
|
+
|
|
72
|
+
<div class="bg-background">
|
|
73
|
+
<ProfileUserHeader
|
|
74
|
+
{data}
|
|
75
|
+
{isLoading}
|
|
76
|
+
{fullName}
|
|
77
|
+
{onLoginAsUser}
|
|
78
|
+
{statusDefault}
|
|
79
|
+
{roleDefault}
|
|
80
|
+
{loginAsUserLabel}
|
|
81
|
+
/>
|
|
82
|
+
|
|
83
|
+
<div class="mx-auto max-w-7xl px-6 py-8">
|
|
84
|
+
<ProfileUserTabs
|
|
85
|
+
tabs={defaultTabs}
|
|
86
|
+
bind:activeTab
|
|
87
|
+
{isLoading}
|
|
88
|
+
/>
|
|
89
|
+
|
|
90
|
+
<div class="flex flex-col gap-8">
|
|
91
|
+
{#if currentTab === "addresses"}
|
|
92
|
+
<ProfileUserAddress
|
|
93
|
+
addresses={data.addresses}
|
|
94
|
+
{isLoading}
|
|
95
|
+
{onAddAddress}
|
|
96
|
+
title={addressesTitle}
|
|
97
|
+
addLabel={addressesAddLabel}
|
|
98
|
+
defaultBadge={addressesDefaultBadge}
|
|
99
|
+
emptyText={addressesEmptyText}
|
|
100
|
+
/>
|
|
101
|
+
{:else if currentTab === "security"}
|
|
102
|
+
<ProfileUserResetPassword {isLoading} {onChangePassword} />
|
|
103
|
+
{:else if currentTab === "settings"}
|
|
104
|
+
<ProfileUserSetting
|
|
105
|
+
notificationPref={data.notificationPref}
|
|
106
|
+
enableNotification={data.enableNotification}
|
|
107
|
+
marketingPrefs={data.marketingPrefs}
|
|
108
|
+
{isLoading}
|
|
109
|
+
/>
|
|
110
|
+
{/if}
|
|
111
|
+
</div>
|
|
112
|
+
</div>
|
|
113
|
+
</div>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ProfileUserData } from "../types";
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
data: ProfileUserData;
|
|
4
|
+
activeTab?: string;
|
|
5
|
+
isLoading?: boolean;
|
|
6
|
+
onLoginAsUser?: (id: string | number) => void;
|
|
7
|
+
onAddAddress?: () => void;
|
|
8
|
+
onChangePassword?: (payload: {
|
|
9
|
+
currentPassword: string;
|
|
10
|
+
newPassword: string;
|
|
11
|
+
confirmPassword: string;
|
|
12
|
+
}) => void;
|
|
13
|
+
tabs?: {
|
|
14
|
+
id: string;
|
|
15
|
+
label: string;
|
|
16
|
+
}[];
|
|
17
|
+
statusDefault?: string;
|
|
18
|
+
roleDefault?: string;
|
|
19
|
+
loginAsUserLabel?: string;
|
|
20
|
+
addressesTitle?: string;
|
|
21
|
+
addressesAddLabel?: string;
|
|
22
|
+
addressesDefaultBadge?: string;
|
|
23
|
+
addressesEmptyText?: string;
|
|
24
|
+
};
|
|
25
|
+
declare const ProfileUser01: import("svelte").Component<$$ComponentProps, {}, "activeTab">;
|
|
26
|
+
type ProfileUser01 = ReturnType<typeof ProfileUser01>;
|
|
27
|
+
export default ProfileUser01;
|
|
@@ -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}
|