@rocketsearch/nuxt-uappi 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -0
- package/module.js +90 -0
- package/package.json +20 -0
- package/runtime/banner.js +168 -0
- package/runtime/components/RocketAutocomplete.vue +279 -0
- package/runtime/components/RocketBanner.vue +130 -0
- package/runtime/components/RocketSearch.vue +480 -0
- package/runtime/components/RocketShowcase.vue +190 -0
- package/runtime/components/banner/RocketBannerItem.vue +219 -0
- package/runtime/components/search/RocketSearchFacets.vue +142 -0
- package/runtime/components/search/RocketSearchPagination.vue +61 -0
- package/runtime/components/search/RocketSearchRange.vue +75 -0
- package/runtime/css/autocomplete.css +210 -0
- package/runtime/css/banner.css +138 -0
- package/runtime/css/common.css +197 -0
- package/runtime/css/search.css +706 -0
- package/runtime/css/showcase.css +56 -0
- package/runtime/package.json +3 -0
- package/runtime/plugin.js +98 -0
- package/runtime/rocket.js +632 -0
- package/runtime/uappi.js +71 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/* Port de linxecommerce/2.0.0/src/scss/showcase.scss — CSS nested nativo.
|
|
2
|
+
O Swiper vira scroll-snap: arraste/touch nativos, setas rolam uma "página". */
|
|
3
|
+
|
|
4
|
+
[data-rocket-showcase-position] {
|
|
5
|
+
margin-top: 60px;
|
|
6
|
+
margin-bottom: 60px;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.rocket-search__showcase {
|
|
10
|
+
--showcase-gap: 16px;
|
|
11
|
+
position: relative;
|
|
12
|
+
|
|
13
|
+
& .rocket-search__showcase__title {
|
|
14
|
+
position: relative;
|
|
15
|
+
display: block;
|
|
16
|
+
margin-bottom: 30px;
|
|
17
|
+
font-size: 25px;
|
|
18
|
+
font-weight: 700;
|
|
19
|
+
text-align: center;
|
|
20
|
+
|
|
21
|
+
&.rocket-search__product-placeholder__item {
|
|
22
|
+
width: 150px;
|
|
23
|
+
height: 30px;
|
|
24
|
+
margin-left: auto;
|
|
25
|
+
margin-right: auto;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
& .rocket-search__showcase__description {
|
|
30
|
+
display: block;
|
|
31
|
+
margin-bottom: 30px;
|
|
32
|
+
text-align: center;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
& .rocket-search__showcase__track {
|
|
36
|
+
display: flex;
|
|
37
|
+
gap: var(--showcase-gap);
|
|
38
|
+
margin: 0;
|
|
39
|
+
padding: 0;
|
|
40
|
+
list-style: none;
|
|
41
|
+
overflow-x: auto;
|
|
42
|
+
scroll-snap-type: x mandatory;
|
|
43
|
+
scrollbar-width: none;
|
|
44
|
+
|
|
45
|
+
&::-webkit-scrollbar {
|
|
46
|
+
display: none;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
& .rocket-search__showcase__slide {
|
|
51
|
+
flex: 0 0 calc((100% - (var(--product-columns) - 1) * var(--showcase-gap)) / var(--product-columns));
|
|
52
|
+
min-width: 0;
|
|
53
|
+
scroll-snap-align: start;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { createRocket, sectionFromNivel } from '<%= options.runtimeDir %>/rocket.js';
|
|
2
|
+
|
|
3
|
+
const options = <%= JSON.stringify(options.config) %>;
|
|
4
|
+
|
|
5
|
+
// Traduz o `dadosPageAtual` do tema (resposta da Front API da Uappi) para o contexto da
|
|
6
|
+
// página — é o que o browsingContext entregava na Linx.
|
|
7
|
+
function pageFromState (dados) {
|
|
8
|
+
const nivel = dados && dados.estrutura && dados.estrutura.nivel;
|
|
9
|
+
const section = sectionFromNivel(nivel);
|
|
10
|
+
if (!section) return null;
|
|
11
|
+
const conteudo = (dados && dados.conteudo) || {};
|
|
12
|
+
return {
|
|
13
|
+
section,
|
|
14
|
+
productId: section === 'pdp' && conteudo.id != null ? String(conteudo.id) : null,
|
|
15
|
+
categoryId: section === 'category' && conteudo.id != null ? String(conteudo.id) : null,
|
|
16
|
+
product: section === 'pdp' ? conteudo : null
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default function ({ app, store, $axios }, inject) {
|
|
21
|
+
const rocket = createRocket(options);
|
|
22
|
+
inject('rocket', rocket);
|
|
23
|
+
|
|
24
|
+
if (process.server) {
|
|
25
|
+
// Banner loading="ssr" busca no servidor e precisa do pageType da página renderizada.
|
|
26
|
+
// Só o contexto: evento nenhum sai do servidor.
|
|
27
|
+
if (store) {
|
|
28
|
+
store.subscribe((mutation) => {
|
|
29
|
+
const page = mutation.type === 'setDadosPageAtual' && pageFromState(mutation.payload);
|
|
30
|
+
if (page) rocket.setPage(page);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
rocket.initDebugFromUrl();
|
|
37
|
+
rocket.flushPendingCartEvents();
|
|
38
|
+
|
|
39
|
+
let pageResolved = false;
|
|
40
|
+
|
|
41
|
+
function applyPage (dados) {
|
|
42
|
+
const page = pageFromState(dados);
|
|
43
|
+
if (!page) return;
|
|
44
|
+
pageResolved = true;
|
|
45
|
+
rocket.setPage(page);
|
|
46
|
+
rocket.fireProductView();
|
|
47
|
+
rocket.firePageViewIfSectionChanged();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Primeira carga: a página já veio do SSR, o commit aconteceu no servidor e o estado
|
|
51
|
+
// chega hidratado — não há mutation no cliente para ouvir.
|
|
52
|
+
if (store && store.state.dadosPageAtual) applyPage(store.state.dadosPageAtual);
|
|
53
|
+
|
|
54
|
+
// Navegação SPA: o tema commita setDadosPageAtual quando a página nova carrega os dados.
|
|
55
|
+
if (store) {
|
|
56
|
+
store.subscribe((mutation) => {
|
|
57
|
+
if (mutation.type === 'setDadosPageAtual') applyPage(mutation.payload);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (!pageResolved) rocket.firePageViewIfSectionChanged();
|
|
62
|
+
|
|
63
|
+
// Só depois do onReady: a navegação INICIAL do Nuxt também passa pelo beforeEach
|
|
64
|
+
// (from = '/'), e o reset apagaria o contexto que acabou de vir do SSR.
|
|
65
|
+
app.router.onReady(() => {
|
|
66
|
+
app.router.beforeEach((to, from, next) => {
|
|
67
|
+
if (to.path !== from.path) {
|
|
68
|
+
pageResolved = false;
|
|
69
|
+
rocket.setPage({});
|
|
70
|
+
}
|
|
71
|
+
next();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Página que não commita dados (ex.: rota estática sem Front API) ainda precisa de
|
|
75
|
+
// page_view — sem isso a jornada ficaria presa na seção anterior.
|
|
76
|
+
app.router.afterEach((to, from) => {
|
|
77
|
+
if (to.path === from.path) return;
|
|
78
|
+
setTimeout(() => {
|
|
79
|
+
if (!pageResolved) rocket.firePageViewIfSectionChanged();
|
|
80
|
+
}, 1500);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// Mesmo ponto único que a Linx interceptava (/carrinho/adicionar-produto): aqui todo
|
|
85
|
+
// add-to-cart do tema passa por POST /v2/front/checkout/cart no $axios.
|
|
86
|
+
if ($axios) {
|
|
87
|
+
$axios.onResponse((response) => {
|
|
88
|
+
const config = response && response.config;
|
|
89
|
+
if (!config || String(config.method).toLowerCase() !== 'post') return;
|
|
90
|
+
if (!/\/v2\/front\/checkout\/cart\/?$/.test(config.url || '')) return;
|
|
91
|
+
try {
|
|
92
|
+
const payload = typeof config.data === 'string' ? JSON.parse(config.data) : config.data;
|
|
93
|
+
rocket.trackAddToCart(payload);
|
|
94
|
+
}
|
|
95
|
+
catch (e) { /* tracking é best-effort */ }
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|