project_e_commerce icon indicating copy to clipboard operation
project_e_commerce copied to clipboard

Does anyone have a working AddressForm.jsx and Checkout.jsx form that conform to recent API object naming conventions?

Open KBCodes2021 opened this issue 3 years ago • 3 comments

I've completed 2/3rds of the project. I can log the token generated in Checkout.jsx and log it in the AddressForm.jsx. But when adding shippingSubdivision and setShippingOption I get HTTP 500 errors.

Any help would be appreciated! I've commented out components that were very unstable.

This is the Address Form: and Checkout is below:

import React, { useState, useEffect } from 'react'; import { InputLabel, Select, MenuItem, Button, Grid, Typography } from '@material-ui/core'; import { useForm, FormProvider } from 'react-hook-form'; import { Link } from 'react-router-dom';

import { commerce } from '../../lib/commerce'; import FormInput from './CustomTextField';

const AddressForm = ({ checkoutToken }) => { const [shippingCountries, setShippingCountries] = useState([]); const [shippingCountry, setShippingCountry] = useState(''); const [shippingSubdivisions, setShippingSubdivisions] = useState([]); const [shippingSubdivision, setShippingSubdivision] = useState(''); const [shippingOptions, setShippingOptions] = useState([]); const [shippingOption, setShippingOption] = useState(''); const methods = useForm();

const fetchShippingCountries = async (checkoutTokenId) => { const { countries } = await commerce.services.localeListShippingCountries(checkoutTokenId);

console.log(countries);
setShippingCountries(countries);
setShippingCountry(Object.keys(countries)[0]);

};

const fetchSubdivisions = async (countryCode) => { const { subdivisions } = await commerce.services.localeListSubdivisions(countryCode);

setShippingSubdivisions(subdivisions);
setShippingSubdivision(Object.keys(subdivisions)[0]);

};

// const fetchShippingOptions = async (checkoutTokenId, country, stateProvince = null) => { // const options = await commerce.checkout.getShippingOptions(checkoutTokenId, { country, region: stateProvince });

// setShippingOptions(options); // setShippingOption(options[0].id); // };

useEffect(() => {
fetchShippingCountries(checkoutToken.id);

}, []);

useEffect(() => { if (shippingCountry) fetchSubdivisions(shippingCountry); }, [shippingCountry]);

// useEffect(() => { // if (shippingSubdivision) fetchShippingOptions(checkoutToken.id, shippingCountry, shippingSubdivision); // }, [shippingSubdivision]);

return (
    <>
        <Typography variant="h6" gutterBottom>Shipping Address</Typography>
        <FormProvider {...methods}>
            <form>
                <Grid container spacing={3}>
                <FormInput required name="firstName" label="First name" />
                <FormInput required name="lastName" label="Last name" />
                <FormInput required name="address1" label="Address line 1" />
                <FormInput required name="email" label="Email" />
                <FormInput required name="city" label="City" />
                <FormInput required name="zip" label="Zip / Postal code" />
                <Grid item xs={12} sm={6}>

                   <InputLabel>Shipping Country</InputLabel>
                  <Select value={shippingCountry} fullWidth onChange={(e) => setShippingCountry(e.target.value)}>
                  {Object.entries(shippingCountries).map(([code, name]) => ({ id: code, label: name })).map((item) => (
                  <MenuItem key={item.id} value={item.id}>
                  {item.label}
                  </MenuItem>
                   ))}
                  </Select>
                  </Grid>

                <Grid item xs={12} sm={6}>
                <InputLabel>Shipping Subdivision</InputLabel>
                <Select value={shippingSubdivision} fullWidth onChange={(e) => setShippingSubdivision(e.target.value)}>
                    {Object.entries(shippingSubdivisions).map(([code, name]) => ({ id: code, label: name })).map((item) => (
                    <MenuItem key={item.id} value={item.id}>
                        {item.label}
                    </MenuItem>
                    ))}
                </Select>
                </Grid>

                
        {/* <Grid item xs={12} sm={6}>
          <InputLabel>Shipping Options</InputLabel>
          <Select value={shippingOption} fullWidth onChange={(e) => setShippingOption(e.target.value)}>
            {shippingOptions.map((sO) => ({ id: sO.id, label: `${sO.description} - (${sO.price.formatted_with_symbol})` })).map((item) => (
              <MenuItem key={item.id} value={item.id}>
                {item.label}
              </MenuItem>
            ))}
          </Select>
        </Grid> */}
      </Grid>
      <br />
      {/* <div style={{ display: 'flex', justifyContent: 'space-between' }}>
        <Button component={Link} variant="outlined" to="/cart">Back to Cart</Button>
        <Button type="submit" variant="contained" color="primary">Next</Button>
      </div> */}
    </form>
  </FormProvider>
</>

); };

export default AddressForm;

Checkout

import React, { useState, useEffect } from 'react' import { Paper, Stepper, Step, StepLabel, Typography, CircularProgress, Divider, Button } from '@material-ui/core';

import { commerce } from '../../../lib/commerce'; import useStyles from './styles'; import AddressForm from '../AddressForm'; import PaymentForm from '../PaymentForm';

const steps = ['Shipping address', 'Payment details'];

const Checkout = ({ cart }) => { const [activeStep, setActiveStep] = useState(0); const [checkoutToken, setCheckoutToken] = useState(null); const classes = useStyles();

useEffect(() => {
    const generateToken = async () => {
        try {
            const token = await commerce.checkout.generateToken(cart.id, {type: 'cart'});

            console.log(token);

            setCheckoutToken(token);
        } catch (error) {
            
        }
    }

    generateToken();
}, [cart]);

const Confirmation = () => (
    <div>
        Confirmation
    </div>
);

const Form = () => activeStep === 0
    ? <AddressForm checkoutToken={checkoutToken}/>
    : <PaymentForm />

return (
    <>

  <div className={classes.toolbar} />
  <main className={classes.layout}>
    <Paper className={classes.paper}>
      <Typography variant="h4" align="center">Checkout</Typography>
      <Stepper activeStep={activeStep} className={classes.stepper}>
        {steps.map((label) => (
          <Step key={label}>
            <StepLabel>{label}</StepLabel>
          </Step>
        ))}
      </Stepper>
      {activeStep === steps.length ? <Confirmation /> : checkoutToken && <Form />}
    </Paper>
  </main>
    </>
)

}

export default Checkout

KBCodes2021 avatar Jan 11 '22 06:01 KBCodes2021

I am stuck at the countries section, where I am getting an empty array. did you the list countries ?

shvkumar7777 avatar Jan 27 '22 16:01 shvkumar7777

For anyone new who got stuck, It looks like the error is coming from the commerce js company/webiste themselves as localeListShippingCountries is not working at all but it could be replaced with localeListCountries to display the countries but this function will list all of the countries that's in their website, not the one that you selected, not shipping countries that you want and getShippingOptions is not working at all

thiernoa98 avatar Dec 12 '22 20:12 thiernoa98

In Address form i am getting error "methods" is not defined please help me someone

i have installed same all pkg

surendra-sketch avatar Oct 31 '23 07:10 surendra-sketch