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,71 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
/**
|
|
3
|
+
* Variante 01 da página de detalhes do produto.
|
|
4
|
+
* Layout de duas colunas: galeria à esquerda e informações/compra à direita.
|
|
5
|
+
* @component
|
|
6
|
+
* @example
|
|
7
|
+
* ```svelte
|
|
8
|
+
* <ProductDetails01 {data} {onBuy} {onFavorite} {onCart} />
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<script lang="ts">
|
|
14
|
+
import ProductDetailBreadcrumb from "../shared/ProductDetailBreadcrumb.svelte";
|
|
15
|
+
import ProductDetailDescription from "../shared/ProductDetailDescription.svelte";
|
|
16
|
+
import ProductDetailFeatures from "../shared/ProductDetailFeatures.svelte";
|
|
17
|
+
import ProductDetailHeader from "../shared/ProductDetailHeader.svelte";
|
|
18
|
+
import ProductDetailImage from "../shared/ProductDetailImage.svelte";
|
|
19
|
+
import ProductDetailMap from "../shared/ProductDetailMap.svelte";
|
|
20
|
+
import ProductDetailTags from "../shared/ProductDetailTags.svelte";
|
|
21
|
+
import ProductPurchasePanel from "../shared/ProductPurchasePanel.svelte";
|
|
22
|
+
import type { ProductDetailsData } from "../types";
|
|
23
|
+
|
|
24
|
+
let {
|
|
25
|
+
data,
|
|
26
|
+
isLoading = false,
|
|
27
|
+
onBuy,
|
|
28
|
+
onFavorite,
|
|
29
|
+
onCart,
|
|
30
|
+
}: {
|
|
31
|
+
data: ProductDetailsData;
|
|
32
|
+
isLoading?: boolean;
|
|
33
|
+
onBuy?: (id: string | number) => void;
|
|
34
|
+
onFavorite?: (id: string | number) => void;
|
|
35
|
+
onCart?: (id: string | number) => void;
|
|
36
|
+
} = $props();
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<div class="mx-auto max-w-7xl px-6 py-10">
|
|
40
|
+
<div class="mb-8">
|
|
41
|
+
<ProductDetailBreadcrumb items={data.breadcrumb} {isLoading} />
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<div class="grid gap-10 lg:grid-cols-2">
|
|
45
|
+
<ProductDetailImage images={data.gallery} {isLoading} />
|
|
46
|
+
|
|
47
|
+
<div class="flex flex-col gap-5">
|
|
48
|
+
<ProductDetailHeader title={data.title} subtitle={data.subtitle} {isLoading} />
|
|
49
|
+
|
|
50
|
+
<ProductDetailTags tags={data.tags} {isLoading} />
|
|
51
|
+
|
|
52
|
+
<ProductDetailDescription
|
|
53
|
+
description={data.description}
|
|
54
|
+
longDescription={data.longDescription}
|
|
55
|
+
{isLoading}
|
|
56
|
+
/>
|
|
57
|
+
|
|
58
|
+
{#if data.features}
|
|
59
|
+
<ProductDetailFeatures features={data.features} {isLoading} />
|
|
60
|
+
{/if}
|
|
61
|
+
|
|
62
|
+
<ProductPurchasePanel {data} {isLoading} {onBuy} {onFavorite} {onCart} />
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
65
|
+
|
|
66
|
+
{#if data.location}
|
|
67
|
+
<div class="mt-12">
|
|
68
|
+
<ProductDetailMap location={data.location} {isLoading} />
|
|
69
|
+
</div>
|
|
70
|
+
{/if}
|
|
71
|
+
</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 ProductDetails01: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
10
|
+
type ProductDetails01 = ReturnType<typeof ProductDetails01>;
|
|
11
|
+
export default ProductDetails01;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
/**
|
|
3
|
+
* Variante 02 da página de detalhes do produto.
|
|
4
|
+
* Layout com galeria em destaque e conteúdo em coluna centralizada.
|
|
5
|
+
* @component
|
|
6
|
+
* @example
|
|
7
|
+
* ```svelte
|
|
8
|
+
* <ProductDetails02 {data} {onBuy} {onFavorite} {onCart} />
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<script lang="ts">
|
|
14
|
+
import ProductDetailBreadcrumb from "../shared/ProductDetailBreadcrumb.svelte";
|
|
15
|
+
import ProductDetailDescription from "../shared/ProductDetailDescription.svelte";
|
|
16
|
+
import ProductDetailFeatures from "../shared/ProductDetailFeatures.svelte";
|
|
17
|
+
import ProductDetailFilesVertical from "../shared/ProductDetailFilesVertical.svelte";
|
|
18
|
+
import ProductDetailHeader from "../shared/ProductDetailHeader.svelte";
|
|
19
|
+
import ProductDetailMap from "../shared/ProductDetailMap.svelte";
|
|
20
|
+
import ProductDetailTags from "../shared/ProductDetailTags.svelte";
|
|
21
|
+
import ProductPurchasePanel from "../shared/ProductPurchasePanel.svelte";
|
|
22
|
+
import type { ProductDetailsData } from "../types";
|
|
23
|
+
|
|
24
|
+
let {
|
|
25
|
+
data,
|
|
26
|
+
isLoading = false,
|
|
27
|
+
onBuy,
|
|
28
|
+
onFavorite,
|
|
29
|
+
onCart,
|
|
30
|
+
}: {
|
|
31
|
+
data: ProductDetailsData;
|
|
32
|
+
isLoading?: boolean;
|
|
33
|
+
onBuy?: (id: string | number) => void;
|
|
34
|
+
onFavorite?: (id: string | number) => void;
|
|
35
|
+
onCart?: (id: string | number) => void;
|
|
36
|
+
} = $props();
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<div class="bg-background">
|
|
40
|
+
<ProductDetailFilesVertical
|
|
41
|
+
images={data.gallery}
|
|
42
|
+
className="mx-auto max-w-5xl px-6 pt-10"
|
|
43
|
+
{isLoading}
|
|
44
|
+
/>
|
|
45
|
+
|
|
46
|
+
<div class="mx-auto max-w-3xl px-6 py-12">
|
|
47
|
+
<div class="flex flex-col gap-6">
|
|
48
|
+
<div class="flex justify-center">
|
|
49
|
+
<ProductDetailBreadcrumb items={data.breadcrumb} {isLoading} />
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
<ProductDetailHeader
|
|
53
|
+
title={data.title}
|
|
54
|
+
subtitle={data.subtitle}
|
|
55
|
+
className="items-center text-center"
|
|
56
|
+
{isLoading}
|
|
57
|
+
/>
|
|
58
|
+
|
|
59
|
+
<div class="flex justify-center">
|
|
60
|
+
<ProductDetailTags tags={data.tags} {isLoading} />
|
|
61
|
+
</div>
|
|
62
|
+
|
|
63
|
+
<ProductDetailDescription
|
|
64
|
+
description={data.description}
|
|
65
|
+
longDescription={data.longDescription}
|
|
66
|
+
{isLoading}
|
|
67
|
+
/>
|
|
68
|
+
|
|
69
|
+
{#if data.features}
|
|
70
|
+
<div class="mx-auto w-full max-w-md">
|
|
71
|
+
<ProductDetailFeatures features={data.features} {isLoading} />
|
|
72
|
+
</div>
|
|
73
|
+
{/if}
|
|
74
|
+
|
|
75
|
+
<div class="flex justify-center">
|
|
76
|
+
<div class="w-full max-w-sm">
|
|
77
|
+
<ProductPurchasePanel {data} {isLoading} {onBuy} {onFavorite} {onCart} />
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
|
|
83
|
+
{#if data.location}
|
|
84
|
+
<div class="mx-auto max-w-3xl px-6 pb-12">
|
|
85
|
+
<ProductDetailMap location={data.location} {isLoading} />
|
|
86
|
+
</div>
|
|
87
|
+
{/if}
|
|
88
|
+
</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 ProductDetails02: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
10
|
+
type ProductDetails02 = ReturnType<typeof ProductDetails02>;
|
|
11
|
+
export default ProductDetails02;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
/**
|
|
3
|
+
* Variante 03 da página de detalhes do produto.
|
|
4
|
+
* Layout com galeria, conteúdo expandido e painel de compra sticky.
|
|
5
|
+
* @component
|
|
6
|
+
* @example
|
|
7
|
+
* ```svelte
|
|
8
|
+
* <ProductDetails03 {data} {onBuy} {onFavorite} {onCart} />
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<script lang="ts">
|
|
14
|
+
import ProductDetailBreadcrumb from "../shared/ProductDetailBreadcrumb.svelte";
|
|
15
|
+
import ProductDetailDescription from "../shared/ProductDetailDescription.svelte";
|
|
16
|
+
import ProductDetailFeatures from "../shared/ProductDetailFeatures.svelte";
|
|
17
|
+
import ProductDetailFilesVertical from "../shared/ProductDetailFilesVertical.svelte";
|
|
18
|
+
import ProductDetailHeader from "../shared/ProductDetailHeader.svelte";
|
|
19
|
+
import ProductDetailMap from "../shared/ProductDetailMap.svelte";
|
|
20
|
+
import ProductDetailTags from "../shared/ProductDetailTags.svelte";
|
|
21
|
+
import ProductPurchasePanel from "../shared/ProductPurchasePanel.svelte";
|
|
22
|
+
import type { ProductDetailsData } from "../types";
|
|
23
|
+
|
|
24
|
+
let {
|
|
25
|
+
data,
|
|
26
|
+
isLoading = false,
|
|
27
|
+
onBuy,
|
|
28
|
+
onFavorite,
|
|
29
|
+
onCart,
|
|
30
|
+
}: {
|
|
31
|
+
data: ProductDetailsData;
|
|
32
|
+
isLoading?: boolean;
|
|
33
|
+
onBuy?: (id: string | number) => void;
|
|
34
|
+
onFavorite?: (id: string | number) => void;
|
|
35
|
+
onCart?: (id: string | number) => void;
|
|
36
|
+
} = $props();
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<div class="mx-auto max-w-7xl px-6 py-10">
|
|
40
|
+
<div class="mb-8">
|
|
41
|
+
<ProductDetailBreadcrumb items={data.breadcrumb} {isLoading} />
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<div class="grid gap-10 lg:grid-cols-[1fr_22rem]">
|
|
45
|
+
<div class="flex flex-col gap-8">
|
|
46
|
+
<ProductDetailFilesVertical images={data.gallery} {isLoading} />
|
|
47
|
+
|
|
48
|
+
<div class="flex flex-col gap-5">
|
|
49
|
+
<ProductDetailHeader title={data.title} subtitle={data.subtitle} {isLoading} />
|
|
50
|
+
|
|
51
|
+
<ProductDetailTags tags={data.tags} {isLoading} />
|
|
52
|
+
|
|
53
|
+
<ProductDetailDescription
|
|
54
|
+
description={data.description}
|
|
55
|
+
longDescription={data.longDescription}
|
|
56
|
+
{isLoading}
|
|
57
|
+
/>
|
|
58
|
+
|
|
59
|
+
{#if data.features}
|
|
60
|
+
<ProductDetailFeatures features={data.features} {isLoading} />
|
|
61
|
+
{/if}
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
|
|
65
|
+
<aside class="lg:sticky lg:top-8 lg:self-start">
|
|
66
|
+
<div class="rounded-lg border p-6">
|
|
67
|
+
<ProductPurchasePanel {data} {isLoading} {onBuy} {onFavorite} {onCart} />
|
|
68
|
+
</div>
|
|
69
|
+
</aside>
|
|
70
|
+
</div>
|
|
71
|
+
|
|
72
|
+
{#if data.location}
|
|
73
|
+
<div class="mt-12">
|
|
74
|
+
<ProductDetailMap location={data.location} {isLoading} />
|
|
75
|
+
</div>
|
|
76
|
+
{/if}
|
|
77
|
+
</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 ProductDetails03: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
10
|
+
type ProductDetails03 = ReturnType<typeof ProductDetails03>;
|
|
11
|
+
export default ProductDetails03;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
/**
|
|
3
|
+
* Variante 04 da página de detalhes do produto.
|
|
4
|
+
* Layout com galeria, informações e abas de conteúdo (descrição,
|
|
5
|
+
* avaliações) abaixo dos dados principais.
|
|
6
|
+
* @component
|
|
7
|
+
* @example
|
|
8
|
+
* ```svelte
|
|
9
|
+
* <ProductDetails04 {data} {onBuy} {onFavorite} {onCart} />
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<script lang="ts">
|
|
15
|
+
import ProductDetailBreadcrumb from "../shared/ProductDetailBreadcrumb.svelte";
|
|
16
|
+
import ProductDetailHeader from "../shared/ProductDetailHeader.svelte";
|
|
17
|
+
import ProductDetailImage from "../shared/ProductDetailImage.svelte";
|
|
18
|
+
import ProductDetailMap from "../shared/ProductDetailMap.svelte";
|
|
19
|
+
import ProductDetailTags from "../shared/ProductDetailTags.svelte";
|
|
20
|
+
import ProductDetailTabs from "../shared/ProductDetailTabs.svelte";
|
|
21
|
+
import ProductPurchasePanel from "../shared/ProductPurchasePanel.svelte";
|
|
22
|
+
import type { ProductDetailsData } from "../types";
|
|
23
|
+
|
|
24
|
+
let {
|
|
25
|
+
data,
|
|
26
|
+
isLoading = false,
|
|
27
|
+
onBuy,
|
|
28
|
+
onFavorite,
|
|
29
|
+
onCart,
|
|
30
|
+
}: {
|
|
31
|
+
data: ProductDetailsData;
|
|
32
|
+
isLoading?: boolean;
|
|
33
|
+
onBuy?: (id: string | number) => void;
|
|
34
|
+
onFavorite?: (id: string | number) => void;
|
|
35
|
+
onCart?: (id: string | number) => void;
|
|
36
|
+
} = $props();
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<div class="mx-auto max-w-7xl px-6 py-10">
|
|
40
|
+
<div class="mb-8">
|
|
41
|
+
<ProductDetailBreadcrumb items={data.breadcrumb} {isLoading} />
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<div class="grid gap-10 lg:grid-cols-2">
|
|
45
|
+
<ProductDetailImage images={data.gallery} {isLoading} />
|
|
46
|
+
|
|
47
|
+
<div class="flex flex-col gap-5">
|
|
48
|
+
<ProductDetailHeader title={data.title} subtitle={data.subtitle} {isLoading} />
|
|
49
|
+
|
|
50
|
+
<ProductDetailTags tags={data.tags} {isLoading} />
|
|
51
|
+
|
|
52
|
+
<ProductPurchasePanel {data} {isLoading} {onBuy} {onFavorite} {onCart} />
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
<div class="mt-12 border-t pt-8">
|
|
57
|
+
<ProductDetailTabs tabs={data.tabs} {data} {isLoading} />
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
{#if data.location}
|
|
61
|
+
<div class="mt-12">
|
|
62
|
+
<ProductDetailMap location={data.location} {isLoading} />
|
|
63
|
+
</div>
|
|
64
|
+
{/if}
|
|
65
|
+
</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 ProductDetails04: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
10
|
+
type ProductDetails04 = ReturnType<typeof ProductDetails04>;
|
|
11
|
+
export default ProductDetails04;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
/**
|
|
3
|
+
* Página de detalhes do produto com seleção de layout.
|
|
4
|
+
* Permite escolher entre quatro variantes:
|
|
5
|
+
* - **1**: Duas colunas (galeria à esquerda, info à direita).
|
|
6
|
+
* - **2**: Galeria em destaque com conteúdo centralizado.
|
|
7
|
+
* - **3**: Painel de compra sticky no lado direito.
|
|
8
|
+
* - **4**: Abas de conteúdo (descrição e avaliações) abaixo da info.
|
|
9
|
+
*
|
|
10
|
+
* @component
|
|
11
|
+
* @example
|
|
12
|
+
* ```svelte
|
|
13
|
+
* <ProductDetails varient={1} data={productData} />
|
|
14
|
+
*
|
|
15
|
+
* <ProductDetails varient={3} data={productData} onBuy={(id) => console.log(id)} />
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<script lang="ts">
|
|
21
|
+
import type { ProductDetailsProps } from "./types";
|
|
22
|
+
import ProductDetails01 from "./01/ProductDetails01.svelte";
|
|
23
|
+
import ProductDetails02 from "./02/ProductDetails02.svelte";
|
|
24
|
+
import ProductDetails03 from "./03/ProductDetails03.svelte";
|
|
25
|
+
import ProductDetails04 from "./04/ProductDetails04.svelte";
|
|
26
|
+
|
|
27
|
+
let { varient = 1, data, isLoading = false, onBuy, onFavorite, onCart }: ProductDetailsProps = $props();
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
{#if varient === 2}
|
|
31
|
+
<ProductDetails02 {data} {isLoading} {onBuy} {onFavorite} {onCart} />
|
|
32
|
+
{:else if varient === 3}
|
|
33
|
+
<ProductDetails03 {data} {isLoading} {onBuy} {onFavorite} {onCart} />
|
|
34
|
+
{:else if varient === 4}
|
|
35
|
+
<ProductDetails04 {data} {isLoading} {onBuy} {onFavorite} {onCart} />
|
|
36
|
+
{:else}
|
|
37
|
+
<ProductDetails01 {data} {isLoading} {onBuy} {onFavorite} {onCart} />
|
|
38
|
+
{/if}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
/**
|
|
3
|
+
* Ações do produto: botões de compra, favorito e carrinho.
|
|
4
|
+
* Quando `isLoading` é true, exibe Skeletons.
|
|
5
|
+
* @component
|
|
6
|
+
* @example
|
|
7
|
+
* ```svelte
|
|
8
|
+
* <ProductDetailActions id={data.id} {onBuy} {onFavorite} {onCart} buttonBuyText="Comprar" />
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<script lang="ts">
|
|
14
|
+
import { Button } from "../../../ui/button/index.js";
|
|
15
|
+
import Skeleton from "../../../ui/skeleton/skeleton.svelte";
|
|
16
|
+
import {
|
|
17
|
+
HeartAddIcon,
|
|
18
|
+
HeartRemoveIcon,
|
|
19
|
+
ShoppingCartAdd01Icon,
|
|
20
|
+
} from "@hugeicons/core-free-icons";
|
|
21
|
+
import { HugeiconsIcon } from "@hugeicons/svelte";
|
|
22
|
+
|
|
23
|
+
let {
|
|
24
|
+
id,
|
|
25
|
+
buttonBuyText = "Comprar",
|
|
26
|
+
isFavorite = $bindable(false),
|
|
27
|
+
isCart = $bindable(false),
|
|
28
|
+
isLoading = false,
|
|
29
|
+
onBuy,
|
|
30
|
+
onFavorite,
|
|
31
|
+
onCart,
|
|
32
|
+
}: {
|
|
33
|
+
id: string | number;
|
|
34
|
+
buttonBuyText?: string;
|
|
35
|
+
isFavorite?: boolean;
|
|
36
|
+
isCart?: boolean;
|
|
37
|
+
isLoading?: boolean;
|
|
38
|
+
onBuy?: (id: string | number) => void;
|
|
39
|
+
onFavorite?: (id: string | number) => void;
|
|
40
|
+
onCart?: (id: string | number) => void;
|
|
41
|
+
} = $props();
|
|
42
|
+
</script>
|
|
43
|
+
|
|
44
|
+
{#if isLoading}
|
|
45
|
+
<div class="flex items-center gap-2">
|
|
46
|
+
<Skeleton class="h-9 min-w-40 flex-1 rounded-md" />
|
|
47
|
+
<Skeleton class="size-9 rounded-full" />
|
|
48
|
+
<Skeleton class="size-9 rounded-full" />
|
|
49
|
+
</div>
|
|
50
|
+
{:else}
|
|
51
|
+
<div class="flex flex-wrap items-center gap-2">
|
|
52
|
+
<Button class="flex-1 min-w-40 bg-gradient" onclick={() => onBuy?.(id)}>
|
|
53
|
+
{buttonBuyText}
|
|
54
|
+
</Button>
|
|
55
|
+
|
|
56
|
+
<Button
|
|
57
|
+
size="icon"
|
|
58
|
+
class="rounded-full"
|
|
59
|
+
variant="outline"
|
|
60
|
+
aria-label={isFavorite ? "Remover dos favoritos" : "Adicionar aos favoritos"}
|
|
61
|
+
onclick={() => {
|
|
62
|
+
isFavorite = !isFavorite;
|
|
63
|
+
onFavorite?.(id);
|
|
64
|
+
}}
|
|
65
|
+
>
|
|
66
|
+
<HugeiconsIcon icon={isFavorite ? HeartRemoveIcon : HeartAddIcon} />
|
|
67
|
+
</Button>
|
|
68
|
+
|
|
69
|
+
<Button
|
|
70
|
+
size="icon"
|
|
71
|
+
class="rounded-full"
|
|
72
|
+
variant="outline"
|
|
73
|
+
aria-label="Adicionar ao carrinho"
|
|
74
|
+
onclick={() => {
|
|
75
|
+
isCart = !isCart;
|
|
76
|
+
onCart?.(id);
|
|
77
|
+
}}
|
|
78
|
+
>
|
|
79
|
+
<HugeiconsIcon icon={ShoppingCartAdd01Icon} />
|
|
80
|
+
</Button>
|
|
81
|
+
</div>
|
|
82
|
+
{/if}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
type $$ComponentProps = {
|
|
2
|
+
id: string | number;
|
|
3
|
+
buttonBuyText?: string;
|
|
4
|
+
isFavorite?: boolean;
|
|
5
|
+
isCart?: boolean;
|
|
6
|
+
isLoading?: boolean;
|
|
7
|
+
onBuy?: (id: string | number) => void;
|
|
8
|
+
onFavorite?: (id: string | number) => void;
|
|
9
|
+
onCart?: (id: string | number) => void;
|
|
10
|
+
};
|
|
11
|
+
declare const ProductDetailActions: import("svelte").Component<$$ComponentProps, {}, "isFavorite" | "isCart">;
|
|
12
|
+
type ProductDetailActions = ReturnType<typeof ProductDetailActions>;
|
|
13
|
+
export default ProductDetailActions;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
/**
|
|
3
|
+
* Breadcrumb de navegação para a página de detalhes do produto.
|
|
4
|
+
* Quando `isLoading` é true, exibe um Skeleton.
|
|
5
|
+
* @component
|
|
6
|
+
* @example
|
|
7
|
+
* ```svelte
|
|
8
|
+
* <ProductDetailBreadcrumb items={[{ label: "Home", href: "/" }, { label: "Hotel Baía Azul" }]} />
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<script lang="ts">
|
|
14
|
+
import Skeleton from "../../../ui/skeleton/skeleton.svelte";
|
|
15
|
+
import type { ProductDetailsBreadcrumbItem } from "../types";
|
|
16
|
+
|
|
17
|
+
let {
|
|
18
|
+
items,
|
|
19
|
+
isLoading = false,
|
|
20
|
+
}: {
|
|
21
|
+
items: ProductDetailsBreadcrumbItem[];
|
|
22
|
+
isLoading?: boolean;
|
|
23
|
+
} = $props();
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
{#if isLoading}
|
|
27
|
+
<Skeleton class="h-4 w-48 rounded-md" />
|
|
28
|
+
{:else}
|
|
29
|
+
<nav
|
|
30
|
+
aria-label="Breadcrumb"
|
|
31
|
+
class="flex items-center gap-1.5 text-sm text-muted-foreground"
|
|
32
|
+
>
|
|
33
|
+
{#each items as item, i (item.label)}
|
|
34
|
+
{#if item.href}
|
|
35
|
+
<a href={item.href} class="hover:text-foreground transition-colors"
|
|
36
|
+
>{item.label}</a
|
|
37
|
+
>
|
|
38
|
+
{:else}
|
|
39
|
+
<span class="text-foreground font-medium">{item.label}</span>
|
|
40
|
+
{/if}
|
|
41
|
+
{#if i < items.length - 1}
|
|
42
|
+
<span class="select-none">/</span>
|
|
43
|
+
{/if}
|
|
44
|
+
{/each}
|
|
45
|
+
</nav>
|
|
46
|
+
{/if}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ProductDetailsBreadcrumbItem } from "../types";
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
items: ProductDetailsBreadcrumbItem[];
|
|
4
|
+
isLoading?: boolean;
|
|
5
|
+
};
|
|
6
|
+
declare const ProductDetailBreadcrumb: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
7
|
+
type ProductDetailBreadcrumb = ReturnType<typeof ProductDetailBreadcrumb>;
|
|
8
|
+
export default ProductDetailBreadcrumb;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
/**
|
|
3
|
+
* Descrição do produto (curta e longa opcional).
|
|
4
|
+
* Quando `isLoading` é true, exibe Skeletons.
|
|
5
|
+
* @component
|
|
6
|
+
* @example
|
|
7
|
+
* ```svelte
|
|
8
|
+
* <ProductDetailDescription description={data.description} longDescription={data.longDescription} />
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<script lang="ts">
|
|
14
|
+
import Skeleton from "../../../ui/skeleton/skeleton.svelte";
|
|
15
|
+
|
|
16
|
+
let {
|
|
17
|
+
description,
|
|
18
|
+
longDescription,
|
|
19
|
+
isLoading = false,
|
|
20
|
+
}: {
|
|
21
|
+
description: string;
|
|
22
|
+
longDescription?: string;
|
|
23
|
+
isLoading?: boolean;
|
|
24
|
+
} = $props();
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
{#if isLoading}
|
|
28
|
+
<div class="flex flex-col gap-2">
|
|
29
|
+
{#each Array.from({ length: 3 }) as _, i (i)}
|
|
30
|
+
<Skeleton class="h-4 w-full rounded-md" />
|
|
31
|
+
{/each}
|
|
32
|
+
</div>
|
|
33
|
+
{:else}
|
|
34
|
+
<p class="leading-7 text-foreground/90">{description}</p>
|
|
35
|
+
{#if longDescription}
|
|
36
|
+
<p class="leading-7 text-foreground/75">{longDescription}</p>
|
|
37
|
+
{/if}
|
|
38
|
+
{/if}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
type $$ComponentProps = {
|
|
2
|
+
description: string;
|
|
3
|
+
longDescription?: string;
|
|
4
|
+
isLoading?: boolean;
|
|
5
|
+
};
|
|
6
|
+
declare const ProductDetailDescription: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
7
|
+
type ProductDetailDescription = ReturnType<typeof ProductDetailDescription>;
|
|
8
|
+
export default ProductDetailDescription;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
/**
|
|
3
|
+
* Bloco de características do produto (lista de bullets).
|
|
4
|
+
* Quando `isLoading` é true, exibe Skeletons.
|
|
5
|
+
* @component
|
|
6
|
+
* @example
|
|
7
|
+
* ```svelte
|
|
8
|
+
* <ProductDetailFeatures features={["Wi-Fi gratuito", "Pequeno-almoço incluído"]} />
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<script lang="ts">
|
|
14
|
+
import Skeleton from "../../../ui/skeleton/skeleton.svelte";
|
|
15
|
+
|
|
16
|
+
let {
|
|
17
|
+
features,
|
|
18
|
+
isLoading = false,
|
|
19
|
+
}: {
|
|
20
|
+
features: string[];
|
|
21
|
+
isLoading?: boolean;
|
|
22
|
+
} = $props();
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
{#if isLoading}
|
|
26
|
+
<div class="flex flex-col gap-2">
|
|
27
|
+
{#each Array.from({ length: 3 }) as _, i (i)}
|
|
28
|
+
<Skeleton class="h-4 w-2/3 rounded-md" />
|
|
29
|
+
{/each}
|
|
30
|
+
</div>
|
|
31
|
+
{:else}
|
|
32
|
+
<ul class="flex flex-col gap-2">
|
|
33
|
+
{#each features as feature, i (feature)}
|
|
34
|
+
<li class="flex items-start gap-2 text-sm text-foreground/90">
|
|
35
|
+
<span aria-hidden="true" class="mt-1.5 size-1.5 shrink-0 rounded-full bg-primary"></span>
|
|
36
|
+
<span>{feature}</span>
|
|
37
|
+
</li>
|
|
38
|
+
{/each}
|
|
39
|
+
</ul>
|
|
40
|
+
{/if}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
type $$ComponentProps = {
|
|
2
|
+
features: string[];
|
|
3
|
+
isLoading?: boolean;
|
|
4
|
+
};
|
|
5
|
+
declare const ProductDetailFeatures: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
6
|
+
type ProductDetailFeatures = ReturnType<typeof ProductDetailFeatures>;
|
|
7
|
+
export default ProductDetailFeatures;
|