show taxes and shipping

This commit is contained in:
PallaviS67 2022-09-13 14:52:39 +05:30
parent 0d9d752e53
commit b29d2f4f9c
22 changed files with 376 additions and 117 deletions

13
CMS/api.ts Normal file
View File

@ -0,0 +1,13 @@
export function getStrapiURL(path = "") {
return `${
process.env.NEXT_PUBLIC_STRAPI_API_URL || "http://localhost:1337"
}${path}`
}
// Helper to make GET requests to Strapi
export async function fetchAPI(path : string ) {
const requestUrl = getStrapiURL(path)
const response = await fetch(requestUrl)
const data = await response.json()
return data
}

View File

@ -15,23 +15,22 @@ import ShowTaxationWidget from '@components/checkout/ShowTaxWidget'
import ShippingRatesWidget from '@components/checkout/ShippingRatesWidget'
import useGetTax from '@framework/tax/get-tax'
import useShowTax from '@framework/tax/show-tax'
import useShippingRates from '@framework/shipping-rates/get-shipping-rates'
const CartSidebarView: FC = () => {
const { closeSidebar, setSidebarView, sidebarView } = useUI()
const { data, isLoading, isEmpty } = useCart()
const { data: checkoutData, submit: onCheckout } = useCheckout()
if(sidebarView == 'GET_TAXATION_VIEW'){
const getTax = useGetTax()
console.log(getTax)
}
else if(sidebarView == 'SHOW_TAXATION_VIEW'){
const showTax = useShowTax()
}
else if(sidebarView == 'SHIPPING_RATES_WIDGET'){
const shippingRates = useShippingRates()
}
// if(sidebarView == 'GET_TAXATION_VIEW'){
// const getTax = useGetTax()
// console.log(getTax)
// }
// else if(sidebarView == 'SHOW_TAXATION_VIEW'){
// const showTax = useShowTax()
// }
// else if(sidebarView == 'SHIPPING_RATES_WIDGET'){
// const shippingRates = useShippingRates()
// }
async function handleSubmit(event: any) {
event.preventDefault()

View File

@ -11,13 +11,49 @@ import ShippingWidget from '../ShippingWidget'
import PaymentWidget from '../PaymentWidget'
import s from './CheckoutSidebarView.module.css'
import { useCheckoutContext } from '../context'
import GetTaxationWidget from '@components/checkout/GetTaxationWidget'
import ShowTaxationWidget from '@components/checkout/ShowTaxWidget'
import ShippingRatesWidget from '@components/checkout/ShippingRatesWidget'
import useShowTax from '@framework/tax/show-tax'
import useShowShipping from '@framework/shippingRates/get-shipping-rates'
const CheckoutSidebarView: FC = () => {
const [loadingSubmit, setLoadingSubmit] = useState(false)
const { setSidebarView, closeSidebar } = useUI()
const { closeSidebar, setSidebarView, sidebarView } = useUI()
const { data: cartData, revalidate: refreshCart } = useCart()
const { data: checkoutData, submit: onCheckout } = useCheckout()
const { clearCheckoutFields } = useCheckoutContext()
const [tax , setTax] = useState<any>();
const [shipping , setShipping] = useState<any>();
async function callTax(){
console.log(cartData , "in call tax")
const res = await useShowTax(
cartData && {
amount: Number(cartData.subtotalPrice),
cartId : cartData.id
}
)
setTax(res);
}
callTax();
async function callShipping(){
console.log(cartData , "in call tax")
const res = await useShowShipping(
cartData && {
amount: Number(cartData.subtotalPrice),
cartId : cartData.id
}
)
setShipping(res);
}
callShipping();
async function handleSubmit(event: React.ChangeEvent<HTMLFormElement>) {
try {
@ -68,6 +104,21 @@ const CheckoutSidebarView: FC = () => {
isValid={checkoutData?.hasShipping}
onClick={() => setSidebarView('SHIPPING_VIEW')}
/>
<div className="px-4 sm:px-6 flex-1">
</div>
<div className="px-4 sm:px-6 flex-1">
<ShowTaxationWidget
isValid={checkoutData?.hasShipping}
onClick={() => setSidebarView('SHOW_TAXATION_VIEW')}
/>
</div>
<div className="px-4 sm:px-6 flex-1">
<ShippingRatesWidget
isValid={checkoutData?.hasShipping}
onClick={() => setSidebarView('SHIPPING_RATES_WIDGET')}
/>
</div>
<ul className={s.lineItemsList}>
{cartData!.lineItems.map((item: any) => (
@ -92,11 +143,11 @@ const CheckoutSidebarView: FC = () => {
</li>
<li className="flex justify-between py-1">
<span>Taxes</span>
<span>Calculated at checkout</span>
<span>{tax}</span>
</li>
<li className="flex justify-between py-1">
<span>Shipping</span>
<span className="font-bold tracking-wide">FREE</span>
<span className="font-bold tracking-wide">{shipping}</span>
</li>
</ul>
<div className="flex justify-between border-t border-accent-2 py-3 font-bold mb-2">

View File

@ -9,14 +9,12 @@ import useAddAddress from '@framework/customer/address/use-add-item'
import s from './ShippingView.module.css'
interface Form extends HTMLFormElement {
cardHolder: HTMLInputElement
cardNumber: HTMLInputElement
cardExpireDate: HTMLInputElement
cardCvc: HTMLInputElement
type: HTMLInputElement,
firstName: HTMLInputElement
lastName: HTMLInputElement
company: HTMLInputElement
streetNumber: HTMLInputElement
apartments: HTMLInputElement,
zipCode: HTMLInputElement
city: HTMLInputElement
country: HTMLSelectElement
@ -28,8 +26,7 @@ const ShippingView: FC = () => {
async function handleSubmit(event: React.ChangeEvent<Form>) {
event.preventDefault()
await addAddress({
const input = {
type: event.target.type.value,
firstName: event.target.firstName.value,
lastName: event.target.lastName.value,
@ -39,7 +36,9 @@ const ShippingView: FC = () => {
zipCode: event.target.zipCode.value,
city: event.target.city.value,
country: event.target.country.value,
})
}
console.log(input);
await addAddress(input)
setSidebarView('CHECKOUT_VIEW')
}
@ -100,7 +99,7 @@ const ShippingView: FC = () => {
<div className={s.fieldset}>
<label className={s.label}>Country/Region</label>
<select name="country" className={s.select}>
<option>Hong Kong</option>
<option>US</option>
</select>
</div>
</div>

View File

@ -12,7 +12,7 @@ interface SwatchProps {
color?: string
label?: string | null
}
// eslint-disable-next-line react/display-name
const Swatch: React.FC<Omit<ButtonProps, 'variant'> & SwatchProps> = React.memo(
({
active,

View File

@ -20,7 +20,7 @@ export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
loading?: boolean
disabled?: boolean
}
// eslint-disable-next-line react/display-name
const Button: React.FC<ButtonProps> = forwardRef((props, buttonRef) => {
const {
className,

View File

@ -9,7 +9,7 @@ export interface CollapseProps {
title: string
children: ReactNode
}
// eslint-disable-next-line react/display-name
const Collapse: FC<CollapseProps> = React.memo(({ title, children }) => {
const [isActive, setActive] = useState(false)
const [ref, { height: viewHeight }] = useMeasure()

View File

@ -3,6 +3,7 @@ import { SWRHook } from '@commerce/utils/types'
import useCart, { UseCart } from '@commerce/cart/use-cart'
import epClient from '../utils/ep-client'
import normalizeCart from '../utils/normalize-cart'
import { getCookies, setCookie, deleteCookie } from 'cookies-next';
export default useCart as UseCart<typeof handler>
@ -13,7 +14,10 @@ export const handler: SWRHook<any> = {
async fetcher({fetch}) {
const {data:cartData} = await epClient.Cart().Get();
const {data:cartItems} = await epClient.Cart().Items();
return normalizeCart(cartData, cartItems);
const cartDetails = await normalizeCart(cartData, cartItems);
console.log(cartDetails)
cartDetails && setCookie('cartId', cartDetails.id);
return cartDetails ;
},
useHook: ({ useData }) => (input) => {
const response = useData({

View File

@ -1,15 +1,131 @@
import useAddItem, { UseAddItem } from '@commerce/customer/address/use-add-item'
import { MutationHook } from '@commerce/utils/types'
import epClient from '../../utils/ep-client';
import { getCookies, setCookie, deleteCookie, getCookie } from 'cookies-next';
import useAddresses from './use-addresses';
import { useCallback } from 'react'
import { gateway as MoltinGateway} from '@moltin/sdk';
import { MoltinClient } from '@moltin/request';
import axios from "axios";
import useCart from '@framework/cart/use-cart';
import cart from 'pages/api/cart';
const Moltin = MoltinGateway({
client_id: process.env.NEXT_PUBLIC_ELASTICPATH_CLIENTID,
})
export default useAddItem as UseAddItem<typeof handler>
const customerCookies = getCookie('user_token') ;
const customer_token = customerCookies && JSON.parse(customerCookies.toString());
console.log("customer token in add address", customer_token);
const cartId = getCookie('cartId');
export const handler: MutationHook<any> = {
fetchOptions: {
query: '',
},
async fetcher({ input, options, fetch }) {},
useHook:
({ fetch }) =>
() =>
async () => ({}),
}
async fetcher({ input, options, fetch }) {
console.log(cartId , " for shipping and tax") ;
console.log("inside add address code " , input);
// console.log(address , "address for ep");
// Moltin.Addresses.Create({
// customer: customer_token.customer_id,
// body: {type : 'address' , ...address},
// token: customer_token.token
// }).then((address: any) => {
// console.log("address added in ep" , address );
// })
axios({
url: 'http://localhost:3000/events/store/get-tax',
method: 'POST',
data: {
payload:{
data:{
cartId:cartId?.toString(),
shipping_address: {
first_name: input.firstName,
last_name: input.lastName,
company_name: input.company,
phone_number: "(555) 555-1234",
line_1: input.apartments,
city: input.city,
postcode: input.zipCode,
county : "NJ",
country: "Us",
instructions: "Leave in porch"
}
}
}
}
})
.then(function (response) {
console.log(response);
return response
})
.catch(function (error) {
console.log(error);
})
///shipping rates
axios({
url: 'http://localhost:3000/events/store/shipping-added',
method: 'POST',
data: {
payload:{
data:{
cartId:cartId?.toString(),
shipping_address: {
first_name: input.firstName,
last_name: input.lastName,
company_name: input.company,
phone_number: "(555) 555-1234",
line_1: input.apartments,
city: input.city,
postcode: input.zipCode,
county : "NJ",
country: "Us",
instructions: "Leave in porch"
}
}
}
}
})
.then(function (response) {
console.log(response);
return response
})
.catch(function (error) {
console.log(error);
})
const data = input;
return data ;
},
useHook: ({ fetch }) => () => {
const { mutate } = useAddresses()
return useCallback(
async function addItem(input) {
const data = await fetch({ input })
const addressData = data ;
await mutate(addressData, true)
return addressData
},
[fetch, mutate]
)
},
}

View File

@ -1,15 +1,35 @@
import { useCallback } from 'react'
import useAddItem, { UseAddItem } from '@commerce/customer/card/use-add-item'
import { MutationHook } from '@commerce/utils/types'
import useCard from './use-cards';
export default useAddItem as UseAddItem<typeof handler>
console.log("inside add card item ");
export const handler: MutationHook<any> = {
fetchOptions: {
query: '',
},
async fetcher({ input, options, fetch }) {},
useHook:
({ fetch }) =>
() =>
async () => ({}),
async fetcher({ input, options, fetch }) {
console.log("inside add card item handler ", input );
const data = input;
return data ;
},
useHook: ({ fetch }) => () => {
const { mutate } = useCard()
return useCallback(
async function addItem(input) {
const data = await fetch({ input })
const cardData = data ;
await mutate(cardData, true)
return cardData
},
[fetch, mutate]
)
},
}

View File

@ -30,4 +30,4 @@ export const handler: SWRHook<GetCardsHook> = {
[response]
)
},
}
}

View File

@ -11,14 +11,14 @@ export const handler: SWRHook<any> = {
},
async fetcher({fetch, options, input}) {
const creds = getCustomerCookie();
if(!creds.id || !creds.token) {
if(!creds.customer_id || !creds.token) {
return null;
}
const {data} = await fetch({
...options,
variables:{
params: [creds.id, creds.token]
params: [creds.customer_id, creds.token]
}
});

View File

@ -6,12 +6,12 @@ module.exports = {
domains: [
'localhost',
'206.189.135.123',
's3-eu-west-1.amazonaws.com'
's3-eu-west-1.amazonaws.com',
'files-eu.epusercontent.com'
]
},
commerce,
i18n: {
locales: ['en-US'],
defaultLocale: 'en-US',
},
webpack: (config, { isServer }) => {

View File

@ -22,6 +22,7 @@ import { handler as useAddAddressItem } from './customer/address/use-add-item'
import getTax from './tax/get-tax'
import showTax from './tax/show-tax'
import getShippingrates from './shippingRates/get-shipping-rates';
import {fetcher} from './fetcher'
@ -53,6 +54,9 @@ export const elasticpathProvider = {
getTax,
showTax
},
shippingRates:{
getShippingrates
},
products: { useSearch },
auth: { useLogin, useLogout, useSignup },
}

View File

@ -1,35 +0,0 @@
import axios from "axios";
const getShippingrates = () => {
axios({
url: 'http://206.189.135.123:3030/store-events/615aa7276b3472001db03258/get-shipping-rates',
method: 'POST',
data: {
payload:{
data: {
cartId :"Cart1",
shipping_address: {
first_name: "Otis",
last_name: "Sedmak",
phone_number: "(555) 555-1234",
company_name: "Sedmak & Co.",
line_1: "1251, Rexmere Ave",
line_2: "Farmingville, Suffolk",
city: "shipping city",
postcode: "11738",
county: "Farmingville, Suffolk",
country: "US",
instructions: "Leave in porch"
}
}
}
}
}).then((response: any) => {
console.log(response)
return response;
}).catch((error: any) => {
console.log(error)
})
}
export default getShippingrates;

View File

@ -0,0 +1,49 @@
import axios from 'axios'
// const MoltinGateway = require('@moltin/sdk').gateway
import { gateway as MoltinGateway } from '@moltin/sdk';
import { MoltinClient } from '@moltin/request';
import { getCookies, setCookie, deleteCookie, getCookie } from 'cookies-next';
import { CartItem } from '@components/cart';
import { useEffect, useMemo, useState } from 'react'
import { SWRHook } from '@commerce/utils/types'
const cartId = getCookie('cartId');
const customer_token = getCookie('user_token');
console.log("cartId in show tax " , cartId );
console.log("customer token " ,customer_token )
function getShipping (cartId : any){
console.log(cartId , "in tax calculation")
const tax = axios({
url: 'http://localhost:3000/events/store/showShipping',
method: 'POST',
data: {
payload: {
data: {
cartId: cartId
}
}
}
})
.then((response) =>{
return (response.data.shippingRates[0].shipmentCost)
})
return tax
}
export default function useShowShipping(
data?: {
amount: number
cartId: string
} | null
) {
console.log(data , " before function ")
const value = useMemo( async () => {
const res = await getShipping(data?.cartId);
return res;
}, [data?.amount , data?.cartId])
return value
}

View File

@ -1,13 +1,21 @@
import axios from "axios";
import { getCookies, setCookie, deleteCookie, getCookie } from 'cookies-next';
import useCart from "@framework/cart/use-cart";
const cartId = getCookie('cartId');
console.log("cartId " , cartId );
const getTax = () => {
const { data, isLoading, isEmpty } = useCart();
console.log(data);
axios({
url: 'http://206.189.135.123:3030/store-events/615aa7276b3472001db03258/get-tax',
url: 'http://localhost:3000/events/store/get-tax',
method: 'POST',
data: {
payload:{
data:{
cart_id:"Cart1",
cartId:cartId?.toString(),
shipping_address: {
first_name: "Otis",
last_name: "Sedmak",

View File

@ -2,39 +2,53 @@ import axios from 'axios'
// const MoltinGateway = require('@moltin/sdk').gateway
import { gateway as MoltinGateway } from '@moltin/sdk';
import { MoltinClient } from '@moltin/request';
import { getCookies, setCookie, deleteCookie, getCookie } from 'cookies-next';
import { CartItem } from '@components/cart';
import { useEffect, useMemo, useState } from 'react'
import { SWRHook } from '@commerce/utils/types'
const Moltin = MoltinGateway({
client_id: process.env.NEXT_PUBLIC_ELASTICPATH_CLIENTID
})
const client = new MoltinClient({
client_id: process.env.NEXT_PUBLIC_ELASTICPATH_CLIENTID,
client_secret: process.env.NEXT_PUBLIC_ELASTICPATH_SECRET
})
const getTax = () => {
Moltin.Cart('Cart1')
.Items()
.then((cart: any) => {
console.log(cart.data)
let taxItemId = cart?.data[0]?.relationships?.taxes?.data[0]?.id;
if(taxItemId){
client
.put(`carts/Cart1/items/12ef6cda-c8bb-483c-9b5f-4e89c7ef70f2/taxes/${taxItemId}`, {
type: "tax_item"
})
.then((items: any) => {
console.log("SUCCESS");
console.log(items);
return items
})
.catch(console.error)
}
const cartId = getCookie('cartId');
const customer_token = getCookie('user_token');
console.log("cartId in show tax " , cartId );
console.log("customer token " ,customer_token )
function getTax (cartId : any){
console.log(cartId , "in tax calculation")
const tax = axios({
url: 'http://localhost:3000/events/store/showTax',
method: 'POST',
data: {
payload: {
data: {
cartId: cartId
}
)
}
}
})
.then((response) =>{
let rates = 0;
for (const item of response.data.TaxRates.taxdata) {
rates += item.rate;
}
console.log(rates);
return rates
})
return tax
}
export default getTax;
export default function useShowTax(
data?: {
amount: number
cartId: string
} | null
) {
console.log(data , " before function ")
const value = useMemo( async () => {
const res = await getTax(data?.cartId);
return res;
}, [data?.amount , data?.cartId])
return value
}

View File

@ -21,9 +21,9 @@
"node": ">=14.x"
},
"dependencies": {
"@chec/commerce.js": "^2.8.0",
"@moltin/request": "^2.0.2",
"@moltin/sdk": "^8.8.1",
"@chec/commerce.js": "^2.8.0",
"@react-spring/web": "^9.2.1",
"@spree/storefront-api-v2-sdk": "^5.0.1",
"@vercel/fetch": "^6.1.1",
@ -32,6 +32,7 @@
"body-scroll-lock": "^3.1.5",
"classnames": "^2.3.1",
"cookie": "^0.4.1",
"cookies-next": "^2.1.1",
"email-validator": "^2.0.4",
"immutability-helper": "^3.1.1",
"js-cookie": "^2.2.1",
@ -39,7 +40,7 @@
"lodash.debounce": "^4.0.8",
"lodash.random": "^3.2.0",
"lodash.throttle": "^4.1.1",
"next": "^12.0.3",
"next": "^12.2.0",
"next-seo": "^4.26.0",
"next-themes": "^0.0.14",
"postcss": "^8.3.5",

View File

@ -7,6 +7,8 @@ import { Button, Text } from '@components/ui'
import { Bag, Cross, Check, MapPin, CreditCard } from '@components/icons'
import { CartItem } from '@components/cart'
import { useUI } from '@components/ui/context'
import { getCookies, setCookie, deleteCookie, getCookie } from 'cookies-next';
export async function getStaticProps({
preview,
@ -24,9 +26,11 @@ export async function getStaticProps({
}
export default function Cart() {
const error = null
const success = null
const { data, isLoading, isEmpty } = useCart()
const { data, isLoading, isEmpty } = useCart();
const { openSidebar, setSidebarView } = useUI()
const { price: subTotal } = usePrice(

View File

@ -4,12 +4,16 @@ import { ProductCard } from '@components/product'
import { Grid, Marquee, Hero } from '@components/ui'
// import HomeAllProductsGrid from '@components/common/HomeAllProductsGrid'
import type { GetStaticPropsContext, InferGetStaticPropsType } from 'next'
import { fetchAPI } from '../CMS/api';
import { ArticleJsonLd } from 'next-seo'
export async function getStaticProps({
preview,
locale,
locales,
locales
}: GetStaticPropsContext) {
const config = { locale, locales }
const productsPromise = commerce.getAllProducts({
variables: { first: 6 },
@ -23,21 +27,25 @@ export async function getStaticProps({
const { products } = await productsPromise
const { pages } = await pagesPromise
const { categories, brands } = await siteInfoPromise
//const [articles] = await Promise.all([fetchAPI("/articles")])
return {
props: {
products,
categories,
brands,
// articles,
pages,
},
revalidate: 60,
}
}
export default function Home({
products,
export default function Home({
products //,articles
}: InferGetStaticPropsType<typeof getStaticProps>) {
return (
<>
<Grid variant="filled">
@ -61,6 +69,10 @@ export default function Home({
headline=" Dessert dragée halvah croissant."
description="Cupcake ipsum dolor sit amet lemon drops pastry cotton candy. Sweet carrot cake macaroon bonbon croissant fruitcake jujubes macaroon oat cake. Soufflé bonbon caramels jelly beans. Tiramisu sweet roll cheesecake pie carrot cake. "
/>
{/* <Hero
headline={articles[4].title}
description={articles[0].description}
/> */}
<Grid layout="B" variant="filled">
{products.slice(0, 3).map((product: any, i: number) => (
<ProductCard

View File

@ -39,6 +39,6 @@
"./framework/spree",
"./framework/ordercloud",
"./framework/kibocommerce",
"./framework/commercejs"
"./framework/commercejs"
]
}