negodesign 0.0.42 → 0.0.44
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/core/card/product/01/CardProduct01.svelte +6 -0
- package/dist/components/core/card/product/02/CardProduct02.svelte +6 -0
- package/dist/components/core/card/product/data.js +1 -1
- package/dist/components/core/footer/ui/01/Footer01.svelte +0 -9
- package/dist/components/pages/privacy-policy-or-terms-of-use/01/PrivacyPolicyOrTermsOfUse01.svelte +20 -10
- package/dist/components/pages/privacy-policy-or-terms-of-use/01/PrivacyPolicyOrTermsOfUse01.svelte.d.ts +2 -5
- package/dist/components/pages/privacy-policy-or-terms-of-use/02/PrivacyPolicyOrTermsOfUse02.svelte +3 -3
- package/dist/components/pages/privacy-policy-or-terms-of-use/02/PrivacyPolicyOrTermsOfUse02.svelte.d.ts +2 -5
- package/dist/components/pages/privacy-policy-or-terms-of-use/PrivacyPolicyOrTermsOfUse.svelte +5 -5
- package/dist/components/pages/privacy-policy-or-terms-of-use/types.d.ts +10 -13
- package/dist/components/pages/product-details/01/ProductDetails01.svelte +6 -2
- package/dist/components/pages/product-details/01/ProductDetails01.svelte.d.ts +3 -1
- package/dist/components/pages/product-details/02/ProductDetails02.svelte +7 -1
- package/dist/components/pages/product-details/02/ProductDetails02.svelte.d.ts +3 -1
- package/dist/components/pages/product-details/03/ProductDetails03.svelte +6 -2
- package/dist/components/pages/product-details/03/ProductDetails03.svelte.d.ts +3 -1
- package/dist/components/pages/product-details/ProductDetails.svelte +31 -5
- package/dist/components/pages/product-details/shared/ProductPromotionDetails.svelte +29 -0
- package/dist/components/pages/product-details/shared/ProductPromotionDetails.svelte.d.ts +8 -0
- package/dist/components/pages/product-details/shared/ProductPurchasePanel.svelte +16 -7
- package/dist/components/pages/product-details/shared/ProductPurchasePanel.svelte.d.ts +3 -1
- package/dist/components/pages/product-details/types.d.ts +16 -0
- package/package.json +1 -1
|
@@ -86,6 +86,12 @@
|
|
|
86
86
|
onerror={(e) =>
|
|
87
87
|
((e.target as HTMLImageElement).src = ImgPlaceHolderGallery)}
|
|
88
88
|
/>
|
|
89
|
+
{:else}
|
|
90
|
+
<img
|
|
91
|
+
src={ImgPlaceHolderGallery}
|
|
92
|
+
alt="Not Found"
|
|
93
|
+
class="rounded-lg h-36 md:h-44 w-full object-cover object-center"
|
|
94
|
+
/>
|
|
89
95
|
{/if}
|
|
90
96
|
<div class="absolute inset-0 bg-black/5 rounded-sm h-full w-full"></div>
|
|
91
97
|
</aside>
|
|
@@ -85,6 +85,12 @@
|
|
|
85
85
|
onerror={(e) =>
|
|
86
86
|
((e.target as HTMLImageElement).src = ImgPlaceHolderGallery)}
|
|
87
87
|
/>
|
|
88
|
+
{:else}
|
|
89
|
+
<img
|
|
90
|
+
src={ImgPlaceHolderGallery}
|
|
91
|
+
alt="Not Found"
|
|
92
|
+
class="rounded-lg h-36 md:h-44 w-full object-cover object-center"
|
|
93
|
+
/>
|
|
88
94
|
{/if}
|
|
89
95
|
<div class="absolute inset-0 bg-black/5 rounded-sm h-full w-full"></div>
|
|
90
96
|
</aside>
|
|
@@ -2,7 +2,7 @@ import { GlobalIcon, MapPin, NecklaceIcon } from "@hugeicons/core-free-icons";
|
|
|
2
2
|
const items = [
|
|
3
3
|
{
|
|
4
4
|
id: 1,
|
|
5
|
-
imageUrl: "https://images.unsplash.com/photo-1507525428034-b723cf961d3e?q=80&w=1170&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
|
|
5
|
+
//imageUrl: "https://images.unsplash.com/photo-1507525428034-b723cf961d3e?q=80&w=1170&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
|
|
6
6
|
title: "Hotel Baía Azul",
|
|
7
7
|
content: "Acomodação premium de frente para o mar com quartos luxuosos, restaurante internacional, piscina aquecida e serviço de transfer exclusivo para hóspedes.",
|
|
8
8
|
isFavorite: true,
|
|
@@ -16,16 +16,7 @@
|
|
|
16
16
|
onSubscribe,
|
|
17
17
|
}: FooterProps = $props();
|
|
18
18
|
|
|
19
|
-
let email = $state("");
|
|
20
19
|
const year = new Date().getFullYear();
|
|
21
|
-
|
|
22
|
-
function handleSubscribe(e: SubmitEvent) {
|
|
23
|
-
e.preventDefault();
|
|
24
|
-
const value = email.trim();
|
|
25
|
-
if (!value) return;
|
|
26
|
-
onSubscribe?.(value);
|
|
27
|
-
email = "";
|
|
28
|
-
}
|
|
29
20
|
</script>
|
|
30
21
|
|
|
31
22
|
<footer class="p-10">
|
package/dist/components/pages/privacy-policy-or-terms-of-use/01/PrivacyPolicyOrTermsOfUse01.svelte
CHANGED
|
@@ -12,16 +12,23 @@
|
|
|
12
12
|
</script>
|
|
13
13
|
|
|
14
14
|
<script lang="ts">
|
|
15
|
-
import type { DocPageData } from "../types";
|
|
16
15
|
import { buildToc } from "../shared/toc";
|
|
17
16
|
import PrivacyPolicyOrTermsOfUseBreadcrumb from "../shared/PrivacyPolicyOrTermsOfUseBreadcrumb.svelte";
|
|
18
17
|
import DocSectionView from "../shared/DocSectionView.svelte";
|
|
19
18
|
import DocsSidebar from "./DocsSidebar.svelte";
|
|
20
19
|
import TableOfContents from "./TableOfContents.svelte";
|
|
20
|
+
import type { PrivacyPolicyOrTermsOfUseProps } from "../types";
|
|
21
21
|
|
|
22
|
-
let {
|
|
22
|
+
let {
|
|
23
|
+
breadcrumb,
|
|
24
|
+
sections,
|
|
25
|
+
title,
|
|
26
|
+
lastUpdated,
|
|
27
|
+
isVisibleMenuLeft = true,
|
|
28
|
+
isVisibleMenuRight,
|
|
29
|
+
}: PrivacyPolicyOrTermsOfUseProps = $props();
|
|
23
30
|
|
|
24
|
-
const toc = $derived(buildToc(
|
|
31
|
+
const toc = $derived(buildToc(sections));
|
|
25
32
|
|
|
26
33
|
/** Currently visible section, for highlighting in the TOC (simple scroll-spy). */
|
|
27
34
|
let activeId = $state<string | undefined>(undefined);
|
|
@@ -48,26 +55,29 @@
|
|
|
48
55
|
|
|
49
56
|
<div class="mx-auto max-w-7xl px-6 py-10">
|
|
50
57
|
<div class="flex gap-10">
|
|
51
|
-
|
|
58
|
+
{#if isVisibleMenuLeft}
|
|
59
|
+
<DocsSidebar {sections} {activeId} />
|
|
60
|
+
{/if}
|
|
52
61
|
|
|
53
62
|
<main class="min-w-0 flex-1 flex flex-col gap-8">
|
|
54
63
|
<header class="flex flex-col gap-4">
|
|
55
64
|
<div>
|
|
56
|
-
<h1 class="text-3xl font-bold tracking-tight">{
|
|
65
|
+
<h1 class="text-3xl font-bold tracking-tight">{title}</h1>
|
|
57
66
|
<p class="mt-1 text-sm text-muted-foreground">
|
|
58
|
-
Latest update: {
|
|
67
|
+
Latest update: {lastUpdated}
|
|
59
68
|
</p>
|
|
60
69
|
</div>
|
|
61
|
-
<PrivacyPolicyOrTermsOfUseBreadcrumb items={
|
|
70
|
+
<PrivacyPolicyOrTermsOfUseBreadcrumb items={breadcrumb} />
|
|
62
71
|
</header>
|
|
63
72
|
|
|
64
73
|
<div class="flex flex-col gap-10">
|
|
65
|
-
{#each
|
|
74
|
+
{#each sections as section (section.id)}
|
|
66
75
|
<DocSectionView {section} />
|
|
67
76
|
{/each}
|
|
68
77
|
</div>
|
|
69
78
|
</main>
|
|
70
|
-
|
|
71
|
-
|
|
79
|
+
{#if isVisibleMenuRight}
|
|
80
|
+
<TableOfContents items={toc} {activeId} />
|
|
81
|
+
{/if}
|
|
72
82
|
</div>
|
|
73
83
|
</div>
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
data: DocPageData;
|
|
4
|
-
};
|
|
5
|
-
declare const PrivacyPolicyOrTermsOfUse01: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
1
|
+
import type { PrivacyPolicyOrTermsOfUseProps } from "../types";
|
|
2
|
+
declare const PrivacyPolicyOrTermsOfUse01: import("svelte").Component<PrivacyPolicyOrTermsOfUseProps, {}, "">;
|
|
6
3
|
type PrivacyPolicyOrTermsOfUse01 = ReturnType<typeof PrivacyPolicyOrTermsOfUse01>;
|
|
7
4
|
export default PrivacyPolicyOrTermsOfUse01;
|
package/dist/components/pages/privacy-policy-or-terms-of-use/02/PrivacyPolicyOrTermsOfUse02.svelte
CHANGED
|
@@ -11,14 +11,14 @@
|
|
|
11
11
|
</script>
|
|
12
12
|
|
|
13
13
|
<script lang="ts">
|
|
14
|
-
import type { DocPageData } from "../types";
|
|
15
14
|
import DocsPageHero from "./DocsPageHero.svelte";
|
|
15
|
+
import type { PrivacyPolicyOrTermsOfUseProps } from "../types";
|
|
16
16
|
|
|
17
|
-
let { data }:
|
|
17
|
+
let { ...data }: PrivacyPolicyOrTermsOfUseProps = $props();
|
|
18
18
|
</script>
|
|
19
19
|
|
|
20
20
|
<svelte:head>
|
|
21
21
|
<title>{data.title}</title>
|
|
22
22
|
</svelte:head>
|
|
23
23
|
|
|
24
|
-
<DocsPageHero
|
|
24
|
+
<DocsPageHero {data} />
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
data: DocPageData;
|
|
4
|
-
};
|
|
5
|
-
declare const PrivacyPolicyOrTermsOfUse02: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
1
|
+
import type { PrivacyPolicyOrTermsOfUseProps } from "../types";
|
|
2
|
+
declare const PrivacyPolicyOrTermsOfUse02: import("svelte").Component<PrivacyPolicyOrTermsOfUseProps, {}, "">;
|
|
6
3
|
type PrivacyPolicyOrTermsOfUse02 = ReturnType<typeof PrivacyPolicyOrTermsOfUse02>;
|
|
7
4
|
export default PrivacyPolicyOrTermsOfUse02;
|
package/dist/components/pages/privacy-policy-or-terms-of-use/PrivacyPolicyOrTermsOfUse.svelte
CHANGED
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
* @component
|
|
9
9
|
* @example
|
|
10
10
|
* ```svelte
|
|
11
|
-
|
|
11
|
+
* <!-- Variant 1 (default) — docs layout with sidebar -->
|
|
12
12
|
* <PrivacyPolicyOrTermsOfUse variant={1} data={pageData} />
|
|
13
13
|
*
|
|
14
|
-
|
|
14
|
+
* <!-- Variant 2 — layout with hero -->
|
|
15
15
|
* <PrivacyPolicyOrTermsOfUse variant={2} data={pageData} />
|
|
16
16
|
* ```
|
|
17
17
|
*/
|
|
@@ -22,11 +22,11 @@
|
|
|
22
22
|
import PrivacyPolicyOrTermsOfUse01 from "./01/PrivacyPolicyOrTermsOfUse01.svelte";
|
|
23
23
|
import PrivacyPolicyOrTermsOfUse02 from "./02/PrivacyPolicyOrTermsOfUse02.svelte";
|
|
24
24
|
|
|
25
|
-
let { variant = 1, data }: PrivacyPolicyOrTermsOfUseProps = $props();
|
|
25
|
+
let { variant = 1, ...data }: PrivacyPolicyOrTermsOfUseProps = $props();
|
|
26
26
|
</script>
|
|
27
27
|
|
|
28
28
|
{#if variant === 2}
|
|
29
|
-
<PrivacyPolicyOrTermsOfUse02 {data} />
|
|
29
|
+
<PrivacyPolicyOrTermsOfUse02 {...data} />
|
|
30
30
|
{:else}
|
|
31
|
-
<PrivacyPolicyOrTermsOfUse01 {data} />
|
|
31
|
+
<PrivacyPolicyOrTermsOfUse01 {...data} />
|
|
32
32
|
{/if}
|
|
@@ -37,17 +37,6 @@ export interface DocSection {
|
|
|
37
37
|
/** subsecções aninhadas */
|
|
38
38
|
subsections?: DocSection[];
|
|
39
39
|
}
|
|
40
|
-
/** Dados completos de uma página de documentação/política. */
|
|
41
|
-
export interface DocPageData {
|
|
42
|
-
/** título da página */
|
|
43
|
-
title: string;
|
|
44
|
-
/** data da última atualização */
|
|
45
|
-
lastUpdated: string;
|
|
46
|
-
/** itens do breadcrumb */
|
|
47
|
-
breadcrumb: BreadcrumbItem[];
|
|
48
|
-
/** secções de conteúdo (usadas pela sidebar, TOC e renderização) */
|
|
49
|
-
sections: DocSection[];
|
|
50
|
-
}
|
|
51
40
|
/** Item derivado automaticamente das secções, para a tabela de conteúdos (TOC). */
|
|
52
41
|
export interface TocItem {
|
|
53
42
|
id: string;
|
|
@@ -57,6 +46,14 @@ export interface TocItem {
|
|
|
57
46
|
export interface PrivacyPolicyOrTermsOfUseProps {
|
|
58
47
|
/** Variante do layout: 1 = sidebar+TOC, 2 = hero+coluna. */
|
|
59
48
|
variant?: 1 | 2;
|
|
60
|
-
/**
|
|
61
|
-
|
|
49
|
+
/** título da página */
|
|
50
|
+
title: string;
|
|
51
|
+
/** data da última atualização */
|
|
52
|
+
lastUpdated: string;
|
|
53
|
+
/** itens do breadcrumb */
|
|
54
|
+
breadcrumb: BreadcrumbItem[];
|
|
55
|
+
/** secções de conteúdo (usadas pela sidebar, TOC e renderização) */
|
|
56
|
+
sections: DocSection[];
|
|
57
|
+
isVisibleMenuLeft?: boolean;
|
|
58
|
+
isVisibleMenuRight?: boolean;
|
|
62
59
|
}
|
|
@@ -20,17 +20,21 @@
|
|
|
20
20
|
import ProductDetailReviews from "../shared/ProductDetailReviews.svelte";
|
|
21
21
|
import ProductDetailTags from "../shared/ProductDetailTags.svelte";
|
|
22
22
|
import ProductPurchasePanel from "../shared/ProductPurchasePanel.svelte";
|
|
23
|
-
import type { ProductDetailsData } from "../types";
|
|
23
|
+
import type { ProductDetailsData, ProductPromotionDetails } from "../types";
|
|
24
24
|
|
|
25
25
|
let {
|
|
26
26
|
data,
|
|
27
27
|
isLoading = false,
|
|
28
|
+
promotions = [],
|
|
29
|
+
showPriceWithPromotions = false,
|
|
28
30
|
onBuy,
|
|
29
31
|
onFavorite,
|
|
30
32
|
onCart,
|
|
31
33
|
}: {
|
|
32
34
|
data: ProductDetailsData;
|
|
33
35
|
isLoading?: boolean;
|
|
36
|
+
promotions?: ProductPromotionDetails[];
|
|
37
|
+
showPriceWithPromotions?: boolean;
|
|
34
38
|
onBuy?: (id: string | number) => void;
|
|
35
39
|
onFavorite?: (id: string | number) => void;
|
|
36
40
|
onCart?: (id: string | number) => void;
|
|
@@ -64,7 +68,7 @@
|
|
|
64
68
|
<ProductDetailFeatures features={data.features} {isLoading} />
|
|
65
69
|
{/if}
|
|
66
70
|
|
|
67
|
-
<ProductPurchasePanel {data} {isLoading} {onBuy} {onFavorite} {onCart} />
|
|
71
|
+
<ProductPurchasePanel {data} {isLoading} {promotions} {showPriceWithPromotions} {onBuy} {onFavorite} {onCart} />
|
|
68
72
|
</div>
|
|
69
73
|
</div>
|
|
70
74
|
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import type { ProductDetailsData } from "../types";
|
|
1
|
+
import type { ProductDetailsData, ProductPromotionDetails } from "../types";
|
|
2
2
|
type $$ComponentProps = {
|
|
3
3
|
data: ProductDetailsData;
|
|
4
4
|
isLoading?: boolean;
|
|
5
|
+
promotions?: ProductPromotionDetails[];
|
|
6
|
+
showPriceWithPromotions?: boolean;
|
|
5
7
|
onBuy?: (id: string | number) => void;
|
|
6
8
|
onFavorite?: (id: string | number) => void;
|
|
7
9
|
onCart?: (id: string | number) => void;
|
|
@@ -20,17 +20,21 @@
|
|
|
20
20
|
import ProductDetailReviews from "../shared/ProductDetailReviews.svelte";
|
|
21
21
|
import ProductDetailTags from "../shared/ProductDetailTags.svelte";
|
|
22
22
|
import ProductPurchasePanel from "../shared/ProductPurchasePanel.svelte";
|
|
23
|
-
import type { ProductDetailsData } from "../types";
|
|
23
|
+
import type { ProductDetailsData, ProductPromotionDetails } from "../types";
|
|
24
24
|
|
|
25
25
|
let {
|
|
26
26
|
data,
|
|
27
27
|
isLoading = false,
|
|
28
|
+
promotions = [],
|
|
29
|
+
showPriceWithPromotions = false,
|
|
28
30
|
onBuy,
|
|
29
31
|
onFavorite,
|
|
30
32
|
onCart,
|
|
31
33
|
}: {
|
|
32
34
|
data: ProductDetailsData;
|
|
33
35
|
isLoading?: boolean;
|
|
36
|
+
promotions?: ProductPromotionDetails[];
|
|
37
|
+
showPriceWithPromotions?: boolean;
|
|
34
38
|
onBuy?: (id: string | number) => void;
|
|
35
39
|
onFavorite?: (id: string | number) => void;
|
|
36
40
|
onCart?: (id: string | number) => void;
|
|
@@ -72,6 +76,8 @@
|
|
|
72
76
|
<ProductPurchasePanel
|
|
73
77
|
{data}
|
|
74
78
|
{isLoading}
|
|
79
|
+
{promotions}
|
|
80
|
+
{showPriceWithPromotions}
|
|
75
81
|
{onBuy}
|
|
76
82
|
{onFavorite}
|
|
77
83
|
{onCart}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import type { ProductDetailsData } from "../types";
|
|
1
|
+
import type { ProductDetailsData, ProductPromotionDetails } from "../types";
|
|
2
2
|
type $$ComponentProps = {
|
|
3
3
|
data: ProductDetailsData;
|
|
4
4
|
isLoading?: boolean;
|
|
5
|
+
promotions?: ProductPromotionDetails[];
|
|
6
|
+
showPriceWithPromotions?: boolean;
|
|
5
7
|
onBuy?: (id: string | number) => void;
|
|
6
8
|
onFavorite?: (id: string | number) => void;
|
|
7
9
|
onCart?: (id: string | number) => void;
|
|
@@ -19,18 +19,22 @@
|
|
|
19
19
|
import ProductDetailTags from "../shared/ProductDetailTags.svelte";
|
|
20
20
|
import ProductDetailTabs from "../shared/ProductDetailTabs.svelte";
|
|
21
21
|
import ProductPurchasePanel from "../shared/ProductPurchasePanel.svelte";
|
|
22
|
-
import type { ProductDetailsData } from "../types";
|
|
22
|
+
import type { ProductDetailsData, ProductPromotionDetails } from "../types";
|
|
23
23
|
import { useDevice } from "../../../../hooks/responsive.svelte";
|
|
24
24
|
|
|
25
25
|
let {
|
|
26
26
|
data,
|
|
27
27
|
isLoading = false,
|
|
28
|
+
promotions = [],
|
|
29
|
+
showPriceWithPromotions = false,
|
|
28
30
|
onBuy,
|
|
29
31
|
onFavorite,
|
|
30
32
|
onCart,
|
|
31
33
|
}: {
|
|
32
34
|
data: ProductDetailsData;
|
|
33
35
|
isLoading?: boolean;
|
|
36
|
+
promotions?: ProductPromotionDetails[];
|
|
37
|
+
showPriceWithPromotions?: boolean;
|
|
34
38
|
onBuy?: (id: string | number) => void;
|
|
35
39
|
onFavorite?: (id: string | number) => void;
|
|
36
40
|
onCart?: (id: string | number) => void;
|
|
@@ -55,7 +59,7 @@
|
|
|
55
59
|
|
|
56
60
|
<ProductDetailTags tags={data.tags} {isLoading} />
|
|
57
61
|
|
|
58
|
-
<ProductPurchasePanel {data} {isLoading} {onBuy} {onFavorite} {onCart} />
|
|
62
|
+
<ProductPurchasePanel {data} {isLoading} {promotions} {showPriceWithPromotions} {onBuy} {onFavorite} {onCart} />
|
|
59
63
|
|
|
60
64
|
{#if !responsive.isMobile}
|
|
61
65
|
{#if data.location}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import type { ProductDetailsData } from "../types";
|
|
1
|
+
import type { ProductDetailsData, ProductPromotionDetails } from "../types";
|
|
2
2
|
type $$ComponentProps = {
|
|
3
3
|
data: ProductDetailsData;
|
|
4
4
|
isLoading?: boolean;
|
|
5
|
+
promotions?: ProductPromotionDetails[];
|
|
6
|
+
showPriceWithPromotions?: boolean;
|
|
5
7
|
onBuy?: (id: string | number) => void;
|
|
6
8
|
onFavorite?: (id: string | number) => void;
|
|
7
9
|
onCart?: (id: string | number) => void;
|
|
@@ -20,13 +20,15 @@
|
|
|
20
20
|
<script lang="ts">
|
|
21
21
|
import type { ProductDetailsProps } from "./types";
|
|
22
22
|
import ProductDetails01 from "./01/ProductDetails01.svelte";
|
|
23
|
-
import
|
|
24
|
-
import
|
|
23
|
+
import ProductDetails02 from "./02/ProductDetails02.svelte";
|
|
24
|
+
import ProductDetails03 from "./03/ProductDetails03.svelte";
|
|
25
25
|
|
|
26
26
|
let {
|
|
27
27
|
varient = 1,
|
|
28
28
|
data,
|
|
29
29
|
isLoading = false,
|
|
30
|
+
promotions = [],
|
|
31
|
+
showPriceWithPromotions = false,
|
|
30
32
|
onBuy,
|
|
31
33
|
onFavorite,
|
|
32
34
|
onCart,
|
|
@@ -34,9 +36,33 @@
|
|
|
34
36
|
</script>
|
|
35
37
|
|
|
36
38
|
{#if varient === 2}
|
|
37
|
-
<
|
|
39
|
+
<ProductDetails02
|
|
40
|
+
{data}
|
|
41
|
+
{isLoading}
|
|
42
|
+
{promotions}
|
|
43
|
+
{showPriceWithPromotions}
|
|
44
|
+
{onBuy}
|
|
45
|
+
{onFavorite}
|
|
46
|
+
{onCart}
|
|
47
|
+
/>
|
|
38
48
|
{:else if varient === 3}
|
|
39
|
-
<
|
|
49
|
+
<ProductDetails03
|
|
50
|
+
{data}
|
|
51
|
+
{isLoading}
|
|
52
|
+
{promotions}
|
|
53
|
+
{showPriceWithPromotions}
|
|
54
|
+
{onBuy}
|
|
55
|
+
{onFavorite}
|
|
56
|
+
{onCart}
|
|
57
|
+
/>
|
|
40
58
|
{:else}
|
|
41
|
-
<ProductDetails01
|
|
59
|
+
<ProductDetails01
|
|
60
|
+
{data}
|
|
61
|
+
{isLoading}
|
|
62
|
+
{promotions}
|
|
63
|
+
{showPriceWithPromotions}
|
|
64
|
+
{onBuy}
|
|
65
|
+
{onFavorite}
|
|
66
|
+
{onCart}
|
|
67
|
+
/>
|
|
42
68
|
{/if}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import CardPromotionPrice from "../../../core/card/promotion/CardPromotionPrice.svelte";
|
|
3
|
+
import Skeleton from "../../../ui/skeleton/skeleton.svelte";
|
|
4
|
+
import type { ProductPromotionDetails } from "../types";
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
promotions = [],
|
|
8
|
+
isLoading = false,
|
|
9
|
+
}: {
|
|
10
|
+
promotions?: ProductPromotionDetails[];
|
|
11
|
+
isLoading?: boolean;
|
|
12
|
+
} = $props();
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
{#if isLoading}
|
|
16
|
+
<div class="flex flex-col gap-2">
|
|
17
|
+
<Skeleton class="h-5 w-36 rounded-md" />
|
|
18
|
+
<Skeleton class="h-5 w-28 rounded-md" />
|
|
19
|
+
</div>
|
|
20
|
+
{:else if promotions.length > 0}
|
|
21
|
+
<div class="flex flex-col gap-2">
|
|
22
|
+
<span class="text-sm font-medium text-muted-foreground">Promoções</span>
|
|
23
|
+
{#each promotions as promo (promo.id)}
|
|
24
|
+
<div class="flex items-center gap-2">
|
|
25
|
+
<CardPromotionPrice newPrice={promo.newPrice} oldPrice={promo.oldPrice} />
|
|
26
|
+
</div>
|
|
27
|
+
{/each}
|
|
28
|
+
</div>
|
|
29
|
+
{/if}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ProductPromotionDetails } from "../types";
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
promotions?: ProductPromotionDetails[];
|
|
4
|
+
isLoading?: boolean;
|
|
5
|
+
};
|
|
6
|
+
declare const ProductPromotionDetails: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
7
|
+
type ProductPromotionDetails = ReturnType<typeof ProductPromotionDetails>;
|
|
8
|
+
export default ProductPromotionDetails;
|
|
@@ -14,17 +14,22 @@
|
|
|
14
14
|
import ProductDetailActions from "./ProductDetailActions.svelte";
|
|
15
15
|
import ProductDetailPrice from "./ProductDetailPrice.svelte";
|
|
16
16
|
import ProductDetailRating from "./ProductDetailRating.svelte";
|
|
17
|
-
import
|
|
17
|
+
import ProductPromotionDetails from "./ProductPromotionDetails.svelte";
|
|
18
|
+
import type { ProductDetailsData, ProductPromotionDetails as ProductPromotionDetailsType } from "../types";
|
|
18
19
|
|
|
19
20
|
let {
|
|
20
21
|
data,
|
|
21
22
|
isLoading = false,
|
|
23
|
+
promotions = [],
|
|
24
|
+
showPriceWithPromotions = false,
|
|
22
25
|
onBuy,
|
|
23
26
|
onFavorite,
|
|
24
27
|
onCart,
|
|
25
28
|
}: {
|
|
26
29
|
data: ProductDetailsData;
|
|
27
30
|
isLoading?: boolean;
|
|
31
|
+
promotions?: ProductPromotionDetailsType[];
|
|
32
|
+
showPriceWithPromotions?: boolean;
|
|
28
33
|
onBuy?: (id: string | number) => void;
|
|
29
34
|
onFavorite?: (id: string | number) => void;
|
|
30
35
|
onCart?: (id: string | number) => void;
|
|
@@ -38,12 +43,16 @@
|
|
|
38
43
|
{isLoading}
|
|
39
44
|
/>
|
|
40
45
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
{#if !(showPriceWithPromotions && promotions.length > 0)}
|
|
47
|
+
<ProductDetailPrice
|
|
48
|
+
newPrice={data.newPrice}
|
|
49
|
+
oldPrice={data.oldPrice}
|
|
50
|
+
currency={data.currency}
|
|
51
|
+
{isLoading}
|
|
52
|
+
/>
|
|
53
|
+
{/if}
|
|
54
|
+
|
|
55
|
+
<ProductPromotionDetails {promotions} {isLoading} />
|
|
47
56
|
|
|
48
57
|
<ProductDetailActions
|
|
49
58
|
id={data.id}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import type { ProductDetailsData } from "../types";
|
|
1
|
+
import type { ProductDetailsData, ProductPromotionDetails as ProductPromotionDetailsType } from "../types";
|
|
2
2
|
type $$ComponentProps = {
|
|
3
3
|
data: ProductDetailsData;
|
|
4
4
|
isLoading?: boolean;
|
|
5
|
+
promotions?: ProductPromotionDetailsType[];
|
|
6
|
+
showPriceWithPromotions?: boolean;
|
|
5
7
|
onBuy?: (id: string | number) => void;
|
|
6
8
|
onFavorite?: (id: string | number) => void;
|
|
7
9
|
onCart?: (id: string | number) => void;
|
|
@@ -141,6 +141,11 @@ export interface ProductDetailsData {
|
|
|
141
141
|
* Propriedades do componente principal ProductDetails.
|
|
142
142
|
* Suporta quatro variantes de layout e callbacks de interação.
|
|
143
143
|
*/
|
|
144
|
+
export interface ProductPromotionDetails {
|
|
145
|
+
id: string | number;
|
|
146
|
+
newPrice: string | number;
|
|
147
|
+
oldPrice: string | number;
|
|
148
|
+
}
|
|
144
149
|
export interface ProductDetailsProps {
|
|
145
150
|
/**
|
|
146
151
|
* Variante do layout da página de detalhes.
|
|
@@ -159,6 +164,17 @@ export interface ProductDetailsProps {
|
|
|
159
164
|
* @default false
|
|
160
165
|
*/
|
|
161
166
|
isLoading?: boolean;
|
|
167
|
+
/**
|
|
168
|
+
* Lista de promoções associadas ao produto.
|
|
169
|
+
* Cada promoção contém um preço antigo e novo.
|
|
170
|
+
*/
|
|
171
|
+
promotions?: ProductPromotionDetails[];
|
|
172
|
+
/**
|
|
173
|
+
* Quando true, oculta o preço regular do produto
|
|
174
|
+
* e apresenta apenas os preços das promoções.
|
|
175
|
+
* @default false
|
|
176
|
+
*/
|
|
177
|
+
showPriceWithPromotions?: boolean;
|
|
162
178
|
/**
|
|
163
179
|
* Callback executado quando o utilizador clica no botão de compra.
|
|
164
180
|
* Recebe o id do produto como argumento.
|