feat: criando template

This commit is contained in:
Caroline Moran 2022-12-05 14:23:46 -04:00
commit 971516bb72
72 changed files with 51913 additions and 0 deletions

13
.editorconfig Normal file
View File

@ -0,0 +1,13 @@
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 100

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
* text=auto eol=lf

79
.gitignore vendored Normal file
View File

@ -0,0 +1,79 @@
*node_modules
node_modules
# para arquivos sass e scss
storefront/styles/css
**/*.sass-cache/
**/*.css.map
# Para arquivos de desenvolvimnto
public/
src\arquivos\sass\lib\_sprite.scss
# gulp
dist/
.temp/
# node
### Node ###
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.vscode/*
!.vscode/extensions.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.scannerwork

10
.gitpod.yml Normal file
View File

@ -0,0 +1,10 @@
# This configuration file was automatically generated by Gitpod.
# Please adjust to your needs (see https://www.gitpod.io/docs/config-gitpod-file)
# and commit this file to your remote git repository to share the goodness with others.
tasks:
- init: yarn install
vscode:
extensions:
- dbaeumer.vscode-eslint

1
.husky/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
_

4
.husky/commit-msg Normal file
View File

@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
yarn commitlint --edit $1

8
.husky/common.sh Normal file
View File

@ -0,0 +1,8 @@
command_exists () {
command -v "$1" >/dev/null 2>&1
}
# Workaround for Windows 10, Git Bash and Yarn
if command_exists winpty && test -t 1; then
exec < /dev/tty
fi

4
.husky/pre-commit Normal file
View File

@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
yarn lerna run --concurrency 3 --stream lint --since HEAD --exclude-dependents

9
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,9 @@
{
"recommendations": [
"sonarsource.sonarlint-vscode",
"dbaeumer.vscode-eslint",
"editorconfig.editorconfig",
"esbenp.prettier-vscode",
"eamodio.gitlens"
]
}

27
README.md Normal file
View File

@ -0,0 +1,27 @@
# CHECKOUT M3 ACADEMY
## Instalação e desenvolvimento
- abra o terminal
- yarn install
- cd checkout
- npm i
## Comando para rodar o projeto
- na pasta checkout (cd checkout assim que abrir o projeto)
- rodar: npm run dev
## Versão do node.js:
- NODEJS >= 12
## URL para SRC das tags img:
- https://agenciamagma.vteximg.com.br/arquivos/NomeDaimagemSalvanaPastaAssetsImgs.png
## src/template-checkout
- NÃO ALTERAR ESSES ARQUIVOS
- os arquivos html dessa pasta são meramente ilustrativos, só apra mostrar como está a estrutura html atual no admin da loja
- alterálos não surtirá efeito na pagina, porém é um backup do atual e por isso não deve mexer.

22
checkout/.eslintrc.js Normal file
View File

@ -0,0 +1,22 @@
module.exports = {
env: {
browser: true,
commonjs: true,
es6: false,
jquery: true,
},
globals: {
Modulo: true,
},
extends: ["eslint:recommended", "plugin:prettier/recommended"],
plugins: ["prettier"],
parserOptions: {
ecmaVersion: 10,
sourceType: "module",
},
rules: {
"prettier/prettier": "error",
"linebreak-style": ["warn", "unix"],
"no-undef": "off",
},
};

View File

@ -0,0 +1,6 @@
{
"semi": true,
"singleQuote": false,
"tabWidth": 4,
"useTabs": false
}

147
checkout/gulpfile.js Normal file
View File

@ -0,0 +1,147 @@
const gulp = require("gulp"),
gulpif = require("gulp-if"),
del = require("del"),
connect = require("gulp-connect"),
sourcemaps = require("gulp-sourcemaps"),
autoprefixer = require("gulp-autoprefixer"),
rename = require("gulp-rename"),
sass = require("gulp-sass")(require("sass"));
/**
___ _ _ _ _
/ __| |_ ___ __| |_____ _ _| |_ ___ ___| |_ _ _ _ __
| (__| ' \/ -_) _| / / _ \ || | _| (_-</ -_) _| || | '_ \
\___|_||_\___\__|_\_\___/\_,_|\__| /__/\___|\__|\_,_| .__/
|_|
*/
const webpack = require("webpack");
const isProduction = process.env.NODE_ENV === "production";
const paths = {
styles: {
src: "src/arquivos/sass/*.{scss,css,sass}",
lib: "src/arquivos/sass/lib",
watch: "src/arquivos/sass/**/*.scss",
},
scripts: {
watch: "src/arquivos/js/**/*.js",
},
img: {
src: "src/arquivos/assets/imgs/**",
watch: "src/arquivos/assets/imgs/**",
},
fonts: {
src: "src/arquivos/assets/fonts/**.*",
},
output: "dist",
outputStatic: "dist/arquivos",
outputStaticFonts: "dist/arquivos/fonts",
outputStaticImages: "dist/arquivos/imgs",
tmp: ".temp",
};
function clean() {
return del([paths.output, paths.tmp]);
}
function styles() {
return gulp
.src(paths.styles.src)
.pipe(gulpif(!isProduction, sourcemaps.init()))
.pipe(
sass({
outputStyle: "compressed",
}).on("error", sass.logError)
)
.pipe(
autoprefixer({
cascade: false,
})
)
.pipe(
rename({
prefix: "",
extname: ".css",
})
)
.pipe(gulpif(!isProduction, sourcemaps.write()))
.pipe(gulp.dest(paths.outputStatic))
.pipe(connect.reload());
}
function scripts() {
let webpackConfig = require("./webpack.dev.js");
if (process.env.NODE_ENV === "production") {
webpackConfig = require("./webpack.prod.js");
}
return new Promise((resolve) =>
webpack(webpackConfig, (err, stats) => {
if (err) console.log("Webpack", err);
console.log(
stats.toString({
all: false,
modules: false,
maxModules: 0,
errors: true,
warnings: true,
moduleTrace: true,
errorDetails: true,
colors: true,
chunks: true,
})
);
resolve();
connect.reload();
})
);
}
function images() {
return gulp
.src(paths.img.watch)
.pipe(gulp.dest(paths.outputStaticImages))
.pipe(connect.reload());
}
function customFonts() {
return gulp
.src(paths.fonts.src)
.pipe(
rename((path) => ({
dirname: "",
basename: path.basename,
extname: path.extname + ".css",
}))
)
.pipe(gulp.dest(paths.outputStaticFonts))
.pipe(connect.reload());
}
function watch() {
devServer();
gulp.watch(paths.scripts.watch, { ignoreInitial: false }, scripts);
gulp.watch(paths.styles.watch, { ignoreInitial: false }, styles);
gulp.watch(paths.fonts.src, { ignoreInitial: false }, customFonts);
gulp.watch(paths.img.src, { ignoreInitial: false }, images);
}
function devServer() {
connect.server({
root: paths.output,
livereload: true,
port: 3000,
});
}
const build = gulp.series(clean, gulp.parallel(scripts, styles, customFonts));
exports.build = build;
exports.clean = clean;
exports.scripts = scripts;
exports.styles = styles;
exports.devServer = devServer;
exports.watch = gulp.series(build, watch);

18166
checkout/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

56
checkout/package.json Normal file
View File

@ -0,0 +1,56 @@
{
"name": "checkout",
"version": "1.0.0",
"main": "index.js",
"license": "UNLICENSED",
"scripts": {
"dev": "cross-env NODE_ENV=development gulp watch",
"prod": "cross-env NODE_ENV=production gulp build",
"lint": "eslint ./src --fix"
},
"dependencies": {
"@babel/plugin-transform-async-to-generator": "^7.14.5",
"cookie": "^0.4.1",
"del": "^6.0.0",
"glob": "^7.1.7",
"gulp": "^4.0.2",
"gulp-autoprefixer": "^8.0.0",
"gulp-concat": "^2.6.1",
"gulp-connect": "^5.7.0",
"gulp-if": "^3.0.0",
"gulp-rename": "^2.0.0",
"gulp-sass": "^5.0.0",
"gulp-sourcemaps": "^3.0.0",
"jquery": "^3.6.0",
"m3-utils": "^0.1.0",
"sass": "^1.38.1",
"terser-webpack-plugin": "^5.1.4"
},
"devDependencies": {
"@babel/core": "^7.15.0",
"@babel/preset-env": "^7.15.0",
"@babel/preset-react": "^7.14.5",
"babel-loader": "^8.2.2",
"cross-env": "^7.0.3",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^3.4.1",
"lint-staged": "^11.1.2",
"prettier": "^2.3.2",
"webpack": "^5.51.1",
"webpack-merge": "^5.8.0"
},
"babel": {
"presets": [
"@babel/env",
"@babel/react"
]
},
"browserslist": [
"defaults"
],
"lint-staged": {
"src/**/*": [
"yarn lint"
]
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 562 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 707 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

@ -0,0 +1,11 @@
import CheckoutUI from "./components/CheckoutUI";
import { Container } from "m3-utils";
import Header from "./components/Header";
import Footer from "./components/Footer";
const m3Checkout = new Container({
appName: "m3-checkout",
components: [CheckoutUI, Header, Footer],
});
m3Checkout.start();

View File

@ -0,0 +1,69 @@
import { isSmallerThen768 } from "../helpers/MediasMatch";
import { alterarTamanhoImagemSrcVtex } from "../helpers/vtexUtils";
import waitForEl from "../helpers/waitForEl";
export default class CheckoutUI {
constructor() {
this.init();
if (isSmallerThen768) {
this.selectors();
this.events();
this.setFooterDropdown();
}
}
selectors() {
this.title = $(".footerCheckout__title");
this.contents = $(".footerCheckout__content");
}
events() {
this.title.click(this.toggleFooterDropdown.bind(this));
}
setFooterDropdown() {
for (let i = 0; i < this.title.length; i++) {
this.title[i].classList.add("dropdown__title");
this.contents[i].classList.add("dropdown__content--closed");
}
}
toggleFooterDropdown(event) {
event.target.classList.toggle("closed");
event.target.nextElementSibling.classList.toggle(
"dropdown__content--closed"
);
}
init() {
this.configThumb();
waitForEl(".product-image img", this.resizeImages.bind(this));
$(window).on("orderFormUpdated.vtex", this.resizeImages.bind(this));
}
configThumb() {
if (isSmallerThen768) {
this.width = 73;
this.height = 96;
} else {
this.width = 63;
this.height = 83;
}
}
resizeImages() {
$(".product-image img").each((i, el) => {
const $el = $(el);
$el.attr(
"src",
alterarTamanhoImagemSrcVtex(
$el.attr("src"),
this.width,
this.height
)
);
});
}
}

View File

@ -0,0 +1,20 @@
import { waitElement } from "m3-utils";
export default class Footer {
constructor() {
this.init();
}
async init() {
await this.selectors();
console.log(this.item);
}
async selectors() {
this.item = await waitElement("#my-element", {
//#my-element pode ser a class ou o id do elemento html qeu vocÊ quer pegar
timeout: 5000, // vai esperar 5 segundos antes de rejeitar a promise
interval: 1000, // vai verificar a cada 1 segundo se o elemento existe
});
}
}

View File

@ -0,0 +1,21 @@
// import waitForEl from "../helpers/waitForEl";
import { waitElement } from "m3-utils";
export default class Header {
constructor() {
this.init();
}
async init() {
await this.selectors();
console.log(this.item);
}
async selectors() {
this.item = await waitElement("#my-element", {
//#my-element pode ser a class ou o id do elemento html qeu vocÊ quer pegar
timeout: 5000, // vai esperar 5 segundos antes de rejeitar a promise
interval: 1000, // vai verificar a cada 1 segundo se o elemento existe
});
}
}

View File

@ -0,0 +1,34 @@
/**
* Helper de para ultização de eventos sobre a navegação por hash
*/
export default class HashRouter {
constructor(routes) {
this.routes = routes;
window.addEventListener("hashchange", this.hashChange.bind(this));
this.init();
}
hashChange(e) {
const from = new URL(e.oldURL).hash || "/";
const to = new URL(e.newURL).hash || "/";
this.routes.forEach((route) => {
if (route.path === to) {
route.onEnter && route.onEnter();
} else if (route.path === from) {
route.onLeave && route.onLeave();
}
});
}
init() {
const actualHash = window.location.hash || "/";
this.routes.forEach((route) => {
if (route.path === actualHash) {
route.onEnter && route.onEnter();
}
});
}
}

View File

@ -0,0 +1 @@
export const isSmallerThen768 = window.matchMedia("(max-width:768px)").matches;

View File

@ -0,0 +1,75 @@
/* eslint-disable no-useless-escape */
import cookie from "cookie";
class Cookie {
get(sKey) {
if (!sKey) {
return null;
}
const cookies = cookie.parse(document.cookie);
return cookies[sKey] || null;
}
set(sKey, sValue, vEnd, sPath, sDomain, bSecure) {
if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) {
return false;
}
var sExpires = "";
if (vEnd) {
switch (vEnd.constructor) {
case Number:
sExpires =
vEnd === Infinity
? "; expires=Fri, 31 Dec 9999 23:59:59 GMT"
: "; max-age=" + vEnd;
break;
case String:
sExpires = "; expires=" + vEnd;
break;
case Date:
sExpires = "; expires=" + vEnd.toUTCString();
break;
}
}
document.cookie =
encodeURIComponent(sKey) +
"=" +
encodeURIComponent(sValue) +
sExpires +
(sDomain ? "; domain=" + sDomain : "") +
(sPath ? "; path=" + sPath : "") +
(bSecure ? "; secure" : "");
return true;
}
delete(sKey, sPath, sDomain) {
if (!this.hasItem(sKey)) {
return false;
}
document.cookie =
encodeURIComponent(sKey) +
"=; expires=Thu, 01 Jan 1970 00:00:00 GMT" +
(sDomain ? "; domain=" + sDomain : "") +
(sPath ? "; path=" + sPath : "");
return true;
}
has(sKey) {
if (!sKey) {
return false;
}
return new RegExp(
"(?:^|;\\s*)" +
encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") +
"\\s*\\="
).test(document.cookie);
}
keys() {
return cookie.parse(document.cookie);
}
}
export default new Cookie();

View File

@ -0,0 +1,28 @@
/**
* Função para verificar se estamos em uma das paginas
* que são passadas por argumento
* @param {array} [varname] um array de strings
* @return {Boolean} [description]
*/
function isPage() {
const identificacaoMetaPage = $('meta[name="page"]').prop("content") || "";
const classTagBody = $("body").attr("class") || "";
const pageDataLayer =
typeof dataLayer !== "undefined"
? window.dataLayer[0].pageCategory
: "";
for (const i in arguments) {
// resultado-busca na tag body
if (
identificacaoMetaPage.search(arguments[i]) >= 0 ||
pageDataLayer === arguments[i] ||
classTagBody.search(arguments[i]) >= 0
)
return true;
}
return false;
}
export default isPage;

View File

@ -0,0 +1,74 @@
/**
* Altera as dimenções especificadas na url da img
* @param {string} src url da imagem na VTEX
* @param {int} width
* @param {int} height
* @return {string} url da imagem com o tamanho alterado
*/
export function alterarTamanhoImagemSrcVtex(src, width, height) {
if (typeof src == "undefined") {
console.warn("Parametro 'src' não recebido.");
return;
}
width = typeof width == "undefined" ? 1 : width;
height = typeof height == "undefined" ? width : height;
src = src.replace(
/\/(\d+)(-(\d+-\d+)|(_\d+))\//g,
"/$1-" + width + "-" + height + "/"
);
return src;
}
/**
* Obtem Preco
* caso o preco recebido seja um Float ou int,
* 'Ex.': 10.2 ->'10,20'
* Recebendo uma string o valor sera retornado como um float
* 'Ex.': 'R$1.234,30' -> 1234.3
* @param {FloatZstring} price preço
* @return {[type]} [description]
*/
export function getPrice(price) {
if (!price) {
return 0;
}
if (isNaN(price)) {
return parseFloat(
price.replace("R$", "").replace(".", "").replace(",", ".")
);
} else {
price = price || 0;
price = price.toLocaleString("pt-BR", {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
});
return price;
}
}
export function formatCurrency() {
return Number(value).toLocaleString("pt-BR", {
style: "currency",
currency: "BRL",
});
}
export function getSellerChannel() {
var name = "VTEXSC=sc=";
var ca = document.cookie.split(";");
let res = "1";
ca.forEach((c) => {
let value = String(c);
while (value.charAt(0) == " ") value = value.substring(1);
if (value.indexOf(name) == 0) {
res = value.substring(name.length, value.length);
}
});
return res;
}

View File

@ -0,0 +1,22 @@
/**
* Espera um elemento exitir no dom e executa o callback
*
* @param {string} selector seletor do elemento que dejesa esperar pela criação
* @param {function} callback Função a ser executada quando tal elemento existir
*/
export default function waitForEl(selector) {
return new Promise((resolve) => {
function waitForElCb(s) {
const el = jQuery(s);
if (el.length) {
resolve(el);
} else {
setTimeout(function () {
waitForElCb(selector);
}, 100);
}
}
waitForElCb(selector);
});
}

View File

@ -0,0 +1,25 @@
var Evento = function () {
var _this = this;
_this.handlers = [];
_this.subscribe = function (fn) {
this.handlers.push(fn);
}.bind(_this);
_this.unsubscribe = function (fn) {
this.handlers = this.handlers.filter(function (item) {
if (item !== fn) {
return item;
}
});
}.bind(_this);
_this.fire = function (dados, thisObj) {
var scope = thisObj || window;
this.handlers.forEach(function (item) {
item.call(scope, dados);
});
}.bind(_this);
};
export default Evento;

View File

@ -0,0 +1,105 @@
import Evento from "./Evento";
var RestricaoDeConculsao = function (funcaoDeAvaliacao, mensagemDeErro) {
var _this = this,
_regraAtiva = true,
_mensagemDeErro;
var eventos = {
tentativaDeFinalizacao: new Evento(),
aplicavel: new Evento(),
naoAplicavel: new Evento(),
};
_this.on = function (evento, fn) {
if (Reflect.has(eventos, evento)) {
eventos[evento].subscribe(fn);
}
};
_this.off = function (evento, fn) {
if (Reflect.has(eventos, evento)) {
eventos[evento].unsubscribe(fn);
}
};
_this.mensagemDeErro = function (
mensagemDeErro = "Forneca as informações para finalizar a compra"
) {
if (mensagemDeErro) _mensagemDeErro = mensagemDeErro;
return _mensagemDeErro;
};
_this.inicializar = function configurarEventos() {
$(window).on("orderFormUpdated.vtex", atualizacaoDoPedido);
window.vtexjs.checkout.getOrderForm();
};
function feedback(tipo, titulo, detalhe) {
var message = {
content: {
title: titulo,
detail: detalhe,
},
type: tipo,
};
if ("undefined" != typeof $) {
$(window).trigger("addMessage", message);
} else {
console.warn("Erro ao acionar front-messages-ui");
}
}
function clickBtnDesabilitado(event) {
event.preventDefault();
feedback("warning", "Erro ", _mensagemDeErro);
eventos.tentativaDeFinalizacao.fire();
}
function aplicavel(alternativa) {
// se a regra estiver desativada não sera aplicada
alternativa = alternativa && _regraAtiva;
var evento = alternativa ? "aplicavel" : "naoAplicavel";
eventos[evento].fire();
ativacao(alternativa);
}
function ativacao(alternativa) {
var $btnContainer = $(".payment-submit-wrap,.payment-submit-hide");
var btns = $btnContainer.find("button");
btns.each(function (i, el) {
$(el).toggleClass("btn-warning", alternativa);
});
if (!alternativa) {
$btnContainer.off("click", clickBtnDesabilitado);
} else {
$btnContainer.on("click", clickBtnDesabilitado);
}
}
_this.ativar = function () {
_regraAtiva = true;
ativacao(_regraAtiva);
};
_this.desativar = function () {
_regraAtiva = false;
ativacao(_regraAtiva);
};
function atualizacaoDoPedido(event, orderform) {
var ehAplicavel = funcaoDeAvaliacao.call(funcaoDeAvaliacao, orderform);
if (typeof ehAplicavel === "boolean") {
aplicavel(ehAplicavel);
} else {
aplicavel(false);
console.error(
"função de avaliação retornando resultado indefinido.\n",
ehAplicavel
);
}
}
_this.mensagemDeErro(mensagemDeErro);
_this.inicializar();
};
export default RestricaoDeConculsao;

View File

@ -0,0 +1,17 @@
export default class CatalogService {
async getSkusData(skus) {
const skusPromises = skus.map(this.getSkuData);
const responses = await Promise.all(skusPromises);
return Promise.all(responses.map((r) => r.json()));
}
getSkuData(sku) {
const urlSku = "/produto/sku/" + sku;
return fetch(urlSku, {
method: "GET",
});
}
}

View File

@ -0,0 +1,29 @@
export default class CartItem {
constructor({
productID,
skuID,
url,
imageUrl,
name,
priceOf,
price,
maxInstallmentAmount,
maxInstallmentValue,
qtd,
id,
availableQtd,
}) {
this.id = id;
this.productID = productID;
this.skuID = skuID;
this.url = url;
this.imageUrl = imageUrl;
this.name = name;
this.priceOf = priceOf;
this.price = price;
this.maxInstallmentAmount = maxInstallmentAmount;
this.maxInstallmentValue = maxInstallmentValue;
this.qtd = qtd;
this.availableQtd = availableQtd;
}
}

View File

@ -0,0 +1,97 @@
import { getSalesChannel } from "Helpers/utils";
import { PubSub } from "@agenciam3/pkg/dist/lib/index";
import CartItem from "./CartItem";
export default class CheckoutService {
constructor() {
this.eventsName = {
CHECKOUT_UPDATED: "CHECKOUT_UPDATED",
ORDERFORM_UPDATED: "ORDERFORM_UPDATED",
};
this.events = new PubSub();
if (window.vtexjs) {
this.checkout = window.vtexjs.checkout;
this.orderform = window.vtexjs.checkout.orderForm;
this.events.subscribe(
this.eventsName.ORDERFORM_UPDATED,
this._orderFormUpdated.bind(this)
);
}
}
_orderFormUpdated(evt, orderForm) {
const cartItems = this._mapOrderFormToCartItems(orderForm);
this.events.publish(this.eventsName.CHECKOUT_UPDATED, cartItems);
}
async addItemsToCart(items) {
try {
return await this.checkout.addToCart(
items,
null,
getSalesChannel()
);
} catch (err) {
console.log(err);
}
}
async rmAllItems() {
try {
return await this.checkout.removeAllItems();
} catch (err) {
console.log(err);
}
}
async updateCartItemsQtd(items, qtd) {
try {
const orderForm = await this.checkout.getOrderForm();
let itemIndex;
for (let i = 0; i < orderForm.items.length; i++) {
if (orderForm.items[i].uniqueId == items.id) {
itemIndex = i;
}
}
const updateItem = {
index: itemIndex,
quantity: qtd,
};
return await window.vtexjs.checkout.updateItems(
[updateItem],
null,
false
);
} catch (err) {
console.log(err);
}
}
async getCartItems() {
try {
const orderform = await this.checkout.getOrderForm();
return this._mapOrderFormToCartItems(orderform);
} catch (err) {
return [];
}
}
_mapOrderFormToCartItems(orderform) {
if (orderform.items.length === 0) return [];
return orderform.items.map(
(item) =>
new CartItem({
id: item.uniqueId,
imageUrl: item.imageUrl,
skuID: item.id,
productID: item.productId,
qtd: item.quantity,
price: item.price,
priceOf: item.listPrice,
name: item.name,
url: item.detailUrl,
})
);
}
}

View File

@ -0,0 +1,5 @@
@import "./utils/all";
@import "./partials/header";
@import "./partials/footer";
@import "./checkout/checkout.scss";

View File

@ -0,0 +1,289 @@
.checkout-container {
.client-pre-email {
border-color: $color-gray4;
font-family: $font-family;
padding-top: 8px;
.link-cart {
a {
color: $color-black;
font-size: 14px;
&:hover {
color: lighen($color-black, 10);
}
}
}
.pre-email {
flex-direction: column;
display: flex;
align-items: center;
justify-content: center;
h3 {
margin-bottom: 16px;
span {
color: #303030;
font-size: 24px;
}
small {
color: $color-gray4;
}
}
}
.client-email {
margin: 0 0 16px;
input {
box-shadow: none;
color: $color-black;
font-family: $font-family;
padding: 0 16px;
border: 2px solid $color-gray3;
box-sizing: border-box;
border-radius: 5px;
@media (max-width: 490px) {
width: auto;
}
}
button {
background-color: $color-black;
border-radius: 5px;
border: none;
font-family: $font-family;
height: 54px;
right: 0;
top: 0;
@media (max-width: 490px) {
height: 48px;
margin: 0;
position: absolute;
}
}
span.help.error {
color: red;
}
}
.emailInfo {
padding: 16px;
background-color: $color-white;
border: 1px solid $color-gray4;
border-radius: 0;
h3 {
color: #303030;
margin: 0 0 8px 0;
}
ul {
margin: 0;
li {
span {
color: $color-black;
}
i::before {
color: $color-black;
font-size: 1rem;
opacity: 1;
}
}
}
i::before {
color: $color-black;
font-size: 6rem;
opacity: 0.5;
}
}
}
.shipping-data,
.payment-data,
.client-profile-data {
.accordion-group {
border-radius: 0;
border: 1px solid $color-gray4;
font-family: $font-family;
padding: 16px;
.accordion-heading {
span {
color: #303030;
margin-bottom: 8px;
padding: 0;
i::before {
fill: #303030;
}
}
a {
align-items: center;
background-color: #303030;
border-radius: 8px;
border: none;
color: $color-white;
display: flex;
justify-content: center;
padding: 6px 5px 6px 8px;
}
}
.accordion-inner {
padding: 0;
/* General configurations */
.client-notice {
color: $color-black;
}
p {
label {
color: $color-black;
font-weight: 500;
}
select,
input {
border-radius: 0;
border: 1px solid $color-gray4;
box-shadow: none;
}
.help.error {
color: red;
}
}
.box-client-info-pj {
.link a#is-corporate-client,
.link a#not-corporate-client {
color: $color-black;
font-weight: 500;
text-decoration: underline;
}
}
.state-inscription-box span {
font-weight: 500;
}
button.submit {
border: none;
border-radius: 5px;
background: $color-black;
margin-top: 8px;
outline: none;
transition: all 0.2s linear;
&:hover {
background: lighten($color-black, 5);
}
&:active {
background: darken($color-black, 5);
}
}
/* Shipping configurations */
.ship-postalCode small a {
color: #303030;
font-weight: 500;
text-decoration: underline;
}
.vtex-omnishipping-1-x-deliveryGroup {
p {
color: #303030;
font-size: 14px;
font-weight: 500;
}
.shp-lean {
border: 1px solid $color-gray4;
border-radius: 0;
label {
background-color: $color-white;
box-shadow: none;
color: #303030;
padding: 8px 12px;
svg path {
fill: #d8c8ac;
}
}
}
}
.delivery-address-title {
color: #303030;
font-size: 14px;
font-weight: 500;
}
.shp-summary-group-info {
border-color: $color-gray4;
}
.address-summary {
background: none;
border-color: $color-gray4;
border-radius: 0;
color: #303030;
padding: 12px;
@include mq(md, max) {
background-position: 8px 9px;
}
a {
color: #303030;
font-weight: 500;
text-decoration: underline;
}
}
.shp-summary-group-price,
.shp-summary-package {
color: $color-gray4;
}
.shp-summary-group-price {
padding-right: 16px;
}
.shp-summary-package {
padding-left: 16px;
}
.vtex-omnishipping-1-x-summaryChange {
border-color: #303030;
color: #303030;
}
.vtex-omnishipping-1-x-deliveryChannelsToggle {
background-color: #d8c8ac;
border: 1px solid #d8c8ac;
}
.vtex-omnishipping-1-x-deliveryOptionActive {
text-shadow: 1.3px 1px lighten($color-black, 50);
}
}
}
}
}

