diff options
Diffstat (limited to 'packages/demobank-ui/src')
-rw-r--r-- | packages/demobank-ui/src/pages/ConversionConfig.tsx | 497 |
1 files changed, 280 insertions, 217 deletions
diff --git a/packages/demobank-ui/src/pages/ConversionConfig.tsx b/packages/demobank-ui/src/pages/ConversionConfig.tsx index efe2d1756..980faa4b0 100644 --- a/packages/demobank-ui/src/pages/ConversionConfig.tsx +++ b/packages/demobank-ui/src/pages/ConversionConfig.tsx @@ -262,6 +262,7 @@ function useComponentState({ const both_high = in_ratio > 1 && out_ratio > 1; const both_low = in_ratio < 1 && out_ratio < 1; + return ( <div> <ProfileNavigation current="conversion" @@ -282,7 +283,7 @@ function useComponentState({ <div class="px-2 mt-2 grid grid-cols-1 gap-y-4 sm:gap-x-4"> <label data-enabled={section === "detail"} - class="relative flex cursor-pointer rounded-lg border bg-white p-4 shadow-sm focus:outline-none border-gray-300 -- data-[enabled=true]:border-indigo-600 data-[enabled=true]:ring-2 data-[enabled=true]:ring-indigo-600" + class="relative flex cursor-pointer rounded-lg border bg-white p-4 shadow-sm focus:outline-none border-gray-300 data-[enabled=true]:border-indigo-600 data-[enabled=true]:ring-2 data-[enabled=true]:ring-indigo-600" > <input type="radio" @@ -362,225 +363,29 @@ function useComponentState({ e.preventDefault(); }} > - {section == "cashin" && <Fragment> - <div class="px-6 pt-6"> - <div class="grid max-w-2xl grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6"> - <div class="sm:col-span-5"> - <label - for="cashin_min_amount" - class="block text-sm font-medium leading-6 text-gray-900" - >{i18n.str`Minimum amount`}</label> - <InputAmount - name="cashin_min_amount" - left - currency={config.currency} - value={form.conv?.cashin_min_amount?.value ?? ""} - onChange={form.conv?.cashin_min_amount?.onUpdate} - /> - <ShowInputErrorLabel - message={form.conv?.cashin_min_amount?.error} - isDirty={form.conv?.cashin_min_amount?.value !== undefined} - /> - <p class="mt-2 text-sm text-gray-500"> - <i18n.Translate>Only cashout operation above this threshold will be allowed</i18n.Translate> - </p> - </div> - </div> - </div> - - <div class="px-6 pt-6"> - <div class="grid max-w-2xl grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6"> - <div class="sm:col-span-5"> - <label - for="cashin_tiny_amount" - class="block text-sm font-medium leading-6 text-gray-900" - >{i18n.str`Minimum difference`}</label> - <InputAmount - name="cashin_tiny_amount" - left - currency={config.currency} - value={form.conv?.cashin_tiny_amount?.value ?? ""} - onChange={form.conv?.cashin_tiny_amount?.onUpdate} - /> - <ShowInputErrorLabel - message={form.conv?.cashin_tiny_amount?.error} - isDirty={form.conv?.cashin_tiny_amount?.value !== undefined} - /> - <p class="mt-2 text-sm text-gray-500"> - <i18n.Translate>Smallest difference between two amounts</i18n.Translate> - </p> - </div> - </div> - </div> - - <div class="px-6 pt-6"> - <div class="grid max-w-2xl grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6"> - <div class="sm:col-span-5"> - <label - for="cashin_fee" - class="block text-sm font-medium leading-6 text-gray-900" - >{i18n.str`Fee`}</label> - <InputAmount - name="cashin_fee" - left - currency={config.currency} - value={form.conv?.cashin_fee?.value ?? ""} - onChange={form.conv?.cashin_fee?.onUpdate} - /> - <ShowInputErrorLabel - message={form.conv?.cashin_fee?.error} - isDirty={form.conv?.cashin_fee?.value !== undefined} - /> - <p class="mt-2 text-sm text-gray-500"> - <i18n.Translate>Operation fee</i18n.Translate> - </p> - </div> - </div> - </div> - - <div class="px-6 pt-6"> - <label - class="block text-sm font-medium leading-6 text-gray-900" - for="password" - > - {i18n.str`Ratio`} - </label> - <div class="mt-2"> - <input - type="number" - class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 data-[error=true]:ring-red-500 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6" - name="current" - id="cashin_ratio" - data-error={!!form.conv?.cashin_ratio?.error && form.conv?.cashin_ratio?.value !== undefined} - value={form.conv?.cashin_ratio?.value ?? ""} - onChange={(e) => { - form.conv?.cashin_ratio?.onUpdate(e.currentTarget.value); - }} - autocomplete="off" - /> - <ShowInputErrorLabel - message={form.conv?.cashin_ratio?.error} - isDirty={form.conv?.cashin_ratio?.value !== undefined} - /> - </div> - <p class="mt-2 text-sm text-gray-500"> - <i18n.Translate> - Conversion ratio between currencies - </i18n.Translate> - </p> - </div> - - </Fragment>} + {section == "cashin" && + <ConversionForm id="cashin" + inputCurrency={info.fiat_currency} + outputCurrency={info.regional_currency} + fee={form?.conv?.cashin_fee} + minimum={form?.conv?.cashin_min_amount} + ratio={form?.conv?.cashin_ratio} + rounding={form?.conv?.cashin_rounding_mode} + tiny={form?.conv?.cashin_tiny_amount} + />} {section == "cashout" && <Fragment> - <div class="px-6 pt-6"> - <div class="grid max-w-2xl grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6"> - <div class="sm:col-span-5"> - <label - for="cashout_min_amount" - class="block text-sm font-medium leading-6 text-gray-900" - >{i18n.str`Minimum amount`}</label> - <InputAmount - name="cashout_min_amount" - left - currency={config.currency} - value={form.conv?.cashout_min_amount?.value ?? ""} - onChange={form.conv?.cashout_min_amount?.onUpdate} - /> - <ShowInputErrorLabel - message={form.conv?.cashout_min_amount?.error} - isDirty={form.conv?.cashout_min_amount?.value !== undefined} - /> - <p class="mt-2 text-sm text-gray-500"> - <i18n.Translate>Only cashout operation above this threshold will be allowed</i18n.Translate> - </p> - </div> - </div> - </div> - - <div class="px-6 pt-6"> - <div class="grid max-w-2xl grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6"> - <div class="sm:col-span-5"> - <label - for="cashout_tiny_amount" - class="block text-sm font-medium leading-6 text-gray-900" - >{i18n.str`Minimum difference`}</label> - <InputAmount - name="cashout_tiny_amount" - left - currency={config.currency} - value={form.conv?.cashout_tiny_amount?.value ?? ""} - onChange={form.conv?.cashout_tiny_amount?.onUpdate} - /> - <ShowInputErrorLabel - message={form.conv?.cashout_tiny_amount?.error} - isDirty={form.conv?.cashout_tiny_amount?.value !== undefined} - /> - <p class="mt-2 text-sm text-gray-500"> - <i18n.Translate>Smallest difference between two amounts</i18n.Translate> - </p> - </div> - </div> - </div> - - <div class="px-6 pt-6"> - <div class="grid max-w-2xl grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6"> - <div class="sm:col-span-5"> - <label - for="cashout_fee" - class="block text-sm font-medium leading-6 text-gray-900" - >{i18n.str`Fee`}</label> - <InputAmount - name="cashout_fee" - left - currency={config.currency} - value={form.conv?.cashout_fee?.value ?? ""} - onChange={form.conv?.cashout_fee?.onUpdate} - /> - <ShowInputErrorLabel - message={form.conv?.cashout_fee?.error} - isDirty={form.conv?.cashout_fee?.value !== undefined} - /> - <p class="mt-2 text-sm text-gray-500"> - <i18n.Translate>Operation fee</i18n.Translate> - </p> - </div> - </div> - </div> - - <div class="px-6 pt-6"> - <label - class="block text-sm font-medium leading-6 text-gray-900" - for="password" - > - {i18n.str`Ratio`} - </label> - <div class="mt-2"> - <input - type="number" - class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 data-[error=true]:ring-red-500 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6" - name="current" - id="cashout_ratio" - data-error={!!form.conv?.cashout_ratio?.error && form.conv?.cashout_ratio?.value !== undefined} - value={form.conv?.cashout_ratio?.value ?? ""} - onChange={(e) => { - form.conv?.cashout_ratio?.onUpdate(e.currentTarget.value); - }} - autocomplete="off" - /> - <ShowInputErrorLabel - message={form.conv?.cashout_ratio?.error} - isDirty={form.conv?.cashout_ratio?.value !== undefined} - /> - </div> - <p class="mt-2 text-sm text-gray-500"> - <i18n.Translate> - Conversion ratio between currencies - </i18n.Translate> - </p> - </div> + <ConversionForm id="cashout" + inputCurrency={info.regional_currency} + outputCurrency={info.fiat_currency} + fee={form?.conv?.cashout_fee} + minimum={form?.conv?.cashout_min_amount} + ratio={form?.conv?.cashout_ratio} + rounding={form?.conv?.cashout_rounding_mode} + tiny={form?.conv?.cashout_tiny_amount} + /> </Fragment>} @@ -623,7 +428,7 @@ function useComponentState({ <label for="amount" class="block text-sm font-medium leading-6 text-gray-900" - >{i18n.str`Test amount`}</label> + >{i18n.str`Initial amount`}</label> <InputAmount name="amount" left @@ -855,3 +660,261 @@ function checkConversionForm(i18n: InternationalizationAPI, regional: string, fi } } + +function ConversionForm({ id, inputCurrency, outputCurrency, fee, minimum, ratio, rounding, tiny }: { + inputCurrency: string, + outputCurrency: string, + minimum: UIField | undefined, + tiny: UIField | undefined, + fee: UIField | undefined, + rounding: UIField | undefined, + ratio: UIField | undefined, + id: string, +}): VNode { + const { i18n } = useTranslationContext(); + return <Fragment> + <div class="px-6 pt-6"> + <div class="grid max-w-2xl grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6"> + <div class="sm:col-span-5"> + <label + for="cashin_min_amount" + class="block text-sm font-medium leading-6 text-gray-900" + >{i18n.str`Minimum amount`}</label> + <InputAmount + name="cashin_min_amount" + left + currency={inputCurrency} + value={minimum?.value ?? ""} + onChange={minimum?.onUpdate} + /> + <ShowInputErrorLabel + message={minimum?.error} + isDirty={minimum?.value !== undefined} + /> + <p class="mt-2 text-sm text-gray-500"> + <i18n.Translate>Only cashout operation above this threshold will be allowed</i18n.Translate> + </p> + </div> + </div> + </div> + + <div class="px-6 pt-6"> + <label + class="block text-sm font-medium leading-6 text-gray-900" + for="password" + > + {i18n.str`Ratio`} + </label> + <div class="mt-2"> + <input + type="number" + class="block rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 data-[error=true]:ring-red-500 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6" + name="current" + id="cashin_ratio" + data-error={!!ratio?.error && ratio?.value !== undefined} + value={ratio?.value ?? ""} + onChange={(e) => { + ratio?.onUpdate(e.currentTarget.value); + }} + autocomplete="off" + /> + <ShowInputErrorLabel + message={ratio?.error} + isDirty={ratio?.value !== undefined} + /> + </div> + <p class="mt-2 text-sm text-gray-500"> + <i18n.Translate> + Conversion ratio between currencies + </i18n.Translate> + </p> + </div> + + <div class="px-6 pt-6"> + <div class="grid max-w-2xl grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6"> + <div class="sm:col-span-5"> + <label + for="cashin_tiny_amount" + class="block text-sm font-medium leading-6 text-gray-900" + >{i18n.str`Minimum difference`}</label> + <InputAmount + name="cashin_tiny_amount" + left + currency={outputCurrency} + value={tiny?.value ?? ""} + onChange={tiny?.onUpdate} + /> + <ShowInputErrorLabel + message={tiny?.error} + isDirty={tiny?.value !== undefined} + /> + <p class="mt-2 text-sm text-gray-500"> + <i18n.Translate>Smallest difference between two amounts, values in between will be rounded.</i18n.Translate> + </p> + </div> + </div> + </div> + + + <div class="px-6 pt-6"> + <div class="grid max-w-2xl grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6"> + <div class="sm:col-span-5"> + <label + class="block text-sm font-medium leading-6 text-gray-900" + for="channel" + > + {i18n.str`Rounding mode`} + </label> + <div class="mt-2 max-w-xl text-sm text-gray-500"> + <div class="px-4 mt-4 grid grid-cols-1 gap-y-6"> + <label + onClick={(e) => { + e.preventDefault(); + rounding?.onUpdate("zero") + }} + data-selected={rounding?.value === "zero"} + class="relative flex data-[disabled=false]:cursor-pointer rounded-lg border bg-white data-[disabled=true]:bg-gray-200 p-4 shadow-sm focus:outline-none border-gray-300 data-[selected=true]:ring-2 data-[selected=true]:ring-indigo-600" + > + <input + type="radio" + name="channel" + value="Newsletter" + class="sr-only" + /> + <span class="flex flex-1"> + <span class="flex flex-col"> + <span + id="project-type-0-label" + class="block text-sm font-medium text-gray-900 " + > + <i18n.Translate>Zero</i18n.Translate> + </span> + <i18n.Translate>Amount will be round below to the largest possible value smaller than the input.</i18n.Translate> + </span> + </span> + <svg + data-selected={rounding?.value === "zero"} + class="h-5 w-5 text-indigo-600 data-[selected=false]:hidden" + viewBox="0 0 20 20" + fill="currentColor" + aria-hidden="true" + > + <path + fill-rule="evenodd" + d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z" + clip-rule="evenodd" + /> + </svg> + </label> + + <label + onClick={(e) => { + e.preventDefault(); + rounding?.onUpdate("up") + }} + data-selected={rounding?.value === "up"} + class="relative flex data-[disabled=false]:cursor-pointer rounded-lg border data-[disabled=true]:bg-gray-200 p-4 shadow-sm focus:outline-none border-gray-300 data-[selected=true]:ring-2 data-[selected=true]:ring-indigo-600" + > + <input + type="radio" + name="channel" + value="Existing Customers" + class="sr-only" + /> + <span class="flex flex-1"> + <span class="flex flex-col"> + <span + id="project-type-0-label" + class="block text-sm font-medium text-gray-900 " + > + <i18n.Translate>Up</i18n.Translate> + </span> + <i18n.Translate>Amount will be round up to the smallest possible value larger than the input.</i18n.Translate> + </span> + </span> + <svg + data-selected={rounding?.value === "up"} + class="h-5 w-5 text-indigo-600 data-[selected=false]:hidden" + viewBox="0 0 20 20" + fill="currentColor" + aria-hidden="true" + > + <path + fill-rule="evenodd" + d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z" + clip-rule="evenodd" + /> + </svg> + </label> + <label + onClick={(e) => { + e.preventDefault(); + rounding?.onUpdate("nearest") + }} + data-selected={rounding?.value === "nearest"} + class="relative flex data-[disabled=false]:cursor-pointer rounded-lg border data-[disabled=true]:bg-gray-200 p-4 shadow-sm focus:outline-none border-gray-300 data-[selected=true]:ring-2 data-[selected=true]:ring-indigo-600" + > + <input + type="radio" + name="channel" + value="Existing Customers" + class="sr-only" + /> + <span class="flex flex-1"> + <span class="flex flex-col"> + <span + id="project-type-0-label" + class="block text-sm font-medium text-gray-900 " + > + <i18n.Translate>Nearest</i18n.Translate> + </span> + <i18n.Translate>Amount will be round to the closest possible value.</i18n.Translate> + </span> + </span> + <svg + data-selected={rounding?.value === "nearest"} + class="h-5 w-5 text-indigo-600 data-[selected=false]:hidden" + viewBox="0 0 20 20" + fill="currentColor" + aria-hidden="true" + > + <path + fill-rule="evenodd" + d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z" + clip-rule="evenodd" + /> + </svg> + </label> + </div> + </div> + </div> + </div> + </div> + + <div class="px-6 pt-6"> + <div class="grid max-w-2xl grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6"> + <div class="sm:col-span-5"> + <label + for="cashin_fee" + class="block text-sm font-medium leading-6 text-gray-900" + >{i18n.str`Fee`}</label> + <InputAmount + name="cashin_fee" + left + currency={outputCurrency} + value={fee?.value ?? ""} + onChange={fee?.onUpdate} + /> + <ShowInputErrorLabel + message={fee?.error} + isDirty={fee?.value !== undefined} + /> + <p class="mt-2 text-sm text-gray-500"> + <i18n.Translate>Operation fee</i18n.Translate> + </p> + </div> + </div> + </div> + + </Fragment> +} |