Skip to content

Instantly share code, notes, and snippets.

@kevinold
Created March 12, 2020 23:05
Show Gist options
  • Save kevinold/ded4e827b4b7c5236b5a34fdf5d67067 to your computer and use it in GitHub Desktop.
Save kevinold/ded4e827b4b7c5236b5a34fdf5d67067 to your computer and use it in GitHub Desktop.
import { omit } from "lodash/fp";
import { Machine, assign } from "xstate";
import { dataMachine } from "./dataMachine";
import { httpClient } from "../utils/asyncUtils";
import { User } from "../models";
export interface CreateTransactionMachineSchema {
states: {
stepOne: {};
stepTwo: {};
done: {};
};
}
/*const transactionDataMachine = dataMachine("transactionData").withConfig({
services: {
createData: async (ctx, event: any) => {
const payload = omit("type", event);
const resp = await httpClient.post(
`http://localhost:3001/transactions`,
payload
);
return resp.data;
}
}
});*/
export type CreateTransactionMachineEvents =
| { type: "SET_USERS" }
| { type: "COMPLETE" };
export interface CreateTransactionMachineContext {
sender: User;
receiver: User;
}
export const createTransactionMachine = Machine<
CreateTransactionMachineContext,
CreateTransactionMachineSchema,
CreateTransactionMachineEvents
>(
{
id: "createTransaction",
initial: "stepOne",
states: {
stepOne: {
on: {
SET_USERS: "stepTwo"
}
},
stepTwo: {
entry: "setSenderAndReceiver",
on: {
COMPLETE: "done"
}
},
done: {
type: "final"
}
}
},
{
actions: {
setSenderAndReceiver: assign((ctx, event: any) => ({
sender: event.sender,
receiver: event.receiver
}))
}
}
);
import React, { useState, useEffect } from "react";
import { connect } from "react-redux";
import { IRootReducerState } from "../reducers";
import { User, TransactionPayload } from "../models";
import TransactionCreateStepOne from "../components/TransactionCreateStepOne";
import TransactionCreateStepTwo from "../components/TransactionCreateStepTwo";
import { usersSearchPending } from "../actions/users";
import { useMachine } from "@xstate/react";
import { createTransactionMachine } from "../machines/createTransactionMachine";
export interface LocalProps {
showSnackbar: Function;
sender: User;
}
export interface DispatchProps {
userListSearch: (payload: object) => void;
}
export interface StateProps {
searchUsers: User[];
allUsers: User[];
}
export type TransactionCreateContainerProps = LocalProps &
StateProps &
DispatchProps;
const TransactionCreateContainer: React.FC<TransactionCreateContainerProps> = ({
allUsers,
searchUsers,
sender,
userListSearch,
showSnackbar
}) => {
const [
createTransactionState,
sendCreateTransaction,
createTransactionService
] = useMachine(createTransactionMachine, {
devTools: true
});
useEffect(() => {
const subscription = createTransactionService.subscribe(state => {
// simple state logging
console.log(state);
});
return subscription.unsubscribe;
}, [createTransactionService]);
const setReceiver = (receiver: User) => {
sendCreateTransaction("SET_USERS", { sender, receiver });
};
const createTransaction = (payload: TransactionPayload) => {
sendCreateTransaction("COMPLETE");
//sendCreateTransaction("CREATE", payload);
};
return (
<>
{createTransactionState.matches("stepOne") && (
<TransactionCreateStepOne
allUsers={allUsers}
searchUsers={searchUsers}
setReceiver={setReceiver}
userListSearch={userListSearch}
/>
)}
{createTransactionState.matches("stepTwo") && (
<TransactionCreateStepTwo
receiver={createTransactionState.context.receiver}
sender={sender}
createTransaction={createTransaction}
showSnackbar={showSnackbar}
/>
)}
</>
);
};
const mapStateToProps = (state: IRootReducerState) => ({
searchUsers: state.users.search,
allUsers: state.users.all
});
const mapDispatchToProps = {
userListSearch: usersSearchPending
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(TransactionCreateContainer);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment