Skip to content

Commit

Permalink
feat: move functionalities to store
Browse files Browse the repository at this point in the history
  • Loading branch information
Ako committed Dec 21, 2022
1 parent c08d614 commit 596c97d
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 148 deletions.
17 changes: 2 additions & 15 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,9 @@
import React from "react";
import CountryList from "./Components/CountryList";
import PaymentMethodStore from "./store/PaymentMethod.store";
const PMStore = new PaymentMethodStore()
import {StoreProvider} from "./store/helpers";

const App = () => {
const websocket = React.useRef<WebSocket>();
React.useEffect(() => {
if (
!websocket?.current &&
![0, 1].includes(websocket?.current?.readyState || 3)
) {
websocket.current = new WebSocket(
"wss://ws.binaryws.com/websockets/v3?app_id=1089"
);
}
}, []);
return <StoreProvider store={PMStore}><CountryList websocket={websocket} /></StoreProvider>;
const App = ({store}: { store: PaymentMethodStore }) => {
return <CountryList store={store}/>;
};

export default App;
196 changes: 86 additions & 110 deletions src/Components/CountryList.tsx
Original file line number Diff line number Diff line change
@@ -1,120 +1,96 @@
import React, { useCallback, useEffect, useState } from "react";
import { IPaymentMethod, IResidenceItem } from "./types";
import {useStore} from "../store/helpers";
import React from "react";
import PaymentMethodStore from "../store/PaymentMethod.store";
import {WSHelpers} from "../store/helpers";
import {observer} from "mobx-react-lite";

type TCountryListProps = {
websocket: React.MutableRefObject<WebSocket | undefined>;

store: PaymentMethodStore
};

const CountryList = ({ websocket, }: TCountryListProps) => {
const store = useStore();

console.log("countryList", store.selectedCountry)
const [selected_country, setSelectedCountry] =
useState<IResidenceItem["value"]>("");
const [countries, setCountries] = useState<IResidenceItem[]>([]);
const [payment_methods, setPaymentMethods] = useState<IPaymentMethod[]>([]);

const send = useCallback(
(message: object) => {
if (websocket.current?.readyState === 1) {
websocket?.current?.send(JSON.stringify(message));
}
},
[websocket]
);

useEffect(() => {
websocket.current?.addEventListener("open", () => {
send({ residence_list: 1 });
});
const CountryList = ({store}: TCountryListProps) => {
const {
updatePaymentMethods,
updateCountryList,
toggleLoading,
updateSelectedCountry,
resetPaymentMethods,
resetSelectedCountry,
countryListStore,
selectedCountry,
loading,
paymentMethods
} = store;

websocket.current?.addEventListener("message", (message) => {
const data = JSON.parse(message.data);
const {
send
} = WSHelpers(updatePaymentMethods, updateCountryList, toggleLoading)

switch (data.msg_type) {
case "residence_list":
setCountries(data?.residence_list);
break;
case "payment_methods":
setPaymentMethods(data?.payment_methods);
break;
}
});

return () => {
if ([0, 1].includes(websocket?.current?.readyState || 3)) {
websocket?.current?.close();
}
const onGetListClicked = () => {
if (selectedCountry.value !== "") {
send({
payment_methods: 1,
country: selectedCountry.value,
});
}
};
const onClearClicked = () => {
resetPaymentMethods();
resetSelectedCountry()
};
}, []);

const onGetListClicked = () => {
if (selected_country !== "") {
send({
payment_methods: 1,
country: selected_country,
});
}
};

const onClearClicked = () => {
setSelectedCountry("");
setPaymentMethods([])
};

return (
<article>
<section>
<select
className=""
data-testid="country-dropdown"
value={selected_country}
onChange={(e) => {
setSelectedCountry(e.target.value);
}}
>
<option value="" disabled>
Please select a country
</option>
{countries.map((c) => {
return (
<option key={c?.text} value={c?.value}>
{`${c?.text} - ${c?.value}`}
</option>
);
})}
</select>
<button onClick={onGetListClicked}>Get List</button>
<button onClick={onClearClicked} disabled={!selected_country}>
Clear
</button>
</section>
{payment_methods.length ? (
<section>
<table>
<thead>
<tr>
<th>Display Name</th>
<th>Supported Currencies</th>
<th>Description</th>
</tr>
</thead>
<tbody data-testid="table-body">
{payment_methods?.map((item) => (
<tr key={item.id}>
<td>{item?.display_name}</td>
<td>{item?.supported_currencies?.join(",")}</td>
<td>{item?.description}</td>
</tr>
))}
</tbody>
</table>
</section>
) : null}
</article>
);
return (
<article>
<section>
{loading && <div className="loading">Loading&#8230;</div>}
<select
className=""
data-testid="country-dropdown"
value={selectedCountry.value}
onChange={(e) => {
const item = countryListStore.find(item => item.value === e.target.value)!!
updateSelectedCountry(item)
}}
>
<option value="" disabled>
Please select a country
</option>
{store?.countryListStore?.map((c) => {
return (
<option key={c?.text} value={c?.value}>
{`${c?.text} - ${c?.value}`}
</option>
);
})}
</select>
<button onClick={onGetListClicked} disabled={!selectedCountry.text}>Get List</button>
<button onClick={onClearClicked} disabled={!selectedCountry.text}>
Clear
</button>
</section>
{paymentMethods.length ? (
<section>
<table>
<thead>
<tr>
<th>Display Name</th>
<th>Supported Currencies</th>
<th>Description</th>
</tr>
</thead>
<tbody data-testid="table-body">
{store?.paymentMethods?.map((item) => (
<tr key={item.id}>
<td>{item?.display_name}</td>
<td>{item?.supported_currencies?.join(",")}</td>
<td>{item?.description}</td>
</tr>
))}
</tbody>
</table>
</section>
) : null}
</article>
);
};

export default CountryList;
export default observer(CountryList);
12 changes: 9 additions & 3 deletions src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import './index.css'
import PaymentMethodStore from "./store/PaymentMethod.store";
import {observer} from "mobx-react";

const store = new PaymentMethodStore();
const AppWithStore = observer(({store}: { store: PaymentMethodStore }) => <App store={store}/>)

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<React.StrictMode>
<App />
</React.StrictMode>,
<React.StrictMode>
<AppWithStore store={store}/>
</React.StrictMode>,
)
30 changes: 20 additions & 10 deletions src/store/PaymentMethod.store.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,38 @@
import React from "react";
import { makeAutoObservable } from "mobx";
import {makeAutoObservable} from "mobx";
import {IPaymentMethod, IResidenceItem} from "../Components/types";
const selectedCountryInitValue = {text:"", value:"",phone_idd:""}
// Model the application state.

const selectedCountryInitValue = {text: "", value: "", phone_idd: ""}

class PaymentMethodStore {
countryList: IResidenceItem[] = [];
countryListStore: IResidenceItem[] = [];
paymentMethods: IPaymentMethod[] = [];
selectedCountry: IResidenceItem = selectedCountryInitValue
loading = false;
constructor() {
makeAutoObservable(this);
}

updateCountryList() {
// get the data from ws and put it to
this.countryList = []
toggleLoading = () => {
this.loading = !this.loading;
}
getPaymentMethods(){

updatePaymentMethods = (pms: IPaymentMethod[]) => {
this.paymentMethods = pms
}
updateSelectedCountry = (residence: IResidenceItem) => {
this.selectedCountry = residence
}
updateCountryList = (countryList: IResidenceItem[]) => {
this.countryListStore = countryList
}

resetPaymentMethods() {
this.paymentMethods = [];
}
resetSelectedCountry(){

resetSelectedCountry() {
this.selectedCountry = selectedCountryInitValue
}
}

export default PaymentMethodStore
57 changes: 47 additions & 10 deletions src/store/helpers.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,52 @@
import React from "react";
import PaymentMethodStore from "./PaymentMethod.store";
import React, {useCallback, useEffect, useRef} from "react";
import {IPaymentMethod, IResidenceItem} from "../Components/types";

const StoreContext = React.createContext<PaymentMethodStore>({} as PaymentMethodStore);
export const WSHelpers = (setPaymentMethods: { (pms: IPaymentMethod[]): void; (arg0: any): void; }, setCountries: { (countryList: IResidenceItem[]): void; (arg0: any): void; }, toggleLoading: { (): void; (): void; }) => {
const websocket = useRef<WebSocket>();
useEffect(() => {
websocket?.current?.addEventListener("open", () => {
send({residence_list: 1});
});

export const StoreProvider = ({ children, store }:{children: React.ReactNode, store: PaymentMethodStore}) => {
return (
<StoreContext.Provider value={store}>{children}</StoreContext.Provider>
);
};
websocket.current?.addEventListener("message", (message) => {
const data = JSON.parse(message.data);
toggleLoading()
switch (data.msg_type) {
case "residence_list":
setCountries(data?.residence_list);
break;
case "payment_methods":
setPaymentMethods(data?.payment_methods);
break;
}
});

/* Hook to use store in any functional component */
export const useStore = (): PaymentMethodStore => React.useContext(StoreContext);
return () => {
if ([0, 1].includes(websocket?.current?.readyState || 3)) {
websocket?.current?.close();
}
};
}, []);

React.useEffect(() => {
if (
!websocket?.current &&
![0, 1].includes(websocket?.current?.readyState || 3)
) {
websocket.current = new WebSocket(
"wss://ws.binaryws.com/websockets/v3?app_id=1089"
);
}
}, []);
const send = useCallback(
(message: object) => {
toggleLoading()

if (websocket?.current?.readyState === 1) {
websocket?.current?.send(JSON.stringify(message));
}
},
[websocket]
);
return {send}
}

0 comments on commit 596c97d

Please sign in to comment.