From fa0a1ecf9eb38cac243609093c433c766229ea3a Mon Sep 17 00:00:00 2001 From: aldemirLucas Date: Wed, 11 Sep 2024 00:31:04 -0300 Subject: [PATCH 01/14] feat: wip functional system in progress --- next/components/organisms/PaymentSystem.js | 20 +- next/pages/precos.js | 8 +- next/pages/user/[username].js | 206 ++++++++++++++++++--- next/styles/paymentSystem.module.css | 8 - 4 files changed, 195 insertions(+), 47 deletions(-) diff --git a/next/components/organisms/PaymentSystem.js b/next/components/organisms/PaymentSystem.js index 64f6bc98c..77557bfdd 100644 --- a/next/components/organisms/PaymentSystem.js +++ b/next/components/organisms/PaymentSystem.js @@ -53,6 +53,7 @@ const PaymentForm = ({ onSucess, onErro, clientSecret}) => { return (
{
@@ -94,7 +94,7 @@ export default function PaymentSystem({ userData, plan, onSucess, onErro }) { fontFamily: "Ubuntu", borderRadius: "14px", colorPrimary: "#42B0FF", - colorTextPlaceholder: "#A3A3A3", + colorTextPlaceholder: "#464A51", colorDanger: "#D93B3B", colorBackground: "#FFF", colorText: "#252A32", @@ -136,7 +136,7 @@ export default function PaymentSystem({ userData, plan, onSucess, onErro }) { } if(!clientSecret) return ( - + diff --git a/next/pages/precos.js b/next/pages/precos.js index 8a89bc4c0..c1faa96b0 100644 --- a/next/pages/precos.js +++ b/next/pages/precos.js @@ -85,7 +85,7 @@ export const CardPrice = ({ Leia os { + {/* stripe */} - - - Assinatura {plan.title} - + + + Pagamento + { - openModalSucess()} - onErro={() => openModalErro()} - /> + + + + + BD Pro + + Trocar plano + + + + + Desconto anual + Economize 20% + + + + + + Cupom de desconto + + + + + + Aplicar + + + + + Período de teste - 7 dias grátis + + + + + Detalhes do pagamento + + openModalSucess()} + onErro={() => openModalErro()} + /> + + {/* success */} setIsLoading(true)} @@ -1833,6 +1984,7 @@ const PlansAndPayment = ({ userData }) => { + {/* err */} { + {/* modal plans */} { @@ -1928,19 +2081,20 @@ const PlansAndPayment = ({ userData }) => { minWidth: "fit-content", maxHeight: "fit-content", margin: isMobileMod() ? "0" : "24px", + padding: "32px 22px 26px 22px", borderRadius: isMobileMod() ? "0" : "20px", }} isCentered={isMobileMod() ? false : true} > - + Compare os planos @@ -2003,10 +2157,10 @@ const PlansAndPayment = ({ userData }) => { gridTemplateColumns="repeat(3, 320px)" gridTemplateRows="1fr" alignItems={isMobileMod() ? "center" : {base: "center", lg: "inherit"}} - padding="0 20px 10px" + padding="0 10px 6px" justifyContent="center" justifyItems="center" - gap="20px" + gap="24px" spacing={0} > { + {/* err plans */} { + {/* cancel */} Date: Thu, 12 Sep 2024 17:21:29 -0300 Subject: [PATCH 02/14] feat: ajust visual and new logic from stripe modal --- next/components/organisms/PaymentSystem.js | 11 +- next/pages/api/stripe/createSubscription.js | 33 ++++-- next/pages/precos.js | 4 +- next/pages/user/[username].js | 119 +++++++++++++++++--- next/pages/user/login.js | 2 +- 5 files changed, 138 insertions(+), 31 deletions(-) diff --git a/next/components/organisms/PaymentSystem.js b/next/components/organisms/PaymentSystem.js index 77557bfdd..605166555 100644 --- a/next/components/organisms/PaymentSystem.js +++ b/next/components/organisms/PaymentSystem.js @@ -83,7 +83,7 @@ const PaymentForm = ({ onSucess, onErro, clientSecret}) => { ) } -export default function PaymentSystem({ userData, plan, onSucess, onErro }) { +export default function PaymentSystem({ userData, plan, coupon, onSucess, onErro }) { const [clientSecret, setClientSecret] = useState("") const appearance = { @@ -115,8 +115,8 @@ export default function PaymentSystem({ userData, plan, onSucess, onErro }) { fonts: [{ cssSrc: 'https://fonts.googleapis.com/css2?family=Ubuntu:wght@400;700&display=swap' }], } - const customerCreatPost = async (id) => { - const clientSecret = await fetch(`/api/stripe/createSubscription?p=${btoa(id)}`, {method: "GET"}) + const customerCreatPost = async (id, coupon) => { + const clientSecret = await fetch(`/api/stripe/createSubscription?p=${btoa(id)}&c=${btoa(coupon)}`, {method: "GET"}) .then(res => res.json()) if (clientSecret) { @@ -125,8 +125,9 @@ export default function PaymentSystem({ userData, plan, onSucess, onErro }) { } useEffect(() => { - customerCreatPost(plan.id) - }, []) + setClientSecret("") + customerCreatPost(plan, coupon) + }, [plan, coupon]) const SkeletonBox = ({ type, ...props }) => { if(type === "text") return diff --git a/next/pages/api/stripe/createSubscription.js b/next/pages/api/stripe/createSubscription.js index 814e1d072..ac4d4f444 100644 --- a/next/pages/api/stripe/createSubscription.js +++ b/next/pages/api/stripe/createSubscription.js @@ -2,7 +2,24 @@ import axios from "axios"; const API_URL= `${process.env.NEXT_PUBLIC_API_URL}/api/v1/graphql` -async function createSubscription(id, token) { +async function createSubscription({id, coupon, token}) { + const query = coupon !== "" ? + ` + mutation { + createStripeSubscription (priceId: ${id}, coupon: "${coupon}") { + clientSecret + } + } + ` + : + ` + mutation { + createStripeSubscription (priceId: ${id}) { + clientSecret + } + } + ` + try { const res = await axios({ url: API_URL, @@ -11,13 +28,7 @@ async function createSubscription(id, token) { Authorization: `Bearer ${token}` }, data: { - query: ` - mutation { - createStripeSubscription (priceId: ${id}) { - clientSecret - } - } - ` + query: query } }) const data = res.data @@ -30,7 +41,11 @@ async function createSubscription(id, token) { export default async function handler(req, res) { const token = req.cookies.token - const result = await createSubscription(atob(req.query.p), token) + const result = await createSubscription({ + id: atob(req.query.p), + coupon: atob(req.query.c), + token: token + }) if(result.errors) return res.status(500).json({error: result.errors}) if(result === "err") return res.status(500).json({error: "err"}) diff --git a/next/pages/precos.js b/next/pages/precos.js index c1faa96b0..3e4b0fc76 100644 --- a/next/pages/precos.js +++ b/next/pages/precos.js @@ -436,7 +436,7 @@ export function SectionPrice() { ]} button={{ text: isBDPro.isCurrentPlan && planIntervalPlan() ? "Plano atual" : hasSubscribed ? "Assinar" : "Iniciar teste grátis", - href: username === null ? `/user/login?q=pro&i=${plans?.[`bd_pro_${toggleAnual ? "year" : "month"}`]._id}` :`/user/${username}?plans_and_payment&q=pro&i=${plans?.[`bd_pro_${toggleAnual ? "year" : "month"}`]._id}`, + href: username === null ? `/user/login?i=${plans?.[`bd_pro_${toggleAnual ? "year" : "month"}`]._id}` :`/user/${username}?plans_and_payment&i=${plans?.[`bd_pro_${toggleAnual ? "year" : "month"}`]._id}`, isCurrentPlan: isBDPro.isCurrentPlan && planIntervalPlan(), }} /> @@ -453,7 +453,7 @@ export function SectionPrice() { ]} button={{ text: isBDEmp.isCurrentPlan && planIntervalPlan() ? "Plano atual" : hasSubscribed ? "Assinar" : "Iniciar teste grátis", - href: username === null ? `/user/login?q=empresas&i=${plans?.[`bd_empresas_${toggleAnual ? "year" : "month"}`]._id}` :`/user/${username}?plans_and_payment&q=empresas&i=${plans?.[`bd_empresas_${toggleAnual ? "year" : "month"}`]._id}`, + href: username === null ? `/user/login?i=${plans?.[`bd_empresas_${toggleAnual ? "year" : "month"}`]._id}` :`/user/${username}?plans_and_payment&i=${plans?.[`bd_empresas_${toggleAnual ? "year" : "month"}`]._id}`, isCurrentPlan: isBDEmp.isCurrentPlan && planIntervalPlan(), }} /> diff --git a/next/pages/user/[username].js b/next/pages/user/[username].js index 215318e8a..10cf114e9 100644 --- a/next/pages/user/[username].js +++ b/next/pages/user/[username].js @@ -1441,7 +1441,11 @@ const PlansAndPayment = ({ userData }) => { const router = useRouter() const { query } = router - const [plan, setPlan] = useState({}) + const [plan, setPlan] = useState("") + const [checkoutInfos, setCheckoutInfos] = useState({}) + const [valueCoupon, setValueCoupon] = useState("") + const [couponInputFocus, setCouponInputFocus] = useState(false) + const [coupon, setCoupon] = useState("") const PaymentModal = useDisclosure() const SucessPaymentModal = useDisclosure() const ErroPaymentModal = useDisclosure() @@ -1472,8 +1476,6 @@ const PlansAndPayment = ({ userData }) => { }, [userData?.id]) useEffect(() => { - if(PlansModal.isOpen === false) return - async function fecthPlans() { try { const result = await fetch(`/api/stripe/getPlans`, { method: "GET" }) @@ -1505,12 +1507,20 @@ const PlansAndPayment = ({ userData }) => { } fecthPlans() - }, [PlansModal.isOpen]) + }, []) + + useEffect(() => { + if(plans === null) return + if(plan === "") return + + const value = Object.values(plans).find(elm => elm._id === plan) + setCheckoutInfos(value) + }, [plan, plans]) useEffect(() => { if(query.i) { if(subscriptionInfo?.isActive === true) return AlertChangePlanModal.onOpen() - setPlan({id: query.i}) + setPlan(query.i) PaymentModal.onOpen() } }, [query]) @@ -1690,9 +1700,22 @@ const PlansAndPayment = ({ userData }) => { return formattedDate } - function formattedPlanInterval (value) { - if(value === "month") return "(Mensal)" - if(value === "year") return "(Anual)" + function formattedPlanInterval (value, variant = false) { + if(variant) { + if(value === "month") return "mês" + if(value === "year") return "ano" + } else { + if(value === "month") return "(Mensal)" + if(value === "year") return "(Anual)" + } + } + + function changeIntervalPlanCheckout() { + let togglerValue = !toggleAnual ? "year" : "month" + const value = Object.values(plans).find(elm => elm.interval === togglerValue && elm.productSlug === checkoutInfos?.productSlug) + setCheckoutInfos(value) + setPlan(value._id) + setToggleAnual(!toggleAnual) } useEffect(() => { @@ -1708,7 +1731,10 @@ const PlansAndPayment = ({ userData }) => { { + setToggleAnual(true) + PaymentModal.onClose() + }} propsModalContent={{ width: "100%", maxWidth:"1008px", @@ -1763,7 +1789,7 @@ const PlansAndPayment = ({ userData }) => { lineHeight="24px" color="#252A32" > - BD Pro + {checkoutInfos?.productName} { color="#0068C5" _hover={{color: "#0057A4"}} marginLeft="auto" - >Trocar plano + onClick={() => { + PaymentModal.onClose() + PlansModal.onOpen() + }} + >Alterar plano { gap="8px" alignItems="center" > - + {toggleAnual ? + changeIntervalPlanCheckout()} + /> + : + changeIntervalPlanCheckout()} + /> + } { gap="8px" > { fontWeight="500" fontSize="14px" lineHeight="20px" + onClick={() => { + if(valueCoupon === "") return + setCoupon(valueCoupon) + }} > Aplicar @@ -1866,12 +1915,51 @@ const PlansAndPayment = ({ userData }) => { Período de teste - 7 dias grátis + + + + + + Subtotal + {checkoutInfos?.amount?.toLocaleString('pt-BR', { style: 'currency', currency: 'BRL', minimumFractionDigits: 2 })}/{formattedPlanInterval(checkoutInfos?.interval, true)} + + + {/* */} + + + Total a pagar + {checkoutInfos?.amount?.toLocaleString('pt-BR', { style: 'currency', currency: 'BRL', minimumFractionDigits: 2 })}/{formattedPlanInterval(checkoutInfos?.interval, true)} + + @@ -1887,6 +1975,7 @@ const PlansAndPayment = ({ userData }) => { openModalSucess()} onErro={() => openModalErro()} /> @@ -2197,7 +2286,8 @@ const PlansAndPayment = ({ userData }) => { button={{ text: `${subscriptionInfo?.stripeSubscription === "bd_pro" ? "Plano atual" : hasSubscribed ? "Assinar" : "Iniciar teste grátis"}`, onClick: subscriptionInfo?.stripeSubscription === "bd_pro" ? () => {} : () => { - setPlan({id: plans?.[`bd_pro_${toggleAnual ? "year" : "month"}`]._id}) + setPlan(plans?.[`bd_pro_${toggleAnual ? "year" : "month"}`]._id) + setToggleAnual(true) PlansModal.onClose() PaymentModal.onOpen() }, @@ -2218,7 +2308,8 @@ const PlansAndPayment = ({ userData }) => { button={{ text: `${subscriptionInfo?.stripeSubscription === "bd_pro_empresas" ? "Plano atual" : hasSubscribed ? "Assinar" : "Iniciar teste grátis"}`, onClick: subscriptionInfo?.stripeSubscription === "bd_pro_empresas" ? () => {} : () => { - setPlan({id: plans?.[`bd_empresas_${toggleAnual ? "year" : "month"}`]._id}) + setPlan(plans?.[`bd_empresas_${toggleAnual ? "year" : "month"}`]._id) + setToggleAnual(true) PlansModal.onClose() PaymentModal.onOpen() }, diff --git a/next/pages/user/login.js b/next/pages/user/login.js index a6c30d19c..24ad958cf 100644 --- a/next/pages/user/login.js +++ b/next/pages/user/login.js @@ -82,7 +82,7 @@ export default function Login() { cookies.set('userBD', JSON.stringify(userData)) if(query.i) { - return window.open(`/user/${userData.username}?plans_and_payment&q=${query.q}&i=${query.i}`, "_self") + return window.open(`/user/${userData.username}?plans_and_payment&i=${query.i}`, "_self") } if(userData.workDataTool === null) return window.open("/user/survey", "_self") From a7c95578605f79b3445bcdd18e01900233e1aab7 Mon Sep 17 00:00:00 2001 From: aldemirLucas Date: Fri, 13 Sep 2024 02:39:58 -0300 Subject: [PATCH 03/14] fix: bug in plans year in modal --- next/pages/user/[username].js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/next/pages/user/[username].js b/next/pages/user/[username].js index 10cf114e9..3517dcc13 100644 --- a/next/pages/user/[username].js +++ b/next/pages/user/[username].js @@ -1532,7 +1532,10 @@ const PlansAndPayment = ({ userData }) => { title: "BD Grátis", buttons: [{ text:"Comparar planos", - onClick: () => PlansModal.onOpen()} + onClick: () => { + PlansModal.onOpen() + setToggleAnual(true) + }} ], resources : [ {name: "Tabelas tratadas"}, @@ -1733,6 +1736,7 @@ const PlansAndPayment = ({ userData }) => { isOpen={PaymentModal.isOpen} onClose={() => { setToggleAnual(true) + if(query.i) return window.open(`/user/${userData.username}?plans_and_payment`, "_self") PaymentModal.onClose() }} propsModalContent={{ @@ -1802,6 +1806,7 @@ const PlansAndPayment = ({ userData }) => { marginLeft="auto" onClick={() => { PaymentModal.onClose() + setToggleAnual(true) PlansModal.onOpen() }} >Alterar plano @@ -2158,10 +2163,7 @@ const PlansAndPayment = ({ userData }) => { {/* modal plans */} { - PlansModal.onClose() - setToggleAnual(true) - }} + onClose={PlansModal.onClose} propsModal={{ scrollBehavior: isMobileMod() ? "outside" : "inside", }} @@ -2287,7 +2289,6 @@ const PlansAndPayment = ({ userData }) => { text: `${subscriptionInfo?.stripeSubscription === "bd_pro" ? "Plano atual" : hasSubscribed ? "Assinar" : "Iniciar teste grátis"}`, onClick: subscriptionInfo?.stripeSubscription === "bd_pro" ? () => {} : () => { setPlan(plans?.[`bd_pro_${toggleAnual ? "year" : "month"}`]._id) - setToggleAnual(true) PlansModal.onClose() PaymentModal.onOpen() }, @@ -2309,7 +2310,6 @@ const PlansAndPayment = ({ userData }) => { text: `${subscriptionInfo?.stripeSubscription === "bd_pro_empresas" ? "Plano atual" : hasSubscribed ? "Assinar" : "Iniciar teste grátis"}`, onClick: subscriptionInfo?.stripeSubscription === "bd_pro_empresas" ? () => {} : () => { setPlan(plans?.[`bd_empresas_${toggleAnual ? "year" : "month"}`]._id) - setToggleAnual(true) PlansModal.onClose() PaymentModal.onOpen() }, @@ -2590,7 +2590,10 @@ const PlansAndPayment = ({ userData }) => { letterSpacing="0.3px" _hover={{opacity: 0.7}} marginTop="16px !important" - onClick={() => PlansModal.onOpen()} + onClick={() => { + PlansModal.onOpen() + setToggleAnual(true) + }} > Veja tudo e compare os planos From 057186403e4e9b4e4a7a682820dff783be5f7d5b Mon Sep 17 00:00:00 2001 From: aldemirLucas Date: Fri, 13 Sep 2024 18:30:09 -0300 Subject: [PATCH 04/14] feat: added coupon validation system and visual update in modal --- next/pages/api/stripe/validateStripeCoupon.js | 47 +++++ next/pages/user/[username].js | 194 +++++++++++++----- 2 files changed, 190 insertions(+), 51 deletions(-) create mode 100644 next/pages/api/stripe/validateStripeCoupon.js diff --git a/next/pages/api/stripe/validateStripeCoupon.js b/next/pages/api/stripe/validateStripeCoupon.js new file mode 100644 index 000000000..178c465ec --- /dev/null +++ b/next/pages/api/stripe/validateStripeCoupon.js @@ -0,0 +1,47 @@ +import axios from "axios"; + +const API_URL= `${process.env.NEXT_PUBLIC_API_URL}/api/v1/graphql` + +async function validateStripeCoupon({id, coupon, token}) { + try { + const res = await axios({ + url: API_URL, + method: "POST", + headers: { + Authorization: `Bearer ${token}` + }, + data: { + query:` + mutation { + validateStripeCoupon (priceId: ${id}, coupon: "${coupon}") { + isValid + discountAmount + duration + durationInMonths + errors + } + } + ` + } + }) + const data = res.data + return data + } catch (error) { + console.error(error) + return "err" + } +} + +export default async function handler(req, res) { + const token = req.cookies.token + const result = await validateStripeCoupon({ + id: atob(req.query.p), + coupon: atob(req.query.c), + token: token + }) + + if(result.errors) return res.status(500).json({error: result.errors}) + if(result === "err") return res.status(500).json({error: "err"}) + + res.status(200).json(result?.data?.validateStripeCoupon) +} diff --git a/next/pages/user/[username].js b/next/pages/user/[username].js index 3517dcc13..09764baf6 100644 --- a/next/pages/user/[username].js +++ b/next/pages/user/[username].js @@ -1444,6 +1444,8 @@ const PlansAndPayment = ({ userData }) => { const [plan, setPlan] = useState("") const [checkoutInfos, setCheckoutInfos] = useState({}) const [valueCoupon, setValueCoupon] = useState("") + const [errCoupon, setErrCoupon] = useState(false) + const [couponInfos, setCouponInfos] = useState({}) const [couponInputFocus, setCouponInputFocus] = useState(false) const [coupon, setCoupon] = useState("") const PaymentModal = useDisclosure() @@ -1717,10 +1719,74 @@ const PlansAndPayment = ({ userData }) => { let togglerValue = !toggleAnual ? "year" : "month" const value = Object.values(plans).find(elm => elm.interval === togglerValue && elm.productSlug === checkoutInfos?.productSlug) setCheckoutInfos(value) + setCoupon("") + setValueCoupon("") setPlan(value._id) setToggleAnual(!toggleAnual) } + async function validateStripeCoupon() { + if(valueCoupon === "") return + setErrCoupon(false) + + const result = await fetch(`/api/stripe/validateStripeCoupon?p=${btoa(plan)}&c=${btoa(valueCoupon)}`, { method: "GET" }) + .then(res => res.json()) + + if(result?.isValid === false || result?.errors || !result) { + setValueCoupon("") + setErrCoupon(true) + } else { + setCouponInfos(result) + setCoupon(valueCoupon) + } + } + + const CouponDisplay = () => { + let limitText + + if(couponInfos?.duration === "once") limitText = "(válido apenas na 1ª cobrança)" + if(couponInfos?.duration === "repeating") limitText = `(válido por ${couponInfos?.durationInMonths} meses)` + + return ( + <> + + Cupom {coupon.toUpperCase()} {limitText} + + + - {couponInfos?.discountAmount?.toLocaleString('pt-BR', { style: 'currency', currency: 'BRL', minimumFractionDigits: 2 })}/{formattedPlanInterval(checkoutInfos?.interval, true)} + + + ) + } + + const TotalToPayDisplay = () => { + let value + + if(couponInfos?.discountAmount) { + value = (checkoutInfos?.amount-couponInfos?.discountAmount).toLocaleString('pt-BR', { style: 'currency', currency: 'BRL', minimumFractionDigits: 2 }) + } else { + value = checkoutInfos?.amount?.toLocaleString('pt-BR', { style: 'currency', currency: 'BRL', minimumFractionDigits: 2 }) + } + + return ( + <> + + Total a pagar + + + {value}/{formattedPlanInterval(checkoutInfos?.interval, true)} + + + ) + } + + useEffect(() => { + if(valueCoupon === "") { + setCoupon("") + setCouponInfos("") + } + }, [valueCoupon]) + useEffect(() => { if(isLoading === true || isLoadingH === true) closeModalSucess() if(isLoadingCanSub === true) cancelSubscripetion() @@ -1807,6 +1873,8 @@ const PlansAndPayment = ({ userData }) => { onClick={() => { PaymentModal.onClose() setToggleAnual(true) + setCoupon("") + setValueCoupon("") PlansModal.onOpen() }} >Alterar plano @@ -1865,27 +1933,45 @@ const PlansAndPayment = ({ userData }) => { > Cupom de desconto + - + + + {valueCoupon && + setValueCoupon("")} + /> + } + { alignItems="center" justifyContent="center" width="fit-content" - height="40px" + height="44px" borderRadius="8px" padding="10px 34px" border="1px solid" @@ -1909,14 +1995,32 @@ const PlansAndPayment = ({ userData }) => { fontWeight="500" fontSize="14px" lineHeight="20px" - onClick={() => { - if(valueCoupon === "") return - setCoupon(valueCoupon) - }} + onClick={() => validateStripeCoupon()} > Aplicar + + {errCoupon && + + Por favor, insira um cupom válido. + + } { - - + Subtotal + + {checkoutInfos?.amount?.toLocaleString('pt-BR', { style: 'currency', currency: 'BRL', minimumFractionDigits: 2 })}/{formattedPlanInterval(checkoutInfos?.interval, true)} - + - {/* */} - - - Total a pagar - {checkoutInfos?.amount?.toLocaleString('pt-BR', { style: 'currency', currency: 'BRL', minimumFractionDigits: 2 })}/{formattedPlanInterval(checkoutInfos?.interval, true)} - - + {couponInfos?.discountAmount && + + } + + From 66d1d9c48e3db56ede42678dd7a5562010a6a82f Mon Sep 17 00:00:00 2001 From: aldemirLucas Date: Sun, 15 Sep 2024 17:28:01 -0300 Subject: [PATCH 05/14] feat: ajust visual in stripe modal payment --- next/components/organisms/PaymentSystem.js | 41 ++++++++++++++++++---- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/next/components/organisms/PaymentSystem.js b/next/components/organisms/PaymentSystem.js index 605166555..fd9af5e57 100644 --- a/next/components/organisms/PaymentSystem.js +++ b/next/components/organisms/PaymentSystem.js @@ -89,30 +89,57 @@ export default function PaymentSystem({ userData, plan, coupon, onSucess, onErro const appearance = { theme: "stripe", variables: { + fontFamily: 'Roboto, sans-serif', fontSizeBase: "16px", fontSizeSm: "16px", - fontFamily: "Ubuntu", borderRadius: "14px", - colorPrimary: "#42B0FF", + colorPrimary: "#2B8C4D", colorTextPlaceholder: "#464A51", - colorDanger: "#D93B3B", - colorBackground: "#FFF", + colorDanger: "#BF3434", + colorBackground: "#FFFFFF", colorText: "#252A32", }, rules: { ".Input": { - border: "1px solid #DEDFE0", + border: "2px solid #EEEEEE", + backgroundColor: "#EEEEEE" }, ".Input:hover": { - border: "2px solid #42B0FF", + backgroundColor:"#DEDFE0", + borderColor: "#DEDFE0" }, + ".Input:focus": { + backgroundColor: "#FFFFFF", + border:"2px solid #0068C5", + borderColor: "#0068C5", + boxShadow: "none", + outline: "none" + }, + ".Input:focus:hover": { + backgroundColor: "#FFFFFF", + borderColor: "#0068C5", + }, + ".Tab": { + border: "2px solid #ececec", + backgroundColor: "#FFF", + boxShadow: "none" + }, + ".Tab:focus": { + boxShadow: "none" + }, + ".Tab--selected": { + boxShadow: "none" + }, + ".Tab--selected:focus": { + boxShadow: "none" + } } } const options = { clientSecret, appearance, - fonts: [{ cssSrc: 'https://fonts.googleapis.com/css2?family=Ubuntu:wght@400;700&display=swap' }], + fonts: [{ cssSrc: 'https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap' }], } const customerCreatPost = async (id, coupon) => { From d7a8c7a5a9aa6db948e6780381f3e7cabc2df260 Mon Sep 17 00:00:00 2001 From: aldemirLucas Date: Mon, 16 Sep 2024 16:08:38 -0300 Subject: [PATCH 06/14] feat: ajust text in coupon description --- next/pages/user/[username].js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/next/pages/user/[username].js b/next/pages/user/[username].js index 09764baf6..5d5b0b6e6 100644 --- a/next/pages/user/[username].js +++ b/next/pages/user/[username].js @@ -1516,14 +1516,15 @@ const PlansAndPayment = ({ userData }) => { if(plan === "") return const value = Object.values(plans).find(elm => elm._id === plan) + if(value?.interval === "month") setToggleAnual(false) setCheckoutInfos(value) + PaymentModal.onOpen() }, [plan, plans]) useEffect(() => { if(query.i) { if(subscriptionInfo?.isActive === true) return AlertChangePlanModal.onOpen() setPlan(query.i) - PaymentModal.onOpen() } }, [query]) @@ -1744,15 +1745,15 @@ const PlansAndPayment = ({ userData }) => { const CouponDisplay = () => { let limitText - if(couponInfos?.duration === "once") limitText = "(válido apenas na 1ª cobrança)" - if(couponInfos?.duration === "repeating") limitText = `(válido por ${couponInfos?.durationInMonths} meses)` + if(couponInfos?.duration === "once") limitText = toggleAnual ? "(válido por 1 ano)" : "(válido por 1 mês)" + if(couponInfos?.duration === "repeating") limitText = `(válido por ${couponInfos?.durationInMonths} ${couponInfos?.durationInMonths.length === 1 ? "mês" : "meses"})` return ( <> Cupom {coupon.toUpperCase()} {limitText} - + - {couponInfos?.discountAmount?.toLocaleString('pt-BR', { style: 'currency', currency: 'BRL', minimumFractionDigits: 2 })}/{formattedPlanInterval(checkoutInfos?.interval, true)} @@ -1773,7 +1774,7 @@ const PlansAndPayment = ({ userData }) => { Total a pagar - + {value}/{formattedPlanInterval(checkoutInfos?.interval, true)} @@ -1802,6 +1803,7 @@ const PlansAndPayment = ({ userData }) => { isOpen={PaymentModal.isOpen} onClose={() => { setToggleAnual(true) + setValueCoupon("") if(query.i) return window.open(`/user/${userData.username}?plans_and_payment`, "_self") PaymentModal.onClose() }} @@ -2035,7 +2037,7 @@ const PlansAndPayment = ({ userData }) => { { Subtotal - + {checkoutInfos?.amount?.toLocaleString('pt-BR', { style: 'currency', currency: 'BRL', minimumFractionDigits: 2 })}/{formattedPlanInterval(checkoutInfos?.interval, true)} From ac2e32eb6ee2b9d0d9f9b6c8de3ee6b0cbc26b89 Mon Sep 17 00:00:00 2001 From: aldemirLucas Date: Tue, 17 Sep 2024 15:20:51 -0300 Subject: [PATCH 07/14] fix: bd pro download --- next/components/molecules/DataInformationQuery.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/next/components/molecules/DataInformationQuery.js b/next/components/molecules/DataInformationQuery.js index c51b9a65e..588107004 100644 --- a/next/components/molecules/DataInformationQuery.js +++ b/next/components/molecules/DataInformationQuery.js @@ -196,7 +196,7 @@ export default function DataInformationQuery({ resource }) { let user if(cookies.get("userBD")) user = JSON.parse(cookies.get("userBD")) - if(user?.proSubscriptionStatus === "active") return true + if(user?.internalSubscription?.edges?.[0]?.node?.isActive === true) return true return false } From f22b25744b7ee87c973a24e18938c56bdeb3de7d Mon Sep 17 00:00:00 2001 From: aldemirLucas Date: Tue, 17 Sep 2024 17:32:14 -0300 Subject: [PATCH 08/14] feat: text explaining the duration of the coupon --- next/components/molecules/ColumnsTable.js | 32 ++++++++++++++++--- .../molecules/DataInformationQuery.js | 2 +- next/pages/user/[username].js | 16 ++++++++++ 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/next/components/molecules/ColumnsTable.js b/next/components/molecules/ColumnsTable.js index cbe2e726e..d507e95b8 100644 --- a/next/components/molecules/ColumnsTable.js +++ b/next/components/molecules/ColumnsTable.js @@ -440,7 +440,7 @@ export default function ColumnsTable({ + } {headers.map((elm, i) => ( @@ -594,7 +604,9 @@ export default function ColumnsTable({ {template === "checks" && handleCheckboxChange(elm.node.name)} /> + } {elm?.node?.name ? elm.node.name : "Não informado"} { if(result?.isValid === false || result?.errors || !result) { setValueCoupon("") setErrCoupon(true) + } + if(result?.duration === "repeating" && toggleAnual === true) { + setValueCoupon("") + setErrCoupon(true) } else { setCouponInfos(result) setCoupon(valueCoupon) @@ -2059,6 +2063,18 @@ const PlansAndPayment = ({ userData }) => { } + + {(couponInfos?.duration === "once" || couponInfos?.duration === "repeating") && + + A partir do {couponInfos?.duration === "once" && 2} {couponInfos?.duration === "repeating" && couponInfos?.durationInMonths + 1}°{formattedPlanInterval(checkoutInfos?.interval, true)}, o total a pagar será de {checkoutInfos?.amount?.toLocaleString('pt-BR', { style: 'currency', currency: 'BRL', minimumFractionDigits: 2 })}/{formattedPlanInterval(checkoutInfos?.interval, true)}. + + } From 52440280b6e13c953f041e65e7dcb1017a931a8c Mon Sep 17 00:00:00 2001 From: aldemirLucas Date: Wed, 18 Sep 2024 16:09:28 -0300 Subject: [PATCH 09/14] feat: ajust trial sub text ind checkout payment --- next/pages/user/[username].js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/next/pages/user/[username].js b/next/pages/user/[username].js index 8828c9e09..00638d742 100644 --- a/next/pages/user/[username].js +++ b/next/pages/user/[username].js @@ -2072,7 +2072,7 @@ const PlansAndPayment = ({ userData }) => { lineHeight="24px" color="#464A51" > - A partir do {couponInfos?.duration === "once" && 2} {couponInfos?.duration === "repeating" && couponInfos?.durationInMonths + 1}°{formattedPlanInterval(checkoutInfos?.interval, true)}, o total a pagar será de {checkoutInfos?.amount?.toLocaleString('pt-BR', { style: 'currency', currency: 'BRL', minimumFractionDigits: 2 })}/{formattedPlanInterval(checkoutInfos?.interval, true)}. + A partir do {couponInfos?.duration === "once" && 2} {couponInfos?.duration === "repeating" && couponInfos?.durationInMonths + 1}º {formattedPlanInterval(checkoutInfos?.interval, true)} {!hasSubscribed && "e 7º dia"}, o total a pagar será de {checkoutInfos?.amount?.toLocaleString('pt-BR', { style: 'currency', currency: 'BRL', minimumFractionDigits: 2 })}/{formattedPlanInterval(checkoutInfos?.interval, true)}. } From 83daca584c5405e9eaafee17699ca1eb24e8961c Mon Sep 17 00:00:00 2001 From: aldemirLucas Date: Wed, 18 Sep 2024 17:44:27 -0300 Subject: [PATCH 10/14] fix: err toggleAnual in page price --- next/pages/precos.js | 1 + 1 file changed, 1 insertion(+) diff --git a/next/pages/precos.js b/next/pages/precos.js index 3e4b0fc76..2a7d517ef 100644 --- a/next/pages/precos.js +++ b/next/pages/precos.js @@ -338,6 +338,7 @@ export function SectionPrice() { } } + setToggleAnual(true) fecthPlans() }, []) From 85ad796be43b3dbde455af2e3798deed822c551d Mon Sep 17 00:00:00 2001 From: aldemirLucas Date: Wed, 18 Sep 2024 17:45:18 -0300 Subject: [PATCH 11/14] fix: err toggleAnual in page price --- next/pages/precos.js | 1 + 1 file changed, 1 insertion(+) diff --git a/next/pages/precos.js b/next/pages/precos.js index 3e4b0fc76..2a7d517ef 100644 --- a/next/pages/precos.js +++ b/next/pages/precos.js @@ -338,6 +338,7 @@ export function SectionPrice() { } } + setToggleAnual(true) fecthPlans() }, []) From c5e88222306f15dcdf3623e5740c7ad566ed1e0e Mon Sep 17 00:00:00 2001 From: aldemirLucas Date: Wed, 18 Sep 2024 18:24:44 -0300 Subject: [PATCH 12/14] feat: change icon twitter for bluesky --- next/components/molecules/Footer.js | 6 ++++-- next/pages/quem-somos.js | 4 +++- next/public/img/icons/blueskyIcon.js | 14 ++++++++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 next/public/img/icons/blueskyIcon.js diff --git a/next/components/molecules/Footer.js b/next/components/molecules/Footer.js index ca4600cce..6b1a86138 100644 --- a/next/components/molecules/Footer.js +++ b/next/components/molecules/Footer.js @@ -9,7 +9,8 @@ import BodyText from "../atoms/BodyText" import { isMobileMod } from "../../hooks/useCheckMobile.hook" import YoutubeIcon from "../../public/img/icons/youtubeIcon"; -import TwitterIcon from "../../public/img/icons/twitterIcon"; +// import TwitterIcon from "../../public/img/icons/twitterIcon"; +import BlueskyIcon from "../../public/img/icons/blueskyIcon"; import DiscordIcon from "../../public/img/icons/discordIcon"; import GithubIcon from "../../public/img/icons/githubIcon"; import LinkedinIcon from "../../public/img/icons/linkedinIcon"; @@ -262,7 +263,8 @@ export default function Footer({ template, ocult = false }) { - }/> + {/* }/> */} + }/> }/> }/> }/> diff --git a/next/pages/quem-somos.js b/next/pages/quem-somos.js index 5dfa81dc5..e6538000c 100755 --- a/next/pages/quem-somos.js +++ b/next/pages/quem-somos.js @@ -27,6 +27,7 @@ import InternalError from "../public/img/internalError"; import WebIcon from "../public/img/icons/webIcon"; import EmailIcon from "../public/img/icons/emailIcon"; import TwitterIcon from "../public/img/icons/twitterIcon"; +import BlueskyIcon from "../public/img/icons/blueskyIcon"; import LinkedinIcon from "../public/img/icons/linkedinIcon"; import GithubIcon from "../public/img/icons/githubIcon"; import DiscordIcon from "../public/img/icons/discordIcon"; @@ -376,7 +377,8 @@ export default function QuemSomos({ data }) { zIndex="1" backgroundColor="#FFF" > - + {/* */} + diff --git a/next/public/img/icons/blueskyIcon.js b/next/public/img/icons/blueskyIcon.js new file mode 100644 index 000000000..25975b017 --- /dev/null +++ b/next/public/img/icons/blueskyIcon.js @@ -0,0 +1,14 @@ +import { createIcon } from '@chakra-ui/icons'; + +const BlueskyIcon = createIcon({ + displayName: "bluesky", + viewBox: "0 0 24 24", + path: ( + + ), +}) + +export default BlueskyIcon \ No newline at end of file From 85f05e883955c0eb45722340710e705fea3d4bea Mon Sep 17 00:00:00 2001 From: aldemirLucas Date: Wed, 18 Sep 2024 19:22:15 -0300 Subject: [PATCH 13/14] fix: redirect bug in dataset page --- next/components/organisms/DatasetResource.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/next/components/organisms/DatasetResource.js b/next/components/organisms/DatasetResource.js index 6d1f4c908..d9c22ebc2 100644 --- a/next/components/organisms/DatasetResource.js +++ b/next/components/organisms/DatasetResource.js @@ -23,7 +23,7 @@ export default function DatasetResource({ const [informationRequests, setInformationRequests] = useState([]) const pushQuery = (key, value) => { - router.push({ + router.replace({ pathname: `/dataset/${query.dataset}`, query: { [key]: value } }, From 9566f485eff1924589ed5a0caeb5298ad6d43e85 Mon Sep 17 00:00:00 2001 From: aldemirLucas Date: Thu, 19 Sep 2024 16:40:09 -0300 Subject: [PATCH 14/14] chore: ajust border input stripe --- next/components/organisms/PaymentSystem.js | 1 + 1 file changed, 1 insertion(+) diff --git a/next/components/organisms/PaymentSystem.js b/next/components/organisms/PaymentSystem.js index fd9af5e57..9a7927d42 100644 --- a/next/components/organisms/PaymentSystem.js +++ b/next/components/organisms/PaymentSystem.js @@ -101,6 +101,7 @@ export default function PaymentSystem({ userData, plan, coupon, onSucess, onErro }, rules: { ".Input": { + borderRadius: "8px", border: "2px solid #EEEEEE", backgroundColor: "#EEEEEE" },