From 9755381cb855ba35600f484710be8d7db6f8ebf8 Mon Sep 17 00:00:00 2001 From: Robert Brodie Date: Mon, 13 Nov 2023 12:40:30 -0500 Subject: [PATCH] SP-675 Update currencies and wallets display --- docs/main.js | 143 +--------------------- docs/style.css | 2 +- src/{index.html => currencies.html} | 3 +- src/currencies.js | 180 ++++++++++++++++++++++++++++ src/main.js | 143 +--------------------- docs/index.html => src/wallets.html | 3 +- src/wallets.js | 137 +++++++++++++++++++++ 7 files changed, 330 insertions(+), 281 deletions(-) rename src/{index.html => currencies.html} (91%) create mode 100644 src/currencies.js rename docs/index.html => src/wallets.html (91%) create mode 100644 src/wallets.js diff --git a/docs/main.js b/docs/main.js index 091ce70..c546207 100644 --- a/docs/main.js +++ b/docs/main.js @@ -1,95 +1,11 @@ const API_ENDPOINT = 'https://bitpay.com/supportedwallets'; -const getSupportedWallets = async () => { +export const getSupportedWallets = async () => { const res = await fetch(API_ENDPOINT); return await res.json(); }; -const createWalletTableRow = (supportedWallet) => { - const trElement = document.createElement('tr'); - const tdElement = document.createElement('td'); - const displayNameWrapper = document.createElement('div'); - const displayName = document.createElement('div'); - const avatar = document.createElement('img'); - - const trClassLists = [ - 'hover:bg-slate-200', - 'cursor-pointer', - 'transition-all', - ]; - const tdClassLists = ['whitespace-nowrap', 'p-5', 'text-sm']; - const displayNameWrapperClassLists = ['flex', 'items-center']; - const avatarClassLists = ['h-11', 'w-11']; - const displayNameClassLists = ['ml-4', 'font-medium']; - - tdElement.classList.add(...tdClassLists); - displayNameWrapper.classList.add(...displayNameWrapperClassLists); - tdElement.appendChild(displayNameWrapper); - avatar.src = supportedWallet.image; - avatar.classList.add(...avatarClassLists); - displayName.classList.add(...displayNameClassLists); - displayName.textContent = `${supportedWallet.displayName} (${supportedWallet.key})`; - displayNameWrapper.appendChild(avatar); - displayNameWrapper.appendChild(displayName); - trElement.classList.add(...trClassLists); - trElement.setAttribute('data-child-key', supportedWallet.key); - trElement.appendChild(tdElement); - - return trElement; -}; - -const createWalletCurrenciesTableRow = (walletCurrencies, walletKey) => { - const trElement = document.createElement('tr'); - const tdElement = document.createElement('td'); - const currenciesWrapper = document.createElement('div'); - const trClassLists = ['hidden', 'transition-all']; - const tdClassLists = ['whitespace-nowrap', 'p-5', 'text-sm']; - const currenciesWrapperClassLists = ['flex', 'flex-wrap', '-mx-4']; - trElement.classList.add(...trClassLists); - tdElement.classList.add(...tdClassLists); - currenciesWrapper.classList.add(...currenciesWrapperClassLists); - - walletCurrencies.forEach((currency) => { - const walletCurrencyElement = createWalletCurrency(currency); - currenciesWrapper.appendChild(walletCurrencyElement); - }); - - tdElement.appendChild(currenciesWrapper); - trElement.setAttribute('data-parent-key', walletKey); - trElement.appendChild(tdElement); - - return trElement; -}; - -const createWalletCurrency = (currency) => { - const currencyWrapper = document.createElement('div'); - const currencyCode = document.createElement('div'); - const currencyImage = document.createElement('img'); - - const currencyImageClassLists = ['w-6', 'h-6']; - const currencyCodeClassLists = ['ml-2']; - const currencyWrapperClassLists = [ - 'px-4', - 'flex', - 'items-center', - 'w-1/2', - 'sm:w-1/4', - 'md:w-1/5', - 'mb-2', - ]; - - currencyWrapper.classList.add(...currencyWrapperClassLists); - currencyCode.textContent = currency.code; - currencyCode.classList.add(...currencyCodeClassLists); - currencyImage.src = currency.image.replace('_m', ''); - currencyImage.classList.add(...currencyImageClassLists); - currencyWrapper.appendChild(currencyImage); - currencyWrapper.appendChild(currencyCode); - - return currencyWrapper; -}; - -const createErrorTemplate = () => { +export const createErrorTemplate = () => { const tableBodyError = document.querySelector('#tableBodyError'); const trElement = document.createElement('tr'); const tdElement = document.createElement('td'); @@ -100,7 +16,7 @@ const createErrorTemplate = () => { tableBodyError.appendChild(trElement); }; -const createLoadingTemplate = () => { +export const createLoadingTemplate = () => { const tableBodyLoading = document.querySelector('#tableBodyLoading'); const createLoadingRow = () => { @@ -144,7 +60,7 @@ const createLoadingTemplate = () => { }); }; -const toggleTableRows = () => { +export const toggleTableRows = () => { const parentRows = [...document.querySelectorAll('[data-child-key]')]; if (!parentRows.length) { @@ -166,54 +82,3 @@ const toggleTableRows = () => { }); }); }; - -const prepareTable = async () => { - const loadingTemplateEl = document.querySelector('#tableBodyLoading'); - const errorTemplateEl = document.querySelector('#tableBodyError'); - const bitPayWalletDisplayName = 'BitPay'; - - createLoadingTemplate(); - - try { - const { data } = await getSupportedWallets(); - const bitpayWallets = data.filter( - (wallet) => wallet.displayName === bitPayWalletDisplayName - ); - - let supportedWallets = data.filter( - (supportedWallet) => - 'displayName' in supportedWallet && - supportedWallet.displayName !== bitPayWalletDisplayName - ); - supportedWallets.sort((a, b) => - a.displayName.toLowerCase() > b.displayName.toLowerCase() ? 1 : -1 - ); - supportedWallets = [...bitpayWallets, ...supportedWallets]; - - loadingTemplateEl.remove(); - errorTemplateEl.remove(); - - const tableBody = document.querySelector('#tableBody'); - supportedWallets.forEach((supportedWallet) => { - const walletCurrencies = supportedWallet.currencies.sort((a, b) => - a.code.toLowerCase() > b.code.toLowerCase() ? 1 : -1 - ); - const walletTableRow = createWalletTableRow(supportedWallet); - const currenciesTableRow = createWalletCurrenciesTableRow( - walletCurrencies, - supportedWallet.key - ); - tableBody.appendChild(walletTableRow); - tableBody.appendChild(currenciesTableRow); - }); - - toggleTableRows(); - } catch (e) { - loadingTemplateEl.remove(); - createErrorTemplate(); - } -}; - -window.addEventListener('DOMContentLoaded', async () => { - await prepareTable(); -}); diff --git a/docs/style.css b/docs/style.css index 7507c75..540a888 100644 --- a/docs/style.css +++ b/docs/style.css @@ -1 +1 @@ -/*! tailwindcss v3.3.3 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Heebo,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.-mx-4{margin-left:-1rem;margin-right:-1rem}.mx-auto{margin-left:auto;margin-right:auto}.mb-2{margin-bottom:.5rem}.ml-2{margin-left:.5rem}.ml-4{margin-left:1rem}.flex{display:flex}.table{display:table}.hidden{display:none}.h-11{height:2.75rem}.h-4{height:1rem}.h-6{height:1.5rem}.w-1\/2{width:50%}.w-1\/3{width:33.333333%}.w-11{width:2.75rem}.w-6{width:1.5rem}.min-w-full{min-width:100%}.max-w-4xl{max-width:56rem}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.cursor-pointer{cursor:pointer}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0;border-top-width:calc(1px*(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px*var(--tw-divide-y-reverse))}.divide-gray-200>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(229 231 235/var(--tw-divide-opacity))}.divide-gray-300>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(209 213 219/var(--tw-divide-opacity))}.whitespace-nowrap{white-space:nowrap}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.border{border-width:1px}.bg-slate-100{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity))}.bg-slate-200{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.p-5{padding:1.25rem}.px-4{padding-left:1rem;padding-right:1rem}.py-10{padding-top:2.5rem;padding-bottom:2.5rem}.text-sm{font-size:.875rem;line-height:1.25rem}.font-medium{font-weight:500}.text-red-500{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity))}.shadow-sm{--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.hover\:bg-slate-200:hover{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity))}@media (min-width:640px){.sm\:w-1\/4{width:25%}}@media (min-width:768px){.md\:w-1\/5{width:20%}} \ No newline at end of file +/*! tailwindcss v3.3.3 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Heebo,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.-mx-4{margin-left:-1rem;margin-right:-1rem}.mx-auto{margin-left:auto;margin-right:auto}.mb-2{margin-bottom:.5rem}.ml-2{margin-left:.5rem}.ml-4{margin-left:1rem}.flex{display:flex}.table{display:table}.hidden{display:none}.h-11{height:2.75rem}.h-4{height:1rem}.h-6{height:1.5rem}.w-1\/2{width:50%}.w-1\/3{width:33.333333%}.w-11{width:2.75rem}.w-6{width:1.5rem}.w-full{width:100%}.min-w-full{min-width:100%}.max-w-4xl{max-width:56rem}.flex-1{flex:1 1 0%}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.cursor-pointer{cursor:pointer}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.gap-x-2{-moz-column-gap:.5rem;column-gap:.5rem}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0;border-top-width:calc(1px*(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px*var(--tw-divide-y-reverse))}.divide-gray-200>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(229 231 235/var(--tw-divide-opacity))}.divide-gray-300>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(209 213 219/var(--tw-divide-opacity))}.whitespace-nowrap{white-space:nowrap}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.border{border-width:1px}.bg-slate-100{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity))}.bg-slate-200{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.p-5{padding:1.25rem}.px-4{padding-left:1rem;padding-right:1rem}.py-10{padding-top:2.5rem;padding-bottom:2.5rem}.py-\[10px\]{padding-top:10px;padding-bottom:10px}.text-sm{font-size:.875rem;line-height:1.25rem}.font-medium{font-weight:500}.text-red-500{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity))}.shadow-sm{--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.hover\:bg-slate-200:hover{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity))}@media (min-width:640px){.sm\:w-1\/4{width:25%}}@media (min-width:768px){.md\:w-1\/5{width:20%}.md\:flex-row{flex-direction:row}} \ No newline at end of file diff --git a/src/index.html b/src/currencies.html similarity index 91% rename from src/index.html rename to src/currencies.html index 3bf0a2c..97c82b3 100644 --- a/src/index.html +++ b/src/currencies.html @@ -31,6 +31,7 @@ - + + diff --git a/src/currencies.js b/src/currencies.js new file mode 100644 index 0000000..4388255 --- /dev/null +++ b/src/currencies.js @@ -0,0 +1,180 @@ +import { + getSupportedWallets, + createErrorTemplate, + createLoadingTemplate, + toggleTableRows, +} from './main.js'; + +const createCurrencyTableRow = (currency) => { + const trElement = document.createElement('tr'); + const tdElement = document.createElement('td'); + const displayNameWrapper = document.createElement('div'); + const displayName = document.createElement('div'); + const avatar = document.createElement('img'); + + const trClassLists = [ + 'hover:bg-slate-200', + 'cursor-pointer', + 'transition-all', + ]; + const tdClassLists = ['whitespace-nowrap', 'py-[10px]', 'p-5', 'text-sm']; + const displayNameWrapperClassLists = ['flex', 'items-center']; + const avatarClassLists = ['h-11', 'w-11']; + const displayNameClassLists = ['ml-4', 'font-medium']; + + tdElement.classList.add(...tdClassLists); + displayNameWrapper.classList.add(...displayNameWrapperClassLists); + tdElement.appendChild(displayNameWrapper); + avatar.src = currency.image; + avatar.classList.add(...avatarClassLists); + + displayName.classList.add(...displayNameClassLists); + displayName.textContent = currency.code; + displayNameWrapper.appendChild(avatar); + displayNameWrapper.appendChild(displayName); + + trElement.classList.add(...trClassLists); + trElement.setAttribute('data-child-key', currency.code); + trElement.appendChild(tdElement); + + return trElement; +}; + +const createCurrencyWalletsTableRow = (wallets, currencyCode) => { + const MAX_ITEMS_WITHOUT_COLUMN_SPLIT = 8; + const trElement = document.createElement('tr'); + const tdElement = document.createElement('td'); + const walletsWrapper = document.createElement('div'); + const additionalWalletsWrapper = document.createElement('div'); + const trClassLists = ['hidden', 'transition-all']; + const tdClassLists = [ + 'whitespace-nowrap', + 'flex', + 'flex-col', + 'md:flex-row', + 'p-5', + 'gap-x-2', + 'text-sm', + ]; + const walletsWrapperClassLists = ['flex', 'flex-1', 'flex-col']; + trElement.classList.add(...trClassLists); + tdElement.classList.add(...tdClassLists); + walletsWrapper.classList.add(...walletsWrapperClassLists); + additionalWalletsWrapper.classList.add(...walletsWrapperClassLists); + + if (wallets.length > MAX_ITEMS_WITHOUT_COLUMN_SPLIT) { + wallets.forEach((wallet, index) => { + if (index >= Math.round(wallets.length / 2)) { // 2 columns + additionalWalletsWrapper.appendChild(createCurrencyWallet(wallet)); + } else { + walletsWrapper.appendChild(createCurrencyWallet(wallet)); + } + + tdElement.appendChild(walletsWrapper); + tdElement.appendChild(additionalWalletsWrapper); + trElement.setAttribute('data-parent-key', currencyCode); + trElement.appendChild(tdElement); + }); + } else { + wallets.forEach((wallet) => { + walletsWrapper.appendChild(createCurrencyWallet(wallet)); + }); + + tdElement.appendChild(walletsWrapper); + trElement.setAttribute('data-parent-key', currencyCode); + trElement.appendChild(tdElement); + } + + return trElement; +}; + +const createCurrencyWallet = (wallet) => { + const walletWrapper = document.createElement('div'); + const walletName = document.createElement('div'); + const walletImage = document.createElement('img'); + const walletImageClassLists = ['w-6', 'h-6']; + const walletNameClassLists = ['ml-2']; + const walletWrapperClassLists = ['flex', 'items-center', 'w-full', 'mb-2']; + + walletWrapper.classList.add(...walletWrapperClassLists); + walletName.textContent = wallet.name; + walletName.classList.add(...walletNameClassLists); + walletImage.src = wallet.image; + walletImage.classList.add(...walletImageClassLists); + walletWrapper.appendChild(walletImage); + walletWrapper.appendChild(walletName); + + return walletWrapper; +}; + +const prepareTable = async () => { + const loadingTemplateEl = document.querySelector('#tableBodyLoading'); + const errorTemplateEl = document.querySelector('#tableBodyError'); + const bitPayWalletDisplayName = 'BitPay'; + + createLoadingTemplate(); + + try { + const { data } = await getSupportedWallets(); + const bitpayWallets = data.filter( + (wallet) => wallet.displayName === bitPayWalletDisplayName + ); + + let supportedWallets = data.filter( + (supportedWallet) => + 'displayName' in supportedWallet && + supportedWallet.displayName !== bitPayWalletDisplayName + ); + supportedWallets.sort((a, b) => + a.displayName.toLowerCase() > b.displayName.toLowerCase() ? 1 : -1 + ); + supportedWallets = [...bitpayWallets, ...supportedWallets]; + + let currencies = {}; + + supportedWallets.forEach((supportedWallet) => { + const walletCurrencies = supportedWallet['currencies']; + return walletCurrencies.forEach((currency) => { + const currencyCode = currency.code; + + if (!currencies[currencyCode]) { + currencies[currencyCode] = {}; + } + currencies[currencyCode]['code'] = currencyCode; + currencies[currencyCode]['image'] = currency.image.replace('_m', ''); + if (!currencies[currencyCode].wallets) { + currencies[currencyCode].wallets = []; + } + + currencies[currencyCode].wallets.push({ + name: supportedWallet.displayName + ' (' + supportedWallet.key + ')', + image: supportedWallet.image, + }); + }); + }); + + loadingTemplateEl.remove(); + errorTemplateEl.remove(); + + const tableBody = document.querySelector('#tableBody'); + + Object.values(currencies).forEach((currency) => { + const currencyTableRow = createCurrencyTableRow(currency); + const walletsTableRow = createCurrencyWalletsTableRow( + currency.wallets, + currency.code + ); + tableBody.appendChild(currencyTableRow); + tableBody.appendChild(walletsTableRow); + }); + + toggleTableRows(); + } catch (e) { + loadingTemplateEl.remove(); + createErrorTemplate(); + } +}; + +window.addEventListener('DOMContentLoaded', async () => { + await prepareTable(); +}); \ No newline at end of file diff --git a/src/main.js b/src/main.js index 091ce70..c546207 100644 --- a/src/main.js +++ b/src/main.js @@ -1,95 +1,11 @@ const API_ENDPOINT = 'https://bitpay.com/supportedwallets'; -const getSupportedWallets = async () => { +export const getSupportedWallets = async () => { const res = await fetch(API_ENDPOINT); return await res.json(); }; -const createWalletTableRow = (supportedWallet) => { - const trElement = document.createElement('tr'); - const tdElement = document.createElement('td'); - const displayNameWrapper = document.createElement('div'); - const displayName = document.createElement('div'); - const avatar = document.createElement('img'); - - const trClassLists = [ - 'hover:bg-slate-200', - 'cursor-pointer', - 'transition-all', - ]; - const tdClassLists = ['whitespace-nowrap', 'p-5', 'text-sm']; - const displayNameWrapperClassLists = ['flex', 'items-center']; - const avatarClassLists = ['h-11', 'w-11']; - const displayNameClassLists = ['ml-4', 'font-medium']; - - tdElement.classList.add(...tdClassLists); - displayNameWrapper.classList.add(...displayNameWrapperClassLists); - tdElement.appendChild(displayNameWrapper); - avatar.src = supportedWallet.image; - avatar.classList.add(...avatarClassLists); - displayName.classList.add(...displayNameClassLists); - displayName.textContent = `${supportedWallet.displayName} (${supportedWallet.key})`; - displayNameWrapper.appendChild(avatar); - displayNameWrapper.appendChild(displayName); - trElement.classList.add(...trClassLists); - trElement.setAttribute('data-child-key', supportedWallet.key); - trElement.appendChild(tdElement); - - return trElement; -}; - -const createWalletCurrenciesTableRow = (walletCurrencies, walletKey) => { - const trElement = document.createElement('tr'); - const tdElement = document.createElement('td'); - const currenciesWrapper = document.createElement('div'); - const trClassLists = ['hidden', 'transition-all']; - const tdClassLists = ['whitespace-nowrap', 'p-5', 'text-sm']; - const currenciesWrapperClassLists = ['flex', 'flex-wrap', '-mx-4']; - trElement.classList.add(...trClassLists); - tdElement.classList.add(...tdClassLists); - currenciesWrapper.classList.add(...currenciesWrapperClassLists); - - walletCurrencies.forEach((currency) => { - const walletCurrencyElement = createWalletCurrency(currency); - currenciesWrapper.appendChild(walletCurrencyElement); - }); - - tdElement.appendChild(currenciesWrapper); - trElement.setAttribute('data-parent-key', walletKey); - trElement.appendChild(tdElement); - - return trElement; -}; - -const createWalletCurrency = (currency) => { - const currencyWrapper = document.createElement('div'); - const currencyCode = document.createElement('div'); - const currencyImage = document.createElement('img'); - - const currencyImageClassLists = ['w-6', 'h-6']; - const currencyCodeClassLists = ['ml-2']; - const currencyWrapperClassLists = [ - 'px-4', - 'flex', - 'items-center', - 'w-1/2', - 'sm:w-1/4', - 'md:w-1/5', - 'mb-2', - ]; - - currencyWrapper.classList.add(...currencyWrapperClassLists); - currencyCode.textContent = currency.code; - currencyCode.classList.add(...currencyCodeClassLists); - currencyImage.src = currency.image.replace('_m', ''); - currencyImage.classList.add(...currencyImageClassLists); - currencyWrapper.appendChild(currencyImage); - currencyWrapper.appendChild(currencyCode); - - return currencyWrapper; -}; - -const createErrorTemplate = () => { +export const createErrorTemplate = () => { const tableBodyError = document.querySelector('#tableBodyError'); const trElement = document.createElement('tr'); const tdElement = document.createElement('td'); @@ -100,7 +16,7 @@ const createErrorTemplate = () => { tableBodyError.appendChild(trElement); }; -const createLoadingTemplate = () => { +export const createLoadingTemplate = () => { const tableBodyLoading = document.querySelector('#tableBodyLoading'); const createLoadingRow = () => { @@ -144,7 +60,7 @@ const createLoadingTemplate = () => { }); }; -const toggleTableRows = () => { +export const toggleTableRows = () => { const parentRows = [...document.querySelectorAll('[data-child-key]')]; if (!parentRows.length) { @@ -166,54 +82,3 @@ const toggleTableRows = () => { }); }); }; - -const prepareTable = async () => { - const loadingTemplateEl = document.querySelector('#tableBodyLoading'); - const errorTemplateEl = document.querySelector('#tableBodyError'); - const bitPayWalletDisplayName = 'BitPay'; - - createLoadingTemplate(); - - try { - const { data } = await getSupportedWallets(); - const bitpayWallets = data.filter( - (wallet) => wallet.displayName === bitPayWalletDisplayName - ); - - let supportedWallets = data.filter( - (supportedWallet) => - 'displayName' in supportedWallet && - supportedWallet.displayName !== bitPayWalletDisplayName - ); - supportedWallets.sort((a, b) => - a.displayName.toLowerCase() > b.displayName.toLowerCase() ? 1 : -1 - ); - supportedWallets = [...bitpayWallets, ...supportedWallets]; - - loadingTemplateEl.remove(); - errorTemplateEl.remove(); - - const tableBody = document.querySelector('#tableBody'); - supportedWallets.forEach((supportedWallet) => { - const walletCurrencies = supportedWallet.currencies.sort((a, b) => - a.code.toLowerCase() > b.code.toLowerCase() ? 1 : -1 - ); - const walletTableRow = createWalletTableRow(supportedWallet); - const currenciesTableRow = createWalletCurrenciesTableRow( - walletCurrencies, - supportedWallet.key - ); - tableBody.appendChild(walletTableRow); - tableBody.appendChild(currenciesTableRow); - }); - - toggleTableRows(); - } catch (e) { - loadingTemplateEl.remove(); - createErrorTemplate(); - } -}; - -window.addEventListener('DOMContentLoaded', async () => { - await prepareTable(); -}); diff --git a/docs/index.html b/src/wallets.html similarity index 91% rename from docs/index.html rename to src/wallets.html index 3bf0a2c..38e60d5 100644 --- a/docs/index.html +++ b/src/wallets.html @@ -31,6 +31,7 @@ - + + diff --git a/src/wallets.js b/src/wallets.js new file mode 100644 index 0000000..52146e7 --- /dev/null +++ b/src/wallets.js @@ -0,0 +1,137 @@ +import { getSupportedWallets, createErrorTemplate, createLoadingTemplate, toggleTableRows } from './main.js'; + +const createWalletTableRow = (supportedWallet) => { + const trElement = document.createElement('tr'); + const tdElement = document.createElement('td'); + const displayNameWrapper = document.createElement('div'); + const displayName = document.createElement('div'); + const avatar = document.createElement('img'); + + const trClassLists = [ + 'hover:bg-slate-200', + 'cursor-pointer', + 'transition-all', + ]; + const tdClassLists = ['whitespace-nowrap', 'p-5', 'text-sm']; + const displayNameWrapperClassLists = ['flex', 'items-center']; + const avatarClassLists = ['h-11', 'w-11']; + const displayNameClassLists = ['ml-4', 'font-medium']; + + tdElement.classList.add(...tdClassLists); + displayNameWrapper.classList.add(...displayNameWrapperClassLists); + tdElement.appendChild(displayNameWrapper); + avatar.src = supportedWallet.image; + avatar.classList.add(...avatarClassLists); + displayName.classList.add(...displayNameClassLists); + displayName.textContent = `${supportedWallet.displayName} (${supportedWallet.key})`; + displayNameWrapper.appendChild(avatar); + displayNameWrapper.appendChild(displayName); + trElement.classList.add(...trClassLists); + trElement.setAttribute('data-child-key', supportedWallet.key); + trElement.appendChild(tdElement); + + return trElement; +}; + +const createWalletCurrenciesTableRow = (walletCurrencies, walletKey) => { + const trElement = document.createElement('tr'); + const tdElement = document.createElement('td'); + const currenciesWrapper = document.createElement('div'); + const trClassLists = ['hidden', 'transition-all']; + const tdClassLists = ['whitespace-nowrap', 'p-5', 'text-sm']; + const currenciesWrapperClassLists = ['flex', 'flex-wrap', '-mx-4']; + trElement.classList.add(...trClassLists); + tdElement.classList.add(...tdClassLists); + currenciesWrapper.classList.add(...currenciesWrapperClassLists); + + walletCurrencies.forEach((currency) => { + const walletCurrencyElement = createWalletCurrency(currency); + currenciesWrapper.appendChild(walletCurrencyElement); + }); + + tdElement.appendChild(currenciesWrapper); + trElement.setAttribute('data-parent-key', walletKey); + trElement.appendChild(tdElement); + + return trElement; +}; + +const createWalletCurrency = (currency) => { + const currencyWrapper = document.createElement('div'); + const currencyCode = document.createElement('div'); + const currencyImage = document.createElement('img'); + + const currencyImageClassLists = ['w-6', 'h-6']; + const currencyCodeClassLists = ['ml-2']; + const currencyWrapperClassLists = [ + 'px-4', + 'flex', + 'items-center', + 'w-1/2', + 'sm:w-1/4', + 'md:w-1/5', + 'mb-2', + ]; + + currencyWrapper.classList.add(...currencyWrapperClassLists); + currencyCode.textContent = currency.code; + currencyCode.classList.add(...currencyCodeClassLists); + currencyImage.src = currency.image.replace('_m', ''); + currencyImage.classList.add(...currencyImageClassLists); + currencyWrapper.appendChild(currencyImage); + currencyWrapper.appendChild(currencyCode); + + return currencyWrapper; +}; + + +const prepareTable = async () => { + const loadingTemplateEl = document.querySelector('#tableBodyLoading'); + const errorTemplateEl = document.querySelector('#tableBodyError'); + const bitPayWalletDisplayName = 'BitPay'; + + createLoadingTemplate(); + + try { + const { data } = await getSupportedWallets(); + const bitpayWallets = data.filter( + (wallet) => wallet.displayName === bitPayWalletDisplayName + ); + + let supportedWallets = data.filter( + (supportedWallet) => + 'displayName' in supportedWallet && + supportedWallet.displayName !== bitPayWalletDisplayName + ); + supportedWallets.sort((a, b) => + a.displayName.toLowerCase() > b.displayName.toLowerCase() ? 1 : -1 + ); + supportedWallets = [...bitpayWallets, ...supportedWallets]; + + loadingTemplateEl.remove(); + errorTemplateEl.remove(); + + const tableBody = document.querySelector('#tableBody'); + supportedWallets.forEach((supportedWallet) => { + const walletCurrencies = supportedWallet.currencies.sort((a, b) => + a.code.toLowerCase() > b.code.toLowerCase() ? 1 : -1 + ); + const walletTableRow = createWalletTableRow(supportedWallet); + const currenciesTableRow = createWalletCurrenciesTableRow( + walletCurrencies, + supportedWallet.key + ); + tableBody.appendChild(walletTableRow); + tableBody.appendChild(currenciesTableRow); + }); + + toggleTableRows(); + } catch (e) { + loadingTemplateEl.remove(); + createErrorTemplate(); + } +}; + +window.addEventListener('DOMContentLoaded', async () => { + await prepareTable(); +}); \ No newline at end of file