mirror of
https://github.com/jlengrand/adyen-web-demo.git
synced 2026-03-10 08:01:24 +00:00
content
This commit is contained in:
@@ -1,11 +1,9 @@
|
||||
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
||||
import type { OnDeckState } from '../types';
|
||||
|
||||
|
||||
const initialState: OnDeckState = {
|
||||
profile: {
|
||||
name: '',
|
||||
product: ''
|
||||
product: 'dropin'
|
||||
},
|
||||
checkout: {},
|
||||
local: {},
|
||||
@@ -30,9 +28,9 @@ export const onDeckSlice = createSlice({
|
||||
updateSessionsInfo: (state, action: PayloadAction<OnDeckState>) => {
|
||||
return { ...state, sessions: action.payload };
|
||||
},
|
||||
updateRedirectInfo: (state, action: PayloadAction<any>) => {
|
||||
updateRedirectInfo: (state, action: PayloadAction<any>) => {
|
||||
return { ...state, isRedirect: action.payload };
|
||||
},
|
||||
},
|
||||
clearOnDeckInfo: state => {
|
||||
return initialState;
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ import { CheckoutBuilder, PaymentsForm, ComponentBase } from '.';
|
||||
const ApplicationRouter = () => {
|
||||
return (
|
||||
<Routes>
|
||||
<Route path="/checkout-builder" element={<CheckoutBuilder />} />
|
||||
<Route path="/checkout-builder/:component" element={<ComponentBase />} />
|
||||
<Route path="/" element={<CheckoutBuilder />} />
|
||||
<Route path="/:component" element={<ComponentBase />} />
|
||||
</Routes>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -5,14 +5,8 @@ import { Editor } from './configSteps/Editor';
|
||||
import type { ConfigPropTypes, UpdateConfig } from './types';
|
||||
import { Content } from './configSteps/Content';
|
||||
|
||||
const content = {
|
||||
title: 'Profile',
|
||||
version: 'Web Components/Drop-in v5.19.0',
|
||||
description:
|
||||
'The SDK instance accepts parameters related to itself. You must set global or component-specific configuration either on the locally on the main instance, globally through the AdyenCheckout , or in API request. Create and store a configuration profile for future use.'
|
||||
};
|
||||
|
||||
export const Config = ({ configuration, descriptors, step, setActiveStep, action, updateStore }: ConfigPropTypes) => {
|
||||
export const Config = ({ configuration, descriptors, step, setActiveStep, action, updateStore, content }: ConfigPropTypes) => {
|
||||
const { profilePageContent } = content;
|
||||
const handleUpdateConfig: UpdateConfig = (item, value, current): void => {
|
||||
let newConfig = { ...configuration };
|
||||
|
||||
@@ -33,20 +27,8 @@ export const Config = ({ configuration, descriptors, step, setActiveStep, action
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<Content title={content.title} version={content.version} description={content.description} />
|
||||
<Grid mt={2} container>
|
||||
<Grid item xs={8}>
|
||||
<Typography pb={2} variant="body1" gutterBottom>
|
||||
Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec velit neque, auctor sit amet aliquam vel,
|
||||
ullamcorper sit amet ligula. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Pellentesque in ipsum id orci porta
|
||||
dapibus.
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={8}>
|
||||
<Typography variant="overline" gutterBottom>
|
||||
<Box sx={{ fontSize: 16, fontWeight: 'medium' }}>Parameters</Box>
|
||||
</Typography>
|
||||
<Divider />
|
||||
</Grid>
|
||||
<Grid item xs={8}>
|
||||
<ListOptions descriptors={descriptors} configuration={configuration} handleUpdateConfig={handleUpdateConfig} />
|
||||
</Grid>
|
||||
@@ -63,7 +45,9 @@ export const Config = ({ configuration, descriptors, step, setActiveStep, action
|
||||
<Grid item xs={1}>
|
||||
<Grid p={1} sx={{ height: '100%' }} direction="row" container justifyContent="space-between" alignItems="flex-end">
|
||||
<Grid item>
|
||||
<Button sx={{bgcolor:'#0abf53'}} variant="contained">Edit</Button>
|
||||
<Button sx={{ bgcolor: '#0abf53' }} variant="contained">
|
||||
Edit
|
||||
</Button>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<NavButtons step={step} setActiveStep={setActiveStep} configuration={configuration} />
|
||||
|
||||
@@ -10,6 +10,7 @@ import type { ActionCreatorWithPayload } from '@reduxjs/toolkit';
|
||||
import { useState } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { onDeckActions } from '../../app';
|
||||
import content from '../../helpers/content.json';
|
||||
import { useAppDispatch, useRedirect } from '../../hooks';
|
||||
import type { RootState } from '../../store';
|
||||
import { Config } from './Config';
|
||||
@@ -23,11 +24,12 @@ const ColorlibStepIconRoot = styled('div')<{
|
||||
}>(({ theme, ownerState }) => ({
|
||||
color: theme.palette.grey[700],
|
||||
zIndex: 1,
|
||||
width: 50,
|
||||
height: 50,
|
||||
display: 'flex',
|
||||
borderRadius: '50%',
|
||||
justifyContent: 'center',
|
||||
padding:0,
|
||||
margin:0,
|
||||
alignItems: 'center',
|
||||
...((ownerState.active || ownerState.completed) && {
|
||||
color: '#0066ff'
|
||||
@@ -36,7 +38,10 @@ const ColorlibStepIconRoot = styled('div')<{
|
||||
|
||||
export const ConfigWrapper = () => {
|
||||
const descriptors = useSelector((state: RootState) => state.descriptors);
|
||||
|
||||
const [activeStep, setActiveStep] = useState(0);
|
||||
const steps = ['Profile', 'Global', 'Component', 'API', 'Review'];
|
||||
let displayStep;
|
||||
|
||||
const { profile, checkout, local, sessions } = useSelector((state: RootState) => state.onDeck);
|
||||
useRedirect({ profile, checkout, local, sessions }, setActiveStep);
|
||||
@@ -45,8 +50,7 @@ export const ConfigWrapper = () => {
|
||||
dispatch(action(value));
|
||||
};
|
||||
|
||||
const steps = ['Profile', 'Global', 'Component', 'API', 'Review'];
|
||||
let displayStep;
|
||||
const { profilePageContent, globalPageContent, localPageContent, apiPageContent, reviewPageContent }: any = content;
|
||||
|
||||
console.log('STORE', JSON.stringify({ profile, checkout, local, sessions }));
|
||||
|
||||
@@ -60,6 +64,7 @@ export const ConfigWrapper = () => {
|
||||
setActiveStep={setActiveStep}
|
||||
action={updateProfileInfo}
|
||||
updateStore={updateStore}
|
||||
content={profilePageContent}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
@@ -73,6 +78,7 @@ export const ConfigWrapper = () => {
|
||||
setActiveStep={setActiveStep}
|
||||
action={updateCheckoutInfo}
|
||||
updateStore={updateStore}
|
||||
content={globalPageContent}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
@@ -86,6 +92,7 @@ export const ConfigWrapper = () => {
|
||||
setActiveStep={setActiveStep}
|
||||
action={updateLocalInfo}
|
||||
updateStore={updateStore}
|
||||
content={localPageContent}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
@@ -99,11 +106,20 @@ export const ConfigWrapper = () => {
|
||||
setActiveStep={setActiveStep}
|
||||
action={updateSessionsInfo}
|
||||
updateStore={updateStore}
|
||||
content={apiPageContent}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
case 4:
|
||||
displayStep = <ReviewForm key="review" step={activeStep} setActiveStep={setActiveStep} configuration={{ checkout, local, sessions }} />;
|
||||
displayStep = (
|
||||
<ReviewForm
|
||||
key="review"
|
||||
step={activeStep}
|
||||
setActiveStep={setActiveStep}
|
||||
configuration={{ checkout, local, sessions }}
|
||||
content={reviewPageContent}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
case 5:
|
||||
displayStep = (
|
||||
@@ -135,17 +151,17 @@ export const ConfigWrapper = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid container>
|
||||
<Grid item xs={9} mt={2}>
|
||||
<Stepper activeStep={activeStep} sx={{ pt: 3, pb: 5 }}>
|
||||
<Grid justifyContent="center" container>
|
||||
<Grid item xs={6} mt={4} mb={4}>
|
||||
<Stepper activeStep={activeStep}>
|
||||
{steps.map(label => (
|
||||
<Step key={label}>
|
||||
<StepLabel StepIconComponent={ColorlibStepIcon}/>
|
||||
<StepLabel StepIconComponent={ColorlibStepIcon} />
|
||||
</Step>
|
||||
))}
|
||||
</Stepper>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Grid item xs={8}>
|
||||
{displayStep}
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
@@ -10,35 +10,35 @@ interface ContentProps {
|
||||
export const Content = ({ title, version, description }: ContentProps) => {
|
||||
return (
|
||||
<Grid spacing={1} mt={2} container>
|
||||
<Grid item xs={9}>
|
||||
<Grid item xs={12}>
|
||||
<Typography
|
||||
component={'span'}
|
||||
p={0.7}
|
||||
sx={{ bgcolor: '#e6f8ed', borderColor: '#cef2dd', color: '#055f29', borderRadius: '5px' }}
|
||||
variant="h6"
|
||||
>
|
||||
SDK Builder
|
||||
SDK Explorer
|
||||
</Typography>
|
||||
<Typography component={'span'} p={0.7} variant="h5">
|
||||
{title}
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={9}>
|
||||
<Grid item xs={12}>
|
||||
<Typography component={'span'} p={0.7} variant="caption">
|
||||
{version}
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={9}>
|
||||
<Grid item xs={12}>
|
||||
<Typography mt={2} mb={3} variant="body2" gutterBottom>
|
||||
{description}
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={9}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="h4" gutterBottom>
|
||||
<Box>Parameters</Box>
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid pb={2} item xs={9}>
|
||||
<Grid pb={2} item xs={12}>
|
||||
<Divider />
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
@@ -50,7 +50,7 @@ export const NavButtons = ({ step, setActiveStep, configuration }: NavButtonsPro
|
||||
</Button>
|
||||
)}
|
||||
<Button variant="contained" onClick={handleNext}>
|
||||
{step === 4 ? 'Save Checkout' : 'Next'}
|
||||
{step === 4 ? 'Export' : 'Next'}
|
||||
</Button>
|
||||
</Box>
|
||||
);
|
||||
|
||||
@@ -13,16 +13,11 @@ interface ProfileFormProps {
|
||||
action: any;
|
||||
updateStore: (value: any, action: ActionCreatorWithPayload<any>) => void;
|
||||
setActiveStep: (step: number) => void;
|
||||
content: any;
|
||||
}
|
||||
|
||||
const content = {
|
||||
title: 'Profile',
|
||||
version: 'Web Components/Drop-in v5.19.0',
|
||||
description:
|
||||
'The SDK instance accepts parameters related to itself. You must set global or component-specific configuration either on the locally on the main instance, globally through the AdyenCheckout , or in API request. Create and store a configuration profile for future use.'
|
||||
};
|
||||
|
||||
export const ProfileForm = ({ configuration, step, setActiveStep, action, updateStore }: ProfileFormProps) => {
|
||||
export const ProfileForm = ({ configuration, step, setActiveStep, action, updateStore, content }: ProfileFormProps) => {
|
||||
const { profilePageContent } = content;
|
||||
const handleChange = (e: any) => {
|
||||
updateStore({ [e.target.name]: e.target.value }, action);
|
||||
};
|
||||
@@ -31,6 +26,8 @@ export const ProfileForm = ({ configuration, step, setActiveStep, action, update
|
||||
<Fragment>
|
||||
<Content title={content.title} version={content.version} description={content.description} />
|
||||
<Grid spacing={1} mt={2} container>
|
||||
{/*
|
||||
Commented out until we can begin to store config profiles in backend
|
||||
<Grid item xs={7}>
|
||||
<TextField
|
||||
sx={{ borderRadius: '0' }}
|
||||
@@ -42,8 +39,8 @@ export const ProfileForm = ({ configuration, step, setActiveStep, action, update
|
||||
onChange={handleChange}
|
||||
/>
|
||||
<FormHelperText>Required</FormHelperText>
|
||||
</Grid>
|
||||
<Grid item xs={7}>
|
||||
</Grid> */}
|
||||
<Grid item xs={8}>
|
||||
<FormControl fullWidth>
|
||||
<InputLabel>Product</InputLabel>
|
||||
<Select
|
||||
@@ -54,28 +51,29 @@ export const ProfileForm = ({ configuration, step, setActiveStep, action, update
|
||||
value={configuration.product}
|
||||
onChange={handleChange}
|
||||
label="Product"
|
||||
defaultValue="dropin"
|
||||
>
|
||||
<MenuItem value={'dropin'}>dropin</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
<FormHelperText>Required</FormHelperText>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid
|
||||
direction="column"
|
||||
justifyContent="space-between"
|
||||
alignItems="stretch"
|
||||
container
|
||||
sx={{ position: 'fixed', top: 0, right: 0, height: '100vh', bgcolor: 'secondary.main', width: '28%' }}
|
||||
>
|
||||
<Grid item xs={10} sx={{ height: '90%' }}>
|
||||
<JSONInput viewOnly={true} placeholder={configuration} colors={dark_vscode_tribute} locale={localeEn} height="100%" width="100%" />
|
||||
</Grid>
|
||||
<Grid item xs={1}>
|
||||
<Grid p={1} sx={{ height: '100%' }} direction="row" container justifyContent="flex-end" alignItems="flex-end">
|
||||
<Grid item>
|
||||
<NavButtons step={step} setActiveStep={setActiveStep} configuration={configuration} />
|
||||
<Grid item xs={4}>
|
||||
<Grid
|
||||
direction="column"
|
||||
justifyContent="space-between"
|
||||
alignItems="stretch"
|
||||
container
|
||||
sx={{ position: 'fixed', top: 0, right: 0, height: '100vh', bgcolor: 'secondary.main', width: '28%' }}
|
||||
>
|
||||
<Grid item xs={10} sx={{ height: '90%' }}>
|
||||
<JSONInput viewOnly={true} placeholder={configuration} colors={dark_vscode_tribute} locale={localeEn} height="100%" width="100%" />
|
||||
</Grid>
|
||||
<Grid item xs={1}>
|
||||
<Grid p={1} sx={{ height: '100%' }} direction="row" container justifyContent="flex-end" alignItems="flex-end">
|
||||
<Grid item>
|
||||
<NavButtons step={step} setActiveStep={setActiveStep} configuration={configuration} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
import { Grid, Box, Divider, Button } from '@mui/material';
|
||||
import { Grid } from '@mui/material';
|
||||
import React from 'react';
|
||||
import JSONInput from 'react-json-editor-ajrm';
|
||||
import { dark_vscode_tribute, localeEn } from '../../../helpers/jsonEditor';
|
||||
import ComponentBase from '../../ComponentBase/ComponentBase';
|
||||
import { Content } from './Content';
|
||||
import { NavButtons } from './NavButtons';
|
||||
import React from 'react';
|
||||
|
||||
type ReviewFormProps = {
|
||||
configuration: object;
|
||||
step: number;
|
||||
setActiveStep: (step: number) => void;
|
||||
content: any;
|
||||
};
|
||||
|
||||
export const ReviewForm = ({ configuration, step, setActiveStep }: ReviewFormProps) => {
|
||||
export const ReviewForm = ({ configuration, step, setActiveStep, content }: ReviewFormProps) => {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Content title={content.title} version={content.version} description={content.description} />
|
||||
<Grid mt={2} container>
|
||||
<Grid item xs={8}>
|
||||
<ComponentBase />
|
||||
|
||||
@@ -9,6 +9,7 @@ export interface ConfigPropTypes {
|
||||
action: ActionCreatorWithPayload<any>;
|
||||
updateStore: (value: any, action: any) => void;
|
||||
setActiveStep: (step: number) => void;
|
||||
content?: any;
|
||||
}
|
||||
|
||||
export type UpdateConfig = (key: string, value: string | null, current?: any) => void;
|
||||
|
||||
27
packages/client/src/helpers/content.json
Normal file
27
packages/client/src/helpers/content.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"profilePageContent": {
|
||||
"title": "Profile",
|
||||
"version": "Web Components/Drop-in v5.19.0",
|
||||
"description": "The SDK instance accepts parameters related to itself. You must set global or component-specific configuration either locally or on the main instance, globally through the AdyenCheckout , or in API request. Build and export a configuration profile for future use."
|
||||
},
|
||||
"globalPageContent": {
|
||||
"title": "Checkout",
|
||||
"version": "Web Components/Drop-in v5.19.0",
|
||||
"description": "The SDK instance accepts parameters related to itself. You must set global or component-specific configuration either locally or on the main instance, globally through the AdyenCheckout , or in API request. Build and export a configuration profile for future use."
|
||||
},
|
||||
"localPageContent": {
|
||||
"title": "Local",
|
||||
"version": "Web Components/Drop-in v5.19.0",
|
||||
"description": "The SDK instance accepts parameters related to itself. You must set global or component-specific configuration either locally or on the main instance, globally through the AdyenCheckout , or in API request. Build and export a configuration profile for future use."
|
||||
},
|
||||
"apiPageContent": {
|
||||
"title": "API",
|
||||
"version": "Web Components/Drop-in v5.19.0",
|
||||
"description": "The SDK instance accepts parameters related to itself. You must set global or component-specific configuration either locally or on the main instance, globally through the AdyenCheckout , or in API request. Build and export a configuration profile for future use."
|
||||
},
|
||||
"reviewPageContent": {
|
||||
"title": "Review",
|
||||
"version": "Web Components/Drop-in v5.19.0",
|
||||
"description": "The SDK instance accepts parameters related to itself. You must set global or component-specific configuration either locally or on the main instance, globally through the AdyenCheckout , or in API request. Build and export a configuration profile for future use."
|
||||
}
|
||||
}
|
||||
@@ -35,7 +35,8 @@ export const isEmpty = (x: object) => {
|
||||
};
|
||||
|
||||
export const isConfigEmpty = (x: object) => {
|
||||
const emptyConfig = { profile: { name: '', product: '' }, checkout: {}, local: {}, sessions: {} };
|
||||
const defaultProduct = 'dropin';
|
||||
const emptyConfig = { profile: { product: defaultProduct }, checkout: {}, local: {}, sessions: {} };
|
||||
return deepEqual(emptyConfig, x);
|
||||
};
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ export const useInitializeSession = ({ configuration, endpoint }: { configuratio
|
||||
headers: {
|
||||
'Content-type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ ...sessions, returnUrl: `${CLIENT_URL}/checkout-builder` })
|
||||
body: JSON.stringify({ ...sessions, returnUrl: `${CLIENT_URL}/` })
|
||||
};
|
||||
const initialize: () => void = async () => {
|
||||
try {
|
||||
|
||||
@@ -21,10 +21,10 @@ app.use(function (req, res, next) {
|
||||
|
||||
const root = path.join(__dirname, '../client', 'build');
|
||||
app.use(express.static(root));
|
||||
app.get('/checkout-builder', (req, res) => {
|
||||
app.get('/', (req, res) => {
|
||||
res.sendFile('index.html', { root });
|
||||
});
|
||||
app.get('/checkout-builder/dropin', (req, res) => {
|
||||
app.get('/dropin', (req, res) => {
|
||||
res.sendFile('index.html', { root });
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user