View File

@ -0,0 +1,812 @@
.container {
@include mq(md, max) {
width: 100%;
}
}
.cart-template {
font-family: $font-family;
@include mq(md, max) {
padding: 0 0;
}
.item-unit-label {
display: none;
}
.cart {
border: 3px solid $color-gray3;
box-sizing: border-box;
border-radius: 5px;
padding: 16px;
@include mq(md, max) {
margin: 0px 0 25px 0;
border-left: none;
border-right: none;
border-radius: 0;
}
}
.cart-fixed.affix {
position: relative !important;
}
.cart-fixed {
font-family: $font-family;
width: 100%;
h2 {
background: $color-white;
border: none;
color: #303030;
font-size: 14px;
font-weight: 500;
}
.item-unavailable {
padding: 0;
&-message {
padding: 8px;
}
}
.cart {
border: 1px solid $color-gray4;
ul li {
border-top: none;
margin-top: 0;
padding-top: 0;
&:not(:first-child) {
margin-top: 8px;
padding-top: 8px;
border-top: 1px solid #e5e5e5;
}
.shipping-date,
.price {
color: #7d7d7d;
}
}
}
.summary-template-holder {
border-top: none;
background: $color-white;
}
#go-to-cart-button a {
color: #303030;
text-decoration: underline;
}
.summary-totalizers {
td.info {
width: 100%;
}
}
#payment-data-submit {
background: $color-black;
border: none;
border-radius: 0;
color: $color-white;
outline: none;
transition: all 0.2s linear;
&:hover {
background: lighten($color-black, 5);
}
&:active {
background: darken($color-black, 5);
}
}
}
.lookatme {
background-color: $color-white;
}
.cart-items {
.product-item {
padding: 16px 0;
}
th {
color: $color-black;
padding: 0 0 16px;
font-style: normal;
font-weight: bold;
font-size: 14px;
line-height: 16px;
@include mq(md, max) {
&.quantity-price,
&.shipping-date {
display: none;
}
}
}
.product-image {
height: auto;
padding: 0;
width: 60px;
@include mq(sm, max) {
width: 72px;
}
img {
height: 60px;
max-width: 100%;
width: auto;
@include mq(sm, max) {
height: 72px;
width: auto;
}
}
}
.product-name {
padding-right: 0;
@include mq(lg, max) {
width: 250px;
}
a {
color: $color-blue;
font-style: normal;
font-weight: normal;
font-size: 12px;
line-height: 14px;
transition: ease-in 0.22s all;
&:hover {
color: darken($color-blue, 10);
text-decoration: none;
}
@media (max-width: 490px) {
margin-left: 23px;
}
}
.brand,
.seller {
display: none !important;
}
}
td.shipping-date {
color: $color-gray2;
font-size: 12px;
line-height: 14px;
@include mq(md, max) {
display: none;
}
}
.product-price {
min-width: 100px;
@include mq(md, max) {
min-width: 78px;
}
@media (max-width: 490px) {
position: absolute;
bottom: 0;
right: 0;
}
span.list-price {
color: $color-gray2;
font-size: 12px;
line-height: 14px;
text-decoration-line: line-through;
@include mq(sm, max) {
font-size: 12px;
line-height: 14px;
}
.old-product-price-label {
text-transform: lowercase;
}
}
}
td.quantity {
align-items: center;
border: 1px solid $color-gray3;
border-radius: 0;
box-sizing: border-box;
display: flex;
justify-content: center;
margin: 6px auto 0;
max-height: 38px;
max-width: 118px;
padding: 0;
width: max-content !important;
@media (max-width: 490px) {
margin-left: 84px !important;
}
input {
background-color: $color-white;
border: 1px solid $color-gray3;
border-radius: 0;
border-width: 0 1px;
display: block;
max-height: 38px;
margin: 0 !important;
padding: 8px 0;
width: 38px;
color: $color-gray2;
box-shadow: none;
@include mq(lg, max) {
width: 24px !important;
}
}
.icon-plus-sign,
.icon-minus-sign {
&::before {
color: $color-black;
display: block;
font-weight: 500;
padding: 1px 12px;
}
}
.icon-minus-sign {
&:before {
content: "-";
font-size: 16px;
}
}
.icon-plus-sign {
&:before {
content: "+";
font-size: 14px;
}
}
.item-quantity-change {
@media (max-width: 979px) and (min-width: 768px) {
position: inherit;
bottom: inherit;
left: inherit;
height: inherit;
width: inherit;
top: inherit;
}
@media (max-width: 490px) {
padding: 0;
}
}
}
.quantity-price,
.best-price {
.icon-question-sign {
display: none;
}
span {
font-style: normal;
font-weight: normal;
font-size: 14px;
line-height: 16px;
color: $color-black;
}
}
.quantity-price {
@include mq(md, max) {
display: none;
}
}
.item-remove {
@media (max-width: 490px) {
top: 0;
}
.icon::before {
color: $color-gray4;
font-size: 15px;
@include mq(md, max) {
font-size: 18px;
}
}
}
.item-unavailable-message {
background-color: #d8c8ac;
color: $color-white;
.icon-warning-sign {
color: #bb4f4f;
}
.top-arrow {
border-bottom-color: #d8c8ac;
}
}
}
.summary {
.cart-more-options {
margin: 0;
width: max-content;
.srp-container {
padding: 0 0 0 10px;
@include mq(md, max) {
padding: 0 16px;
}
.srp-main-title {
margin: 32px 0 12px;
font-style: normal;
font-weight: normal;
font-size: 24px;
line-height: 28px;
color: $color-gray2;
@include mq(md, max) {
margin-top: 0;
}
}
.srp-description {
color: $color-gray2;
font-size: 12px;
line-height: 18px;
margin: 0 0 12px;
}
button.shp-open-options {
background-color: $color-gray5;
border: none;
border-radius: 5px;
color: $color-gray2;
font-size: 16px;
letter-spacing: 0.05em;
line-height: 19px;
font-weight: 500;
outline: none;
padding: 12px 40px;
transition: all 0.2s linear;
&:hover {
background-color: lighten($color-gray5, 5);
}
&:active {
background-color: darken($color-gray5, 5);
}
}
}
.srp-data {
width: 280px;
@include mq(cstm, max) {
width: calc(100vw - 32px);
}
@include mq(md, max) {
margin-bottom: 40px;
}
.srp-pickup-my-location__button {
background-color: $color-black;
border: none;
border-radius: 5px;
color: $color-white;
outline: none;
width: 100%;
font-style: normal;
font-weight: 500;
font-size: 14px;
line-height: 16px;
letter-spacing: 0.05em;
&:hover {
background-color: lighten($color-black, 5);
}
&:active {
background-color: darken($color-black, 5);
}
}
}
.srp-toggle {
margin: 0 0 34px;
&__wrapper {
background-color: $color-white;
border-radius: 100px;
width: 100%;
font-family: $font-family;
font-style: normal;
font-weight: normal;
font-size: 14px;
line-height: 16px;
text-transform: uppercase;
}
&__current {
border: 1px solid $color-blue;
border-radius: 100px;
}
.blue {
color: $color-blue;
}
label {
width: 50%;
&:active {
background-color: #f0f0f0;
}
}
}
.srp-postal-code {
.ship-postalCode {
label {
font-family: $font-family;
font-style: normal;
font-weight: normal;
font-size: 12px;
line-height: 14px;
color: $color-black;
margin-bottom: 12px;
}
input {
border: 1px solid $color-gray3;
border-radius: 5px;
box-shadow: none;
color: $color-gray3;
font-size: 12px;
height: 36px;
padding: 12px 8px;
width: 172px;
}
& ~ button {
background-color: $color-black;
border: none;
border-radius: 5px;
color: $color-white;
font-size: 12px;
height: 36px;
letter-spacing: 1px;
outline: none;
position: absolute;
right: -150px;
top: 36px;
transition: all 0.2s linear;
width: 96px;
text-transform: uppercase;
&:hover {
background-color: lighten($color-black, 5);
}
&:active {
background-color: darken($color-black, 5);
}
}
small a {
font-family: $font-family;
font-style: normal;
font-weight: normal;
font-size: 10px;
line-height: 12px;
color: $color-blue;
margin-top: 7px;
}
span.help.error {
color: red;
font-size: 12px;
position: absolute;
left: 0;
width: 100%;
top: 17px;
}
}
}
.srp-result {
strong,
.srp-items {
color: #303030;
font-weight: 400;
font-size: 14px;
}
#deliver-at-text a {
color: #303030;
font-size: 16px;
font-weight: 500;
&:hover {
text-decoration: underline;
}
}
.srp-shipping-current-single {
border: 1px solid $color-gray4;
border-radius: 0;
color: #303030;
margin: 16px 0 0;
padding: 4px 12px;
svg path {
fill: #d8c8ac;
}
}
.srp-delivery-select {
border: 1px solid $color-gray4;
}
.srp-delivery-select-container {
border: 1px solid $color-gray4;
border-radius: 0;
.srp-shipping-current-many {
&__name {
color: #303030;
}
&__sla {
color: #7d7d7d;
}
&__price {
color: #7d7d7d;
font-weight: 500;
}
&__arrow svg {
fill: $color-gray4;
}
}
}
}
}
&-totalizers {
padding: 0;
width: 346px;
.coupon-data {
#cart-link-coupon-add {
text-decoration: none;
&:hover {
text-decoration: underline;
cursor: pointer;
}
}
span {
font-family: $font-family;
font-style: normal;
font-weight: normal;
font-size: 12px;
line-height: 14px;
color: $color-blue;
text-decoration: none;
}
}
@include mq(md, max) {
padding: 0 16px;
width: 100%;
}
.coupon-column {
.coupon {
margin: 0;
}
.link-coupon-add {
color: #303030;
font-size: 12px;
text-decoration: underline;
}
.coupon-label label {
margin-bottom: 12px;
font-family: $font-family;
font-style: normal;
font-weight: normal;
font-size: 12px;
line-height: 14px;
color: $color-gray2;
cursor: none;
}
.coupon-fields {
margin-bottom: 32px;
@include mq(sm, max) {
span {
display: flex;
flex-direction: row;
justify-content: space-between;
i {
position: absolute;
right: 91px;
opacity: 1;
}
}
}
input {
border: 2px solid $color-gray3;
border-radius: 5px;
box-shadow: none;
color: $color-gray4;
font-size: 12px;
height: 34px;
padding: 0 12px;
max-width: 160px;
@include mq(sm, max) {
max-width: 100%;
width: 100%;
}
}
button {
background: $color-black;
border: none;
border-radius: 5px;
color: $color-white;
font-size: 12px;
height: 36px;
letter-spacing: 1px;
margin-left: 6px;
outline: none;
transition: all 0.2s linear;
width: 94px;
text-transform: uppercase;
@include mq(md, max) {
width: 138px;
}
&:hover {
background-color: lighten($color-black, 5);
}
&:active {
background-color: darken($color-black, 5);
}
}
}
}
.accordion-group {
tr {
border-color: #e5e5e5;
td {
&.empty {
display: none;
}
&.info,
&.monetary {
font-style: normal;
font-weight: normal;
font-size: 14px;
line-height: 16px;
color: $color-black;
padding: 12px 0;
}
&.info {
text-align: left;
}
&.monetary {
text-align: right;
}
}
}
tfoot {
td.info,
td.monetary {
font-style: normal;
font-weight: normal;
font-size: 18px;
line-height: 21px;
color: $color-black;
}
}
}
}
}
.cart-links-bottom {
display: flex;
flex-direction: column;
width: 343px;
@include mq(md, max) {
padding: 0 16px;
width: calc(100% - 32px);
float: none;
margin-bottom: 50px;
}
@include mq(md, min) {
margin: 0;
padding-bottom: 50px;
}
.link-choose-more-products-wrapper {
display: block;
text-align: center;
margin-bottom: 16px;
@include mq(md, max) {
margin-bottom: 0px;
}
a {
font-family: $font-family;
font-style: normal;
font-weight: normal;
font-size: 12px;
line-height: 14px;
color: $color-blue;
}
}
.btn-place-order-wrapper {
a {
background: $color-green;
border: none;
border-radius: 5px;
display: block;
font-size: 0;
transition: ease-in 0.22s all;
padding: 12px 19px;
&:hover {
background-color: darken($color-green, 5);
}
&:after {
content: "finalizar compra";
font-family: $font-family;
font-weight: 500;
font-size: 13px;
letter-spacing: 0.05em;
color: $color-white;
text-transform: uppercase;
vertical-align: middle;
line-height: 19px;
text-shadow: none;
}
}
}
}
}

View File

@ -0,0 +1,11 @@
body .container-main.container-order-form .orderform-template.active {
.mini-cart {
width: 32.3242%;
margin-left: unset;
margin-right: 0;
float: right;
}
.orderform-template-holder {
width: 66.1132%;
}
}

View File

@ -0,0 +1,38 @@
.empty-cart {
font-family: $font-family;
&-content {
color: $color-black;
text-align: center;
@include mq(md, max) {
padding: 0 16px;
}
}
&-title {
font-size: 20px;
}
&-links {
.link-choose-products {
background: $color-black;
border: none;
border-radius: 5px;
transition: ease-in 0.22s all;
outline: none;
font-family: $font-family;
font-style: normal;
font-weight: 500;
font-size: 14px;
line-height: 16px;
text-align: center;
letter-spacing: 0.05em;
color: $color-white;
text-transform: uppercase;
&:hover {
background: lighten($color-black, 5);
}
}
}
}

View File

@ -0,0 +1,125 @@
@import "./checkout-vazio";
@import "./checkout-carrinho";
@import "./checkout-pagamento";
@import "./checkout-autenticacao";
html {
height: 100%;
min-height: 100%;
}
footer {
width: 94.9734%;
margin: auto auto 0 auto;
}
header {
width: 79.53125%;
margin: 0 auto;
}
body {
display: flex;
flex-direction: column;
min-height: 100% !important;
padding-top: 0 !important;
@include mq(md, max) {
padding-left: 0;
}
&.body-cart {
font-family: $font-family;
}
&.body-cart,
&.body-order-form {
@include mq(xl, min) {
padding-top: 0;
}
@include mq(lg, max) {
padding-bottom: 0 !important;
}
@include mq(md, max) {
padding-right: 0;
padding-left: 0;
}
}
.container-order-form,
.container-cart {
width: 80%;
}
}
.btn-success {
background: $color-black;
text-shadow: none;
&:hover {
background: lighten($color-black, 15%);
}
}
.emailInfo h3 {
color: $color-black !important;
}
#cart-title,
#orderform-title {
color: $color-gray2;
font-family: $font-family;
font-weight: 500;
font-size: 36px;
line-height: 42px;
margin: 40px 0 30px;
letter-spacing: 0.1em;
text-transform: uppercase;
@include mq(md, max) {
margin-left: 30px;
}
}
.dropdown {
&__content {
&--closed {
display: none;
}
}
&__title {
cursor: pointer;
user-select: none;
&::before,
&::after {
content: "";
background: $color-gray2;
display: block;
float: right;
height: 2px;
width: 8px;
margin-top: 8px;
}
&::before {
transform: rotate(0deg);
transition: 0.3s;
}
&::after {
transform: rotate(90deg);
transition: 0.3s;
margin-right: -8px;
}
&.closed::before {
transform: rotate(180deg);
}
&.closed::after {
transform: rotate(0);
}
}
}

View File

@ -0,0 +1 @@
/* _breadcrumb.scss */

View File

@ -0,0 +1 @@
/* _flags.scss */

View File

@ -0,0 +1,74 @@
/* _footer.scss */
.footerCheckout {
border-top: none;
color: $color-gray2;
&__wrapper {
align-items: center;
display: flex;
justify-content: space-between;
}
&__address {
color: $color-gray2;
font-family: $font-family;
font-style: normal;
font-weight: normal;
font-size: 10px;
line-height: 12px;
text-transform: capitalize;
max-width: 40%;
@include mq(md, max) {
margin-bottom: 24px;
max-width: 100%;
}
}
&__stamps {
align-items: center;
display: flex;
justify-self: center;
list-style: none;
@include mq(md, max) {
align-self: center;
margin-bottom: 12px;
}
&__divider {
background-color: $color-gray4;
display: inline-block;
height: 24px;
margin: 0 8px;
width: 1px;
}
}
&__developedBy {
align-items: center;
display: flex;
list-style-type: none;
margin: 0;
li:last-child {
margin-left: 16px;
}
a {
align-items: center;
color: $color-gray2;
display: flex;
font-family: $font-family;
font-style: normal;
font-weight: normal;
font-size: 10px;
line-height: 12px;
text-decoration: none;
span {
margin-right: 8px;
}
}
}
}

View File

@ -0,0 +1,36 @@
/* _header.scss */
.headerCheckout {
.container {
width: auto !important;
}
&__wrapper {
align-items: center;
display: flex;
justify-content: space-between;
}
&__logo {
img {
height: 52px;
width: auto;
}
}
&__safeBuy {
span {
align-items: center;
display: flex;
text-transform: uppercase;
font-family: $font-family;
font-style: normal;
font-weight: normal;
font-size: 12px;
line-height: 14px;
color: $color-gray;
}
i {
margin-right: 8px;
}
}
}

View File

@ -0,0 +1 @@
/* _mais-categorias.scss */

View File

@ -0,0 +1 @@
/* _menu.scss */

View File

@ -0,0 +1 @@
/* _prateleira.scss */

View File

@ -0,0 +1,57 @@
@keyframes notificacao{
0% {
transform:rotate(0deg);
}
50% {
transform:rotate(3deg) translateX(-3px);
}
100% {
transform:rotate(-3deg) translateX(3px);
}
}
@keyframes addcart{
0% {
margin-left:0px;
}
50% {
margin-left:-2px;
}
100% {
margin-left:2px;
}
}
@keyframes spin {
from { transform:rotate(0deg); }
to { transform:rotate(360deg); }
}
@keyframes fadeIn {
from { opacity:0; }
to { opacity:1; }
}
@keyframes sk-scaleout {
0% { transform: scale(0) }
100% {
transform: scale(1.0);
opacity: 0;
}
}
@keyframes cascadeInSimple {
0% {
opacity:0;
transform: translateX(-100%)
}
100% {
opacity:1;
transform: translateX(0)
}
}

View File

@ -0,0 +1,222 @@
/**
* @reference (https://github.com/engageinteractive/core/blob/master/src/scss/utility/_mixins.scss)
*/
@mixin push--auto {
margin: {
left: auto;
right: auto;
}
}
@mixin pseudo($display: block, $pos: absolute, $content: ''){
content: $content;
display: $display;
position: $pos;
}
@mixin position($top: false,$right: false, $bottom:false, $left: false){
@if( $top ){
top:$top;
}
@if( $right ){
right:$right;
}
@if( $left ){
left:$left;
}
@if( $bottom ){
bottom:$bottom;
}
}
@mixin responsive-ratio($x,$y, $pseudo: false) {
$padding: unquote( ( $y / $x ) * 100 + '%' );
@if $pseudo {
&:before {
@include pseudo($pos: relative);
width: 100%;
padding-top: $padding;
}
} @else {
padding-top: $padding;
}
}
@mixin css-triangle($color, $direction, $size: 6px, $position: absolute, $round: false){
@include pseudo($pos: $position);
width: 0;
height: 0;
@if $round {
border-radius: 3px;
}
@if $direction == down {
border-left: $size solid transparent;
border-right: $size solid transparent;
border-top: $size solid $color;
margin-top: 0 - round( $size / 2.5 );
} @else if $direction == up {
border-left: $size solid transparent;
border-right: $size solid transparent;
border-bottom: $size solid $color;
margin-bottom: 0 - round( $size / 2.5 );
} @else if $direction == right {
border-top: $size solid transparent;
border-bottom: $size solid transparent;
border-left: $size solid $color;
margin-right: -$size;
} @else if $direction == left {
border-top: $size solid transparent;
border-bottom: $size solid transparent;
border-right: $size solid $color;
margin-left: -$size;
}
}
@mixin input-placeholder {
&.placeholder { @content; }
&:-moz-placeholder { @content; }
&::-moz-placeholder { @content; }
&:-ms-input-placeholder { @content; }
&::-webkit-input-placeholder { @content; }
}
@mixin hardware($backface: true, $perspective: 1000) {
@if $backface {
backface-visibility: hidden;
}
perspective: $perspective;
}
@mixin truncate($truncation-boundary) {
max-width: $truncation-boundary;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
@mixin appearance($val: none) {
-webkit-appearance: $val;
-moz-appearance: $val;
appearance: $val;
}
@mixin separador($cor,$p-right: 5px) {
position: relative;
padding-right: $p-right;
display: inline-block;
&:after{
content:' ';
display: block;
width: 1px;
height: 100%;
position: absolute;
top: 50%;
right: 0;
transform: translateY(-50%);
background-color: $cor;
}
&:last-child:after{
display: none;
}
}
@mixin mq($width, $type: min) {
@if map_has_key($grid-breakpoints, $width) {
$width: map_get($grid-breakpoints, $width);
@if $type == max {
$width: $width - 1px;
}
@media only screen and (#{$type}-width: $width) {
@content;
}
}
}
@mixin mq_range($min, $max) {
@if (map_has_key($grid-breakpoints, $min) and map_has_key($grid-breakpoints, $max)) {
$width_max: map_get($grid-breakpoints, $max);
$width_min: map_get($grid-breakpoints, $min);
$width_max: $width_max - 1px;
@media only screen and (min-width: $width_min) and (max-width:$width_max) {
@content;
}
}
}
@mixin z-index($nome:'',$soma:0){
@if map_has_key($z-index, $nome) {
z-index: (map_get($z-index,$nome )+$soma) ;
}
}
@mixin scrollbar($width:8px,$bg-color:#eee, $trak-color:#aaa,$trak-color-hover:#999,$border-radius:0 ){
&::-webkit-scrollbar {
width: $width;
}
&::-webkit-scrollbar-track {
background-color: $bg-color;
border-radius: $border-radius;
}
&::-webkit-scrollbar-thumb {
background-color: $trak-color;
border-radius: $border-radius;
&:hover {
background: $trak-color-hover;
}
}
}
@function map-get-next($map, $key, $fallback: false, $return: value) {
// Check if map is valid
@if type-of($map) == map {
// Check if key exists in map
@if map-has-key($map, $key) {
// Init index counter variable
$i: 0;
// Init key index
$key-index: false;
// Traverse map for key
@each $map-key, $map-value in $map {
// Update index
$i: $i + 1;
// If map key found, set key index
@if $map-key == $key {
$key-index: $i;
}
// If next index return next value or key based on $return
@if $i == $key-index + 1 {
@if $return == key {
@return $map-key;
} @else {
@return $map-value;
}
}
// If last entry return false
@if $i == length($map) {
@return $fallback;
}
}
@warn 'No next map item for key #{$key}';
@return $fallback;
}
@warn 'No valid key #{$key} in map';
@return $fallback;
}
@warn 'No valid map';
@return $fallback;
}

View File

@ -0,0 +1,91 @@
// Mixins de definição
@mixin visibility($parent, $display:block) {
@if $display==none {
$display: block;
}
#{$parent} {
display: $display !important;
}
}
@mixin visibility-table($parent) {
table#{$parent} {
display: table !important;
}
tr#{$parent} {
display: table-row !important;
}
th#{$parent},
td#{$parent} {
display: table-cell !important;
}
}
// [converter] $parent hack
@mixin invisibility($parent) {
#{$parent} {
display: none !important;
}
}
@each $slug,$width in $grid-breakpoints {
$class: unquote('.visible-'+$slug);
$classOnly: unquote('.visible-only-'+$slug);
@include invisibility($class);
@include invisibility($classOnly);
}
@each $slug,$width in $grid-breakpoints {
$class: unquote('.visible-'+$slug);
$value: map-get-next($grid-breakpoints,$slug);
$media: '(max-width: '+ (($value)-1) +')';
@if($value == false){
$media: '(min-width: '+ $width +')';
}
@media only screen and #{$media} {
@include visibility($class);
@include visibility($class+'-inline-block',inline-block);
@include visibility($class+'-inline',inline);
@include visibility-table($class);
}
}
@each $slug,$width in $grid-breakpoints {
$class: unquote('.visible-only-'+$slug);
$value: map-get-next($grid-breakpoints,$slug);
$media: '(min-width: '+ $width +') and (max-width: '+ $value +')';
@if($value == false){
$media: '(min-width: '+ (($width)+1) +')';
}
@media only screen and #{$media} {
@include visibility($class);
@include visibility($class+'-inline-block',inline-block);
@include visibility($class+'-inline',inline);
@include visibility-table($class);
}
}
@each $slug,$width in $grid-breakpoints {
$class: unquote('.invisible-'+$slug);
$value: map-get-next($grid-breakpoints,$slug);
$media: '(max-width: '+ (($value)-1) +')';
@if($value == false){
$media: '(min-width: '+ $width +')';
}
@media only screen and #{$media} {
@include invisibility($class);
}
}
@each $slug,$width in $grid-breakpoints {
$class: unquote('.invisible-only-'+$slug);
$value: map-get-next($grid-breakpoints,$slug);
$media: '(min-width: '+ $width +') and (max-width: '+ $value +')';
@if($value == false){
$media: '(min-width: '+$width +')';
}
@media only screen and #{$media} {
@include invisibility($class);
}
}

View File

@ -0,0 +1,38 @@
/* fonts */
@import url("https://fonts.googleapis.com/css2?family=Tenor+Sans&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;500;600;700;800&display=swap");
$font-family: "Open Sans", sans-serif;
$font-family-secundary:"Tenor Sans", sans-serif;
/* Colors */
$color-black: #292929;
$color-white: #fff;
$color-gray: #6c6c6c;
$color-gray2: #7d7d7d;
$color-gray3: #f0f0f0;
$color-gray4: #8d8d8d;
$color-gray5: #e5e5e5;
$color-blue: #4267b2;
$color-green: #4caf50;
/* Grid breakpoints */
$grid-breakpoints: (
xs: 0,
cstm: 400,
sm: 576px,
md: 768px,
lg: 992px,
xl: 1200px
) !default;
$z-index: (
level1: 5,
level2: 10,
level3: 15,
level4: 20,
level5: 25
) !default;

View File

@ -0,0 +1,5 @@
@import "variaveis";
@import "mixin";
@import "utils";
@import "animacao";

View File

@ -0,0 +1,49 @@
.sprite{
display: inline-block;
vertical-align: middle;
}
.no-buttom {
border: none;
margin: 0;
padding: 0;
width: auto;
overflow: visible;
background: transparent;
outline: none;
text-align: inherit;
/* inherit font & color from ancestor */
color: inherit;
font: inherit;
/* Normalize `line-height`. Cannot be changed from `normal` in Firefox 4+. */
line-height: normal;
/* Corrects font smoothing for webkit */
-webkit-font-smoothing: inherit;
-moz-osx-font-smoothing: inherit;
/* Corrects inability to style clickable `input` types in iOS */
appearance: none;
&::-moz-focus-inner {
border: 0;
padding: 0;
}
}
.itens-inline{
>*{ display: inline-block;}
}
%notificacao{
padding: 7.5px 10px ;
min-height: 1em;
border-radius: 3px;
border-right: solid 5px;
display: block;
}

View File

@ -0,0 +1,37 @@
<!-- Esse arquivo é só um demonstrativo de como está o html do footer do checkout atualmente,
MODIFICA-LO NÃO CAUSARÁ EFEITO ALGUM, todo html que for modificado no footer, deverá ser feito através de javaScript. -->
<footer class="footerCheckout">
<div class="footerCheckout__wrapper">
<div class="footerCheckout__address">
<span>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</span>
</div>
<ul class="footerCheckout__stamps">
<li>
<span class="footerCheckout__payments">Aqui: creditcard icons</span>
</li>
<li>
<span class="footerCheckout__stamps__divider"></span>
</li>
<li>
<span class="footerCheckout__payments">Aqui: vtex pci icon</span>
</li>
</ul>
<ul class="footerCheckout__developedBy">
<li>
<a href="https://vtex.com/br-pt/">
<span>Powered By</span>
@TODO: vtex icon
</a>
</li>
<li>
<a href="https://agenciam3.com/">
<span>Developed By</span>
@TODO: m3 icon
</a>
</li>
</ul>
</div>
</footer>

View File

@ -0,0 +1,20 @@
<!-- Esse arquivo é só um demonstrativo de como está o html do header do checkout atualmente,
MODIFICA-LO NÃO CAUSARÁ EFEITO ALGUM, todo html que for modificado no header, deverá ser feito através de javaScript. -->
<header class="headerCheckout">
<div class="container">
<div class="headerCheckout__wrapper">
<div class="headerCheckout__logo">
<a href="/">
<img src="https://agenciamagma.vteximg.com.br/arquivos/LogoM3Academy.png" alt="M3 Academy"/>
</a>
</div>
<div id="progressBar" class="progress-bar"> Aqui entra a barra de progresso
</div>
<div class="headerCheckout__safeBuy">
<img src="https://agenciamagma.vteximg.com.br/arquivos/cadeadoCompraSegM3Academy.png" alt="Cadeado"/>
<span>Compra segura</span>
</div>
</div>
</div>
</header>

View File

@ -0,0 +1,31 @@
const webpack = require("webpack");
const path = require("path");
// var shopName = require("../package.json").name;
/**
* Configuração do webpack
*/
module.exports = {
entry: {
checkout: "./src/arquivos/js/checkout.js",
},
output: {
path: path.resolve(__dirname, "./dist/arquivos"),
filename: "[name]-bundle.js",
// filename: shopName + "--[name]-bundle.js",
},
resolve: {
alias: {
Helpers: path.resolve(__dirname, "..", "src/arquivos/js/helpers"),
Lib: path.resolve(__dirname, "..", "src/arquivos/js/lib"),
Config: path.resolve(__dirname, "..", "src/arquivos/js/config"),
App: path.resolve(__dirname, "..", "src/arquivos/js/app"),
},
},
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
}),
],
};

30
checkout/webpack.dev.js Normal file
View File

@ -0,0 +1,30 @@
const webpack = require("webpack");
const { merge } = require("webpack-merge");
const common = require("./webpack.common.js");
const path = require("path");
module.exports = merge(common, {
devtool: "inline-source-map",
mode: "development",
externals: {
vtexjs: "vtexjs",
jquery: "jQuery",
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /(node_modules|bower_components)/,
include: path.resolve(__dirname, "..", "src/arquivos/js"),
use: {
loader: "babel-loader",
options: {
presets: [["@babel/preset-env"], "@babel/react"],
plugins: ["@babel/plugin-transform-async-to-generator"],
cacheDirectory: true,
},
},
},
],
},
});

47
checkout/webpack.prod.js Normal file
View File

@ -0,0 +1,47 @@
const { merge } = require("webpack-merge");
const common = require("./webpack.common.js");
const TerserPlugin = require("terser-webpack-plugin");
module.exports = merge(common, {
externals: {
jquery: "jQuery",
vtexjs: "vtexjs",
},
mode: "production",
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules\/(?!(@agenciam3\/pkg)\/).*/,
use: {
loader: "babel-loader",
options: {
presets: [["@babel/preset-env"], "@babel/react"],
plugins: ["@babel/plugin-transform-async-to-generator"],
cacheDirectory: true,
},
},
},
],
},
optimization: {
usedExports: true,
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: true,
terserOptions: {
keep_classnames: true,
keep_fnames: true,
compress: {
pure_funcs: [
"console.table",
"console.debug",
"console.log",
],
},
},
}),
],
},
});

4
commitlint.config.js Normal file
View File

@ -0,0 +1,4 @@
module.exports = {
extends: ["@commitlint/config-conventional"],
ignores: [(message) => message.includes("Release")],
};

30667
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

39
package.json Normal file
View File

@ -0,0 +1,39 @@
{
"name": "m3-template",
"version": "1.0.0",
"main": "index.js",
"private": true,
"license": "UNLICENSED",
"scripts": {
"prepare": "husky install",
"vlink:custom": "cd custom && vtex link",
"vlink:storefront": "cd storefront && vtex link",
"vlink:storefront:build": "cd storefront && yarn dev",
"vfix:custom": "cd custom && vtex unlink && vtex link",
"vfix:storefront": "cd storefront && vtex unlink && vtex link",
"vlink": "concurrently \"yarn vlink:custom\" \"yarn vlink:storefront\" \"yarn vlink:storefront:build\"",
"vfix": "concurrently \"yarn vfix:custom\" \"yarn vfix:storefront\" \"yarn vlink:storefront:build\"",
"checkout": "yarn workspace checkout dev",
"checkout:prod": "yarn workspace checkout prod",
"lint:storefront": "yarn workspace storefront lint",
"lint:checkout": "yarn workspace checkout lint",
"lint:custom": "yarn workspace custom lint",
"lint": "yarn lint:custom && yarn lint:checkout && lint:storefront",
"postinstall": "cd custom && yarn install:all"
},
"workspaces": [
"custom",
"storefront",
"checkout"
],
"devDependencies": {
"concurrently": "^6.0.0",
"husky": "^5.2.0",
"lerna": "^4.0.0",
"lint-staged": "^10.5.4"
},
"dependencies": {
"@commitlint/cli": "^12.0.1",
"@commitlint/config-conventional": "^12.0.1"
}
}