mirror of
https://github.com/basicswap/basicswap.git
synced 2025-11-05 18:38:09 +01:00
1082 lines
53 KiB
HTML
1082 lines
53 KiB
HTML
{% include 'header.html' %}
|
|
{% from 'style.html' import breadcrumb_line_svg, input_arrow_down_svg, circular_arrows_svg, confirm_green_svg, green_cross_close_svg, circular_info_messages_svg %}
|
|
|
|
<div class="container mx-auto">
|
|
<section class="p-5 mt-5">
|
|
<div class="flex flex-wrap items-center -m-2">
|
|
<div class="w-full md:w-1/2 p-2">
|
|
<ul class="flex flex-wrap items-center gap-x-3 mb-2">
|
|
<li>
|
|
<a class="flex font-medium text-xs text-coolGray-500 dark:text-gray-300 hover:text-coolGray-700" href="/">
|
|
<p>Home</p>
|
|
</a>
|
|
</li>
|
|
<li>
|
|
{{ breadcrumb_line_svg | safe }}
|
|
</li>
|
|
<li>
|
|
<a class="flex font-medium text-xs text-coolGray-500 dark:text-gray-300 hover:text-coolGray-700" href="#">Offer</a>
|
|
</li>
|
|
<li>
|
|
{{ breadcrumb_line_svg | safe }}
|
|
</li>
|
|
<li>
|
|
<a class="flex font-medium text-xs text-coolGray-500 dark:text-gray-300 hover:text-coolGray-700" href="{{ offer_id }}">OFFER ID: {{ offer_id }}</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
<section class="py-4">
|
|
<div class="container px-4 mx-auto">
|
|
<div class="relative py-11 px-16 bg-coolGray-900 dark:bg-blue-500 rounded-md overflow-hidden">
|
|
<img class="absolute z-10 left-4 top-4" src="/static/images/elements/dots-red.svg" alt="">
|
|
<img class="absolute z-10 right-4 bottom-4" src="/static/images/elements/dots-red.svg" alt="">
|
|
<img class="absolute h-64 left-1/2 top-1/2 transform -translate-x-1/2 -translate-y-1/2 object-cover" src="/static/images/elements/wave.svg" alt="">
|
|
<div class="relative z-20 flex flex-wrap items-center -m-3">
|
|
<div class="w-full md:w-1/2 p-3">
|
|
<h2 class="mb-6 text-4xl font-bold text-white tracking-tighter">Offer</h2>
|
|
<p class="font-normal text-coolGray-200 dark:text-white"><span class="bold">OFFER ID:</span> {{ offer_id }}</p>
|
|
</div>
|
|
<div class="w-full md:w-1/2 p-3 p-6 container flex flex-wrap items-center justify-end items-center mx-auto">
|
|
{% if refresh %}
|
|
<a id="refresh" href="/offer/{{ offer_id }}" class="rounded-full mr-5 flex flex-wrap justify-center px-5 py-3 bg-blue-500 hover:bg-blue-600 font-medium text-sm text-white border dark:bg-gray-500 dark:hover:bg-gray-700 border-blue-500 rounded-md shadow-button focus:ring-0 focus:outline-none">
|
|
{{ circular_arrows_svg | safe }}<span>Refresh {{ refresh }} seconds</span>
|
|
</a>
|
|
{% else %}
|
|
<a id="refresh" href="/offer/{{ offer_id }}" class="rounded-full mr-5 flex flex-wrap justify-center px-5 py-3 bg-blue-500 hover:bg-blue-600 font-medium text-sm text-white border dark:bg-gray-500 dark:hover:bg-gray-700 border-blue-500 rounded-md shadow-button focus:ring-0 focus:outline-none">
|
|
{{ circular_arrows_svg | safe }}<span>Refresh</span>
|
|
</a>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
{% include 'inc_messages.html' %}
|
|
{% if sent_bid_id %}
|
|
<section class="py-4" id="messages_send_bid_id" role="alert">
|
|
<div class="container px-4 mx-auto">
|
|
<div class="p-6 text-green-800 rounded-lg bg-green-50 border border-green-500 dark:bg-gray-500 dark:text-green-400 rounded-md">
|
|
<div class="flex flex-wrap justify-between items-center -m-2">
|
|
<div class="flex-1 p-2">
|
|
<div class="flex flex-wrap -m-1">
|
|
<div class="w-auto p-1">
|
|
{{ circular_info_messages_svg | safe }}
|
|
</div>
|
|
<ul class="ml-4 mt-1">
|
|
<li class="font-semibold text-sm text-green-500 error_msg"><span class="bold">INFO:</span></li>
|
|
<li class="font-medium text-sm text-green-500 infomsg">Sent Bid {{ sent_bid_id }}</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<div class="w-auto p-2">
|
|
<button type="button" class="ms-auto bg-green-50 text-green-500 rounded-lg focus:ring-0 focus:ring-green-400 p-1.5 hover:bg-green-200 inline-flex items-center justify-center h-8 w-8 focus:outline-none dark:bg-gray-800 dark:text-green-400 dark:hover:bg-gray-700" data-dismiss-target="#messages_send_bid_id" aria-label="Close"><span class="sr-only">Close</span>
|
|
{{ green_cross_close_svg | safe }}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
{% endif %}
|
|
<section>
|
|
<div class="pl-6 pr-6 pt-0 pb-0 mt-5 h-full overflow-hidden">
|
|
<div class="pb-6 border-coolGray-100">
|
|
<div class="flex flex-wrap items-center justify-between -m-2">
|
|
<div class="w-full pt-2">
|
|
<div class="container mt-5 mx-auto">
|
|
<div class="pt-6 pb-8 bg-coolGray-100 dark:bg-gray-500 rounded-xl">
|
|
<div class="px-6">
|
|
<div class="w-full mt-6 pb-6 overflow-x-auto">
|
|
<table class="w-full min-w-max text-sm">
|
|
<thead class="uppercase">
|
|
<tr class="text-left">
|
|
<th class="p-0">
|
|
<div class="py-3 px-6 rounded-tl-xl bg-coolGray-200 dark:bg-gray-600">
|
|
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">Options</span>
|
|
</div>
|
|
</th>
|
|
<th class="p-0">
|
|
<div class="py-3 px-6 rounded-tr-xl bg-coolGray-200 dark:bg-gray-600">
|
|
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">Details</span>
|
|
</div>
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="py-3 px-6 bold">Offer State</td>
|
|
<td class="py-3 px-6">{{ data.state }}</td>
|
|
</tr>
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="py-3 px-6 bold">Swap Type</td>
|
|
<td class="py-3 px-6">{{ data.swap_type }}{% if data.reverse == true %} (Transposed){% endif %}</td>
|
|
</tr>
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="py-3 px-6 bold">{% if data.sent %}You Send{% else %}You Get{% endif %}</td>
|
|
<td class="px-6">
|
|
<span class="inline-flex align-middle items-center justify-center w-9 h-10 bg-white-50 rounded">
|
|
<img class="h-7" src="/static/images/coins/{{ data.coin_from }}.png" alt="{{ data.coin_from }}">
|
|
</span>{{ data.coin_from }}
|
|
</td>
|
|
</tr>
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="py-3 px-6 bold">{% if data.sent %}You Get{% else %}You Send{% endif %}</td>
|
|
<td class="px-6">
|
|
<span class="inline-flex align-middle items-center justify-center w-9 h-10 bg-white-50 rounded">
|
|
<img class="h-7" src="/static/images/coins/{{ data.coin_to }}.png" alt="{{ data.coin_to }}">
|
|
</span>{{ data.coin_to }}
|
|
</td>
|
|
</tr>
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="py-3 px-6 bold">Amount Offerer Sends</td>
|
|
<td class="py-3 px-6 bold">{{ data.amt_from }} {{ data.tla_from }}</td>
|
|
</tr>
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="py-3 px-6 bold">Amount Bidder Sends</td>
|
|
<td class="py-3 px-6 bold">{{ data.amt_to }} {{ data.tla_to }}</td>
|
|
</tr>
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="py-3 px-6 bold">Minimum Purchase</td>
|
|
<td class="py-3 px-6">{{ data.amt_bid_min }} {{ data.tla_from }}</td>
|
|
</tr>
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="py-3 px-6 bold">Rate</td>
|
|
<td class="py-3 px-6">{{ data.rate }}</td>
|
|
</tr>
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="py-3 px-6 bold" title="Total coin-from value of completed bids, that this node is involved in">Amount Swapped</td>
|
|
<td class="py-3 px-6">{{ data.amt_swapped }} {{ data.tla_from }}</td>
|
|
</tr>
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="py-3 px-6 bold" title="If bids can be sent with a different amount">Amount Variable</td>
|
|
<td class="py-3 px-6">{{ data.amount_negotiable }}</td>
|
|
</tr>
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="py-3 px-6 bold" title="If bids can be sent with a different amount">Rate Variable</td>
|
|
<td class="py-3 px-6">{{ data.rate_negotiable }}</td>
|
|
</tr>
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="py-3 px-6 bold">Script Lock Type</td>
|
|
<td class="py-3 px-6">{{ data.lock_type }}</td>
|
|
</tr>
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="py-3 px-6 bold">Script Lock Value</td>
|
|
<td class="py-3 px-6">{{ data.lock_value }} {{ data.lock_value_hr }}</td>
|
|
</tr>
|
|
{% if data.addr_to == "Public" %}
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="py-3 px-6 bold">Address To</td>
|
|
<td class="py-3 px-6">{{ data.addr_to }}</td>
|
|
</tr>
|
|
{% else %}
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="py-3 px-6 bold">Address To</td>
|
|
<td class="py-3 px-6">
|
|
<a class="monospace bold" href="/identity/{{ data.addr_to }}">{{ data.addr_to }}</a> {{ data.addr_to_label }}
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="py-3 px-6 bold">Address From</td>
|
|
<td class="py-3 px-6">
|
|
<a class="monospace bold" href="/identity/{{ data.addr_from }}">{{ data.addr_from }}</a> {{ data.addr_from_label }}
|
|
</td>
|
|
</tr>
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td scope="row" class="flex items-center px-46 whitespace-nowrap">
|
|
<svg alt="" class="w-5 h-5 rounded-full ml-5" xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 24 24">
|
|
<g stroke-linecap="round" stroke-width="2" fill="none" stroke="#3B82F6" stroke-linejoin="round">
|
|
<circle cx="12" cy="12" r="11"></circle>
|
|
<polyline points=" 12,6 12,12 18,12 " stroke="#3B82F6"></polyline>
|
|
</g>
|
|
</svg>
|
|
<div class="py-4 pl-2 bold">
|
|
<div>Created At</div>
|
|
</div>
|
|
</td>
|
|
<td class="py-3 px-6">{{ data.created_at | formatts }}</td>
|
|
</tr>
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td scope="row" class="flex items-center px-46 whitespace-nowrap">
|
|
<svg alt="" class="w-5 h-5 rounded-full ml-5" xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 24 24">
|
|
<g stroke-linecap="round" stroke-width="2" fill="none" stroke="#6b7280" stroke-linejoin="round">
|
|
<circle cx="12" cy="12" r="11"></circle>
|
|
<polyline points=" 12,6 12,12 18,12 " stroke="#6b7280"></polyline>
|
|
</g>
|
|
</svg>
|
|
<div class="py-4 pl-2 bold">
|
|
<div>Expired At</div>
|
|
</div>
|
|
</td>
|
|
<td class="py-3 px-6">{{ data.expired_at | formatts }}</td>
|
|
</tr>
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="py-3 px-6 bold">Sent</td>
|
|
<td class="py-3 px-6">{{ data.sent }}</td>
|
|
</tr>
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="py-3 px-6 bold">Revoked</td>
|
|
<td class="py-3 px-6">{{ data.was_revoked }}</td>
|
|
</tr>
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="py-3 px-6 bold">Auto Accept Type</td>
|
|
<td class="py-3 px-6">
|
|
{% if data.auto_accept_type is none %} Unknown
|
|
{% elif data.auto_accept_type == 0 %} Bids are accepted manually
|
|
{% elif data.auto_accept_type == 1 %} Bids are accepted automatically
|
|
{% elif data.auto_accept_type == 2 %} Bids are accepted automatically from known identities
|
|
{% else %} Unknown ({{ data.auto_accept_type }})
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% if data.xmr_type == true %}
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="py-3 px-6 bold">Chain A offer fee rate</td>
|
|
<td class="py-3 px-6">{{ data.a_fee_rate }}</td>
|
|
</tr>
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="py-3 px-6 bold">Chain A local fee rate</td>
|
|
<td class="py-3 px-6">{{ data.a_fee_rate_verify }} (Fee source: {{ data.a_fee_rate_verify_src }}{% if data.a_fee_warn == true %} WARNING {% endif %})</td>
|
|
</tr>
|
|
{% endif %}
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
<section class="p-6 bg-body dark:bg-gray-700">
|
|
<div class="flex flex-wrap items-center">
|
|
<div class="w-full">
|
|
<h4 class="font-semibold text-black dark:text-white text-2xl">Bids</h4>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
<section>
|
|
<div class="pl-6 pr-6 pt-0 pb-6 mt-5 h-full overflow-hidden">
|
|
<div class="container px-0 mx-auto">
|
|
<div class="pt-6 pb-6 bg-coolGray-100 dark:bg-gray-500 rounded-xl">
|
|
<div class="px-6">
|
|
<div class="w-full mt-6 pb-6 overflow-x-auto">
|
|
<table class="w-full min-w-max text-sm">
|
|
<thead class="uppercase">
|
|
<tr class="text-left">
|
|
<th class="p-0">
|
|
<div class="py-3 px-6 rounded-tl-xl bg-coolGray-200 dark:bg-gray-600">
|
|
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">Bid ID</span>
|
|
</div>
|
|
</th>
|
|
<th class="p-0">
|
|
<div class="py-3 px-6 bg-coolGray-200 dark:bg-gray-600">
|
|
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">Bid Amount</span>
|
|
</div>
|
|
</th>
|
|
<th class="p-0">
|
|
<div class="py-3 px-6 bg-coolGray-200 dark:bg-gray-600">
|
|
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">Bid Rate</span>
|
|
</div>
|
|
</th>
|
|
<th class="p-0">
|
|
<div class="py-3 px-6 bg-coolGray-200 dark:bg-gray-600">
|
|
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">Bid Status</span>
|
|
</div>
|
|
</th>
|
|
<th class="p-0">
|
|
<div class="py-3 px-6 rounded-tr-xl bg-coolGray-200 dark:bg-gray-600">
|
|
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">Identity From</span>
|
|
</div>
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
{% for b in bids %}
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="py-3 px-6">
|
|
<a class="monospace" href=/bid/{{ b[0] }}>{{ b[0] }}</a>
|
|
</td>
|
|
<td class="py-3 px-6">{{ b[1] }}</td>
|
|
<td class="py-3 px-6">{{ b[3] }}</td>
|
|
<td class="py-3 px-6">{{ b[2] }}</td>
|
|
<td class="py-3 px-6">
|
|
<a class="monospace" href=/identity/{{ b[4] }}>{{ b[4] }}</a>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<form id="bidForm" action="/offer/{{ offer_id }}" method="post">
|
|
</section>
|
|
{% if data.show_edit_form %}
|
|
<section class="p-6 bg-body dark:bg-gray-700">
|
|
<div class="flex flex-wrap items-center">
|
|
<div class="w-full">
|
|
<h4 class="font-semibold text-black dark:text-white text-2xl">Edit Offer</h4>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
<section>
|
|
<div class="pl-6 pr-6 pt-0 pb-0 mt-5 h-full overflow-hidden">
|
|
<div class="container px-0 mx-auto">
|
|
<div class="pt-6 pb-8 bg-coolGray-100 dark:bg-gray-500 rounded-xl">
|
|
<div class="px-6">
|
|
<div class="w-full mt-6 pb-6 overflow-x-auto">
|
|
<table class="w-full min-w-max text-sm">
|
|
<thead class="uppercase">
|
|
<tr class="text-left">
|
|
<th class="p-0">
|
|
<div class="py-3 px-6 rounded-tl-xl bg-coolGray-200 dark:bg-gray-600">
|
|
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">Options</span>
|
|
</div>
|
|
</th>
|
|
<th class="p-0">
|
|
<div class="py-3 px-6 rounded-tr-xl bg-coolGray-200 dark:bg-gray-600">
|
|
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">Settings</span>
|
|
</div>
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="pr-3 px-6 bold">Auto Accept Strategy:</td>
|
|
<td class="py-3 px-6">
|
|
<div class="relative">
|
|
{{ input_arrow_down_svg | safe }}
|
|
<select name="automation_strat_id" class="bg-gray-50 text-gray-900 appearance-none pr-10 dark:bg-gray-500 dark:text-white border border-gray-300 dark:border-gray-400 dark:text-gray-50 dark:placeholder-gray-50 text-sm rounded-lg outline-none focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 focus:ring-0">
|
|
<option value="-1" {% if data.automation_strat_id==-1 %} selected{% endif %}>None</option>
|
|
{% for a in data.automation_strategies %}
|
|
<option value="{{ a[0] }}" {% if data.automation_strat_id==a[0] %} selected{% endif %}>{{ a[1] }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="rounded-b-md">
|
|
<div class="w-full md:w-0/12">
|
|
<div class="flex flex-wrap justify-end pt-6 pr-6 border-t border-gray-100 dark:border-gray-400">
|
|
<div class="w-full md:w-auto p-1.5">
|
|
<button name="edit_offer_submit" value="Submit" type="submit" class="flex flex-wrap justify-center w-full px-4 py-2.5 bg-blue-500 hover:bg-blue-600 font-medium text-sm text-white border border-blue-500 rounded-md shadow-button focus:ring-0 focus:outline-none">Send Bid</button>
|
|
</div>
|
|
<div class="w-full md:w-auto p-1.5">
|
|
<button name="edit_offer_cancel" value="Cancel" type="submit" class="flex flex-wrap justify-center w-full px-4 py-2.5 font-medium text-sm text-white hover:text-red border border-red-500 hover:border-red-500 hover:bg-red-600 bg-red-500 rounded-md shadow-button focus:ring-0 focus:outline-none">Cancel</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
{% elif data.show_bid_form %}
|
|
<section class="p-6 bg-body dark:bg-gray-700">
|
|
<div class="flex flex-wrap items-center">
|
|
<div class="w-full">
|
|
<h4 class="font-semibold text-black dark:text-white text-2xl">New Bid</h4>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
<section>
|
|
<div class="pl-6 pr-6 pt-0 pb-0 mt-5 h-full overflow-hidden">
|
|
<div class="pt-6 pb-6 bg-coolGray-100 dark:bg-gray-500 rounded-xl">
|
|
<div class="px-6">
|
|
<div class="w-full mt-6 pb-6 overflow-x-auto">
|
|
<table class="w-full min-w-max text-sm">
|
|
<thead class="uppercase">
|
|
<tr class="text-left">
|
|
<th class="p-0">
|
|
<div class="py-3 px-6 rounded-tl-xl bg-coolGray-200 dark:bg-gray-600">
|
|
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">Options</span>
|
|
</div>
|
|
</th>
|
|
<th class="p-0">
|
|
<div class="py-3 px-6 rounded-tr-xl bg-coolGray-200 dark:bg-gray-600">
|
|
<span class="text-xs text-gray-600 dark:text-gray-300 font-semibold">Value</span>
|
|
</div>
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="py-3 px-6 bold">Send From Address</td>
|
|
<td class="py-3 px-6">
|
|
<div class="w-full md:flex-1">
|
|
<div class="relative">
|
|
{{ input_arrow_down_svg | safe }}
|
|
<select class="bg-gray-50 text-gray-900 appearance-none pr-10 dark:bg-gray-500 dark:text-white border border-gray-300 dark:border-gray-400 dark:text-gray-50 dark:placeholder-gray-50 text-sm rounded-lg outline-none focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 focus:ring-0" name="addr_from">
|
|
<option value="-1" {% if data.nb_addr_from=="-1" %} selected{% endif %}>New Address</option>
|
|
{% for a in addrs %}
|
|
<option value="{{ a[0] }}" {% if data.nb_addr_from==a[0] %} selected{% endif %}>{{ a[0] }} {{ a[1] }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<script>
|
|
function handleBidsPageAddress() {
|
|
const selectElement = document.querySelector('select[name="addr_from"]');
|
|
const STORAGE_KEY = 'lastUsedAddressBids';
|
|
|
|
if (!selectElement) return;
|
|
|
|
function loadInitialAddress() {
|
|
const savedAddressJSON = localStorage.getItem(STORAGE_KEY);
|
|
if (savedAddressJSON) {
|
|
try {
|
|
const savedAddress = JSON.parse(savedAddressJSON);
|
|
selectElement.value = savedAddress.value;
|
|
} catch (e) {
|
|
selectFirstAddress();
|
|
}
|
|
} else {
|
|
selectFirstAddress();
|
|
}
|
|
}
|
|
|
|
function selectFirstAddress() {
|
|
if (selectElement.options.length > 1) {
|
|
const firstOption = selectElement.options[1];
|
|
if (firstOption) {
|
|
selectElement.value = firstOption.value;
|
|
saveAddress(firstOption.value, firstOption.text);
|
|
}
|
|
}
|
|
}
|
|
|
|
function saveAddress(value, text) {
|
|
const addressData = {
|
|
value: value,
|
|
text: text
|
|
};
|
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(addressData));
|
|
}
|
|
|
|
selectElement.addEventListener('change', (event) => {
|
|
saveAddress(event.target.value, event.target.selectedOptions[0].text);
|
|
});
|
|
|
|
loadInitialAddress();
|
|
}
|
|
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', handleBidsPageAddress);
|
|
} else {
|
|
handleBidsPageAddress();
|
|
}
|
|
</script>
|
|
{% if data.amount_negotiable == true %}
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="px-6">
|
|
<span class="inline-flex bold align-middle items-center justify-center w-9 h-10 bg-white-50 rounded">
|
|
<img class="h-7" src="/static/images/coins/{{ data.coin_to }}.png" alt="{{ data.coin_to }}">
|
|
</span>
|
|
<span class="bold">Sending ({{ data.tla_to }})</span>
|
|
</td>
|
|
<td class="py-3 px-6">
|
|
<div class="relative">
|
|
<input type="text"
|
|
class="bg-gray-50 text-gray-900 appearance-none pr-28 dark:bg-gray-500 dark:text-white border border-gray-300 dark:border-gray-400 dark:text-gray-50 dark:placeholder-gray-50 text-sm rounded-lg outline-none focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 focus:ring-0"
|
|
id="bid_amount_send"
|
|
autocomplete="off"
|
|
name="bid_amount_send"
|
|
value=""
|
|
max="{{ data.amt_to }}"
|
|
onchange="validateMaxAmount(this, parseFloat('{{ data.amt_to }}')); updateBidParams('sending');">
|
|
<div class="absolute inset-y-0 right-3 flex items-center pointer-events-none text-gray-400 dark:text-gray-300 text-sm">
|
|
max {{ data.amt_to }} ({{ data.tla_to }})
|
|
</div>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="px-6">
|
|
<span class="inline-flex bold align-middle items-center justify-center w-9 h-10 bg-white-50 rounded">
|
|
<img class="h-7" src="/static/images/coins/{{ data.coin_from }}.png" alt="{{ data.coin_from }}">
|
|
</span>
|
|
<span class="bold">Receiving ({{ data.tla_from }})</span>
|
|
</td>
|
|
<td class="py-3 px-6">
|
|
<div class="relative">
|
|
<input type="text"
|
|
class="bg-gray-50 text-gray-900 appearance-none pr-28 dark:bg-gray-500 dark:text-white border border-gray-300 dark:border-gray-400 dark:text-gray-50 dark:placeholder-gray-50 text-sm rounded-lg outline-none focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 focus:ring-0"
|
|
id="bid_amount"
|
|
autocomplete="off"
|
|
name="bid_amount"
|
|
value=""
|
|
max="{{ data.amt_from }}"
|
|
onchange="validateMaxAmount(this, parseFloat('{{ data.amt_from }}')); updateBidParams('receiving');">
|
|
<div class="absolute inset-y-0 right-3 flex items-center pointer-events-none text-gray-400 dark:text-gray-300 text-sm">
|
|
max {{ data.amt_from }} ({{ data.tla_from }})
|
|
</div>
|
|
</div>
|
|
{% if data.xmr_type == true %}
|
|
<div class="text-sm mt-1 text-gray-400 dark:text-gray-300">(excluding estimated <span class="bold">{{ data.amt_from_lock_spend_tx_fee }} {{ data.tla_from }}</span> in tx fees)</div>
|
|
{% else %}
|
|
<div class="text-sm mt-1 text-gray-400 dark:text-gray-300">(excluding a tx fee)</div>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% else %}
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="px-6">
|
|
<span class="inline-flex bold align-middle items-center justify-center w-9 h-10 bg-white-50 rounded">
|
|
<img class="h-7" src="/static/images/coins/{{ data.coin_to }}.png" alt="{{ data.coin_to }}">
|
|
</span>
|
|
<span class="bold">Sending ({{ data.tla_to }})</span>
|
|
</td>
|
|
<td class="py-3 px-6">
|
|
<div class="relative">
|
|
<input type="text"
|
|
class="bg-gray-50 text-gray-900 appearance-none pr-28 dark:bg-gray-500 dark:text-white border border-gray-300 dark:border-gray-400 dark:text-gray-50 dark:placeholder-gray-50 text-sm rounded-lg outline-none focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 focus:ring-0 cursor-not-allowed"
|
|
id="bid_amount_send"
|
|
autocomplete="off"
|
|
name="bid_amount_send"
|
|
value="{{ data.amt_to }}"
|
|
max="{{ data.amt_to }}"
|
|
disabled>
|
|
<div class="absolute inset-y-0 right-3 flex items-center pointer-events-none text-gray-400 dark:text-gray-300 text-sm">
|
|
max {{ data.amt_to }} ({{ data.tla_to }})
|
|
</div>
|
|
</div>
|
|
<div class="text-sm mt-1 text-gray-400 dark:text-gray-300">(Amount not variable)</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="px-6">
|
|
<span class="inline-flex bold align-middle items-center justify-center w-9 h-10 bg-white-50 rounded">
|
|
<img class="h-7" src="/static/images/coins/{{ data.coin_from }}.png" alt="{{ data.coin_from }}">
|
|
</span>
|
|
<span class="bold">Receiving ({{ data.tla_from }})</span>
|
|
</td>
|
|
<td class="py-3 px-6">
|
|
<div class="relative">
|
|
<input type="text"
|
|
class="bg-gray-50 text-gray-900 appearance-none pr-28 dark:bg-gray-500 dark:text-white border border-gray-300 dark:border-gray-400 dark:text-gray-50 dark:placeholder-gray-50 text-sm rounded-lg outline-none focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 focus:ring-0 cursor-not-allowed"
|
|
id="bid_amount"
|
|
autocomplete="off"
|
|
name="bid_amount"
|
|
value="{{ data.bid_amount }}"
|
|
max="{{ data.amt_from }}"
|
|
disabled>
|
|
<div class="absolute inset-y-0 right-3 flex items-center pointer-events-none text-gray-400 dark:text-gray-300 text-sm">
|
|
max {{ data.amt_from }} ({{ data.tla_from }})
|
|
</div>
|
|
</div>
|
|
{% if data.xmr_type == true %}
|
|
<div class="text-sm mt-1 text-gray-400 dark:text-gray-300">(excluding estimated <span class="bold">{{ data.amt_from_lock_spend_tx_fee }} {{ data.tla_from }}</span> in tx fees)</div>
|
|
{% else %}
|
|
<div class="text-sm mt-1 text-gray-400 dark:text-gray-300">(excluding a tx fee)</div>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="py-3 px-6 bold">Rate </td>
|
|
<td class="py-3 px-6">
|
|
{% if data.rate_negotiable == true %}
|
|
<input type="text"
|
|
class="bg-gray-50 text-gray-900 appearance-none pr-10 dark:bg-gray-500 dark:text-white border border-gray-300 dark:border-gray-400 dark:text-gray-50 dark:placeholder-gray-50 text-sm rounded-lg outline-none focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 focus:ring-0"
|
|
id="bid_rate"
|
|
name="bid_rate"
|
|
value="{{ data.bid_rate }}"
|
|
placeholder="Current rate: {{ data.rate }}"
|
|
onchange="updateBidParams('rate')">
|
|
{% else %}
|
|
<input type="text"
|
|
class="bg-gray-50 text-gray-900 appearance-none pr-10 dark:bg-gray-500 dark:text-white border border-gray-300 dark:border-gray-400 dark:text-gray-50 dark:placeholder-gray-50 text-sm rounded-lg outline-none focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 focus:ring-0 cursor-not-allowed"
|
|
id="bid_rate"
|
|
name="bid_rate"
|
|
value="{{ data.rate }}"
|
|
title="Rate is not negotiable"
|
|
disabled>
|
|
<div class="text-sm mt-1 text-gray-400 dark:text-gray-300">(Rate is not negotiable)</div>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="py-3 px-6 bold">Minutes valid</td>
|
|
<td class="py-3 px-6">
|
|
<input type="number" class="bg-gray-50 text-gray-900 appearance-none pr-10 dark:bg-gray-500 dark:text-white border border-gray-300 dark:border-gray-400 dark:text-gray-50 dark:placeholder-gray-50 text-sm rounded-lg outline-none focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 focus:ring-0" name="validmins" min="10" max="1440" value="{{ data.nb_validmins }}">
|
|
</td>
|
|
</tr>
|
|
{% if data.debug_ui == true %}
|
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
|
<td class="py-3 px-6 bold">Debug Option:</td>
|
|
<td class="py-3 px-6">
|
|
<div class="w-full md:flex-1">
|
|
<div class="relative">
|
|
{{ input_arrow_down_svg | safe }}
|
|
<select class="bg-gray-50 text-gray-900 appearance-none pr-10 dark:bg-gray-500 dark:text-white border border-gray-300 dark:border-gray-400 dark:text-gray-50 dark:placeholder-gray-50 text-sm rounded-lg outline-none focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 focus:ring-0" name="debugind">
|
|
<option{% if data.debug_ind=="-1" %} selected{% endif %} value="-1">None</option>
|
|
{% for a in data.debug_options %}
|
|
<option{% if data.debug_ind==a[0] %} selected{% endif %} value="{{ a[0] }}">{{ a[1] }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="rounded-b-md">
|
|
<div class="w-full md:w-0/12">
|
|
<div class="flex flex-wrap justify-end pt-6 pr-6 border-t border-gray-100 dark:border-gray-400">
|
|
<div class="w-full md:w-auto p-1.5">
|
|
<button type="button" onclick="resetForm()" class="flex flex-wrap justify-center w-full px-4 py-2.5 font-medium text-sm text-coolGray-500 hover:text-coolGray-600 border border-coolGray-200 hover:border-coolGray-300 bg-white rounded-md shadow-button focus:ring-0 focus:outline-none dark:text-white dark:hover:text-white dark:bg-gray-600 dark:hover:bg-gray-700 dark:border-gray-600 dark:hover:border-gray-600">
|
|
Clear Form
|
|
</button>
|
|
</div>
|
|
<div class="w-full md:w-auto p-1.5 ml-2">
|
|
<input type="hidden" name="confirm" value="true">
|
|
<button name="sendbid" value="Send Bid" type="submit" class="flex flex-wrap justify-center w-full px-4 py-2.5 bg-blue-500 hover:bg-blue-600 font-medium text-sm text-white border border-blue-500 rounded-md shadow-button focus:ring-0 focus:outline-none">
|
|
Send Bid
|
|
</button>
|
|
</div>
|
|
<div class="w-full md:w-auto p-1.5">
|
|
<button name="cancel" value="Cancel" type="submit" class="flex flex-wrap justify-center w-full px-4 py-2.5 font-medium text-sm text-white hover:text-red border border-red-500 hover:border-red-500 hover:bg-red-600 bg-red-500 rounded-md shadow-button focus:ring-0 focus:outline-none">
|
|
Cancel
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- TODO:
|
|
<div class="w-full md:w-auto p-1.5 ml-2"><button name="check_rates" value="Lookup Rates" type="button" onclick='lookup_rates();' class="flex flex-wrap justify-center w-full px-4 py-2.5 font-medium text-sm text-coolGray-500 hover:text-coolGray-600 border border-coolGray-200 hover:border-coolGray-300 bg-white rounded-md shadow-button focus:ring-0 focus:outline-none"><svg class="mr-2"
|
|
xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 24 24"><g fill="#556987"><path fill="#556987" d="M12,3c1.989,0,3.873,0.65,5.43,1.833l-3.604,3.393l9.167,0.983L22.562,0l-3.655,3.442 C16.957,1.862,14.545,1,12,1C5.935,1,1,5.935,1,12h2C3,7.037,7.037,3,12,3z"></path><path data-color="#556987" d="M12,21c-1.989,0-3.873-0.65-5.43-1.833l3.604-3.393l-9.167-0.983L1.438,24l3.655-3.442 C7.043,22.138,9.455,23,12,23c6.065,0,11-4.935,11-11h-2C21,16.963,16.963,21,12,21z"></path></g></svg><span>Lookup Rates</span></button></div>
|
|
-->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
<div id="confirmModal" class="fixed inset-0 z-50 hidden overflow-y-auto">
|
|
<div class="fixed inset-0 bg-black bg-opacity-50 transition-opacity duration-300 ease-out"></div>
|
|
<div class="relative z-50 min-h-screen px-4 flex items-center justify-center">
|
|
<div class="bg-white dark:bg-gray-500 rounded-lg max-w-2xl w-full p-6 shadow-lg transition-opacity duration-300 ease-out">
|
|
<div class="text-center">
|
|
<h2 class="text-xl font-semibold text-gray-900 dark:text-white mb-6">Confirm Bid</h2>
|
|
<div class="space-y-4 text-left mb-8">
|
|
<div class="bg-gray-50 dark:bg-gray-600 rounded-lg p-4">
|
|
<div class="text-sm text-gray-600 dark:text-gray-400 mb-1">Amount you will get:</div>
|
|
<div class="font-medium text-gray-900 dark:text-white text-lg">
|
|
<span id="modal-amt-receive"></span>
|
|
<span id="modal-receive-currency"></span>
|
|
<div class="text-sm text-gray-500 dark:text-gray-400 mt-1" id="modal-fee-info"></div>
|
|
</div>
|
|
</div>
|
|
<div class="bg-gray-50 dark:bg-gray-600 rounded-lg p-4">
|
|
<div class="text-sm text-gray-600 dark:text-gray-400 mb-1">Amount you will send:</div>
|
|
<div class="font-medium text-gray-900 dark:text-white text-lg">
|
|
<span id="modal-amt-send"></span>
|
|
<span id="modal-send-currency"></span>
|
|
</div>
|
|
</div>
|
|
<div class="bg-gray-50 dark:bg-gray-600 rounded-lg p-4">
|
|
<div class="text-sm text-gray-600 dark:text-gray-400 mb-1">Send From Address:</div>
|
|
<div class="font-mono text-sm p-2 bg-white dark:bg-gray-500 rounded border border-gray-300 dark:border-gray-400 overflow-x-auto text-gray-900 dark:text-white">
|
|
<span id="modal-addr-from"></span>
|
|
</div>
|
|
</div>
|
|
<div class="bg-gray-50 dark:bg-gray-600 rounded-lg p-4">
|
|
<div class="text-sm text-gray-600 dark:text-gray-400 mb-1">Minutes valid:</div>
|
|
<div class="font-medium text-gray-900 dark:text-white text-lg" id="modal-valid-mins"></div>
|
|
</div>
|
|
</div>
|
|
<div class="flex justify-center gap-4">
|
|
<button type="submit" name="sendbid" value="confirm"
|
|
class="px-4 py-2.5 bg-blue-500 hover:bg-blue-600 font-medium text-sm text-white border border-blue-500 rounded-md shadow-button focus:ring-0 focus:outline-none">
|
|
Confirm
|
|
</button>
|
|
<button type="button" onclick="hideConfirmModal()"
|
|
class="px-4 py-2.5 font-medium text-sm text-white hover:text-red border border-red-500 hover:border-red-500 hover:bg-red-600 bg-red-500 rounded-md shadow-button focus:ring-0 focus:outline-none">
|
|
Cancel
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<script>
|
|
const xhr_rates = new XMLHttpRequest();
|
|
xhr_rates.onload = () => {
|
|
if (xhr_rates.status == 200) {
|
|
const obj = JSON.parse(xhr_rates.response);
|
|
const inner_html = '<h4 class="bold>Rates</h4><pre><code>' + JSON.stringify(obj, null, ' ') + '</code></pre>';
|
|
const ratesDisplay = document.getElementById('rates_display');
|
|
if (ratesDisplay) {
|
|
ratesDisplay.innerHTML = inner_html;
|
|
}
|
|
}
|
|
};
|
|
|
|
const xhr_bid_params = new XMLHttpRequest();
|
|
xhr_bid_params.onload = () => {
|
|
if (xhr_bid_params.status == 200) {
|
|
const obj = JSON.parse(xhr_bid_params.response);
|
|
const bidAmountSendInput = document.getElementById('bid_amount_send');
|
|
if (bidAmountSendInput) {
|
|
bidAmountSendInput.value = obj['amount_to'];
|
|
}
|
|
updateModalValues();
|
|
}
|
|
};
|
|
|
|
function lookup_rates() {
|
|
const coin_from = document.getElementById('coin_from')?.value;
|
|
const coin_to = document.getElementById('coin_to')?.value;
|
|
|
|
if (!coin_from || !coin_to || coin_from === '-1' || coin_to === '-1') {
|
|
alert('Coins from and to must be set first.');
|
|
return;
|
|
}
|
|
|
|
const ratesDisplay = document.getElementById('rates_display');
|
|
if (ratesDisplay) {
|
|
ratesDisplay.innerHTML = '<h4>Rates</h4><p>Updating...</p>';
|
|
}
|
|
|
|
xhr_rates.open('POST', '/json/rates');
|
|
xhr_rates.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
|
|
xhr_rates.send(`coin_from=${coin_from}&coin_to=${coin_to}`);
|
|
}
|
|
|
|
function resetForm() {
|
|
const bidAmountSendInput = document.getElementById('bid_amount_send');
|
|
const bidAmountInput = document.getElementById('bid_amount');
|
|
const bidRateInput = document.getElementById('bid_rate');
|
|
const validMinsInput = document.querySelector('input[name="validmins"]');
|
|
const amtVar = document.getElementById('amt_var')?.value === 'True';
|
|
if (bidAmountSendInput) {
|
|
bidAmountSendInput.value = amtVar ? '' : bidAmountSendInput.getAttribute('max');
|
|
}
|
|
if (bidAmountInput) {
|
|
bidAmountInput.value = amtVar ? '' : bidAmountInput.getAttribute('max');
|
|
}
|
|
if (bidRateInput && !bidRateInput.disabled) {
|
|
const defaultRate = document.getElementById('offer_rate')?.value || '';
|
|
bidRateInput.value = defaultRate;
|
|
}
|
|
if (validMinsInput) {
|
|
validMinsInput.value = "60";
|
|
}
|
|
if (!amtVar) {
|
|
updateBidParams('rate');
|
|
}
|
|
updateModalValues();
|
|
const errorMessages = document.querySelectorAll('.error-message');
|
|
errorMessages.forEach(msg => msg.remove());
|
|
|
|
const inputs = document.querySelectorAll('input');
|
|
inputs.forEach(input => {
|
|
input.classList.remove('border-red-500', 'focus:border-red-500');
|
|
});
|
|
}
|
|
|
|
function updateBidParams(value_changed) {
|
|
const coin_from = document.getElementById('coin_from')?.value;
|
|
const coin_to = document.getElementById('coin_to')?.value;
|
|
const amt_var = document.getElementById('amt_var')?.value;
|
|
const rate_var = document.getElementById('rate_var')?.value;
|
|
const bidAmountInput = document.getElementById('bid_amount');
|
|
const bidAmountSendInput = document.getElementById('bid_amount_send');
|
|
const amountFromInput = document.getElementById('amount_from');
|
|
const bidRateInput = document.getElementById('bid_rate');
|
|
const offerRateInput = document.getElementById('offer_rate');
|
|
|
|
if (!coin_from || !coin_to || !amt_var || !rate_var) return;
|
|
|
|
const rate = rate_var === 'True' && bidRateInput ?
|
|
parseFloat(bidRateInput.value) || 0 :
|
|
parseFloat(offerRateInput?.value || '0');
|
|
|
|
if (!rate) return;
|
|
|
|
if (value_changed === 'rate') {
|
|
if (bidAmountSendInput && bidAmountInput) {
|
|
const sendAmount = parseFloat(bidAmountSendInput.value) || 0;
|
|
const receiveAmount = (sendAmount / rate).toFixed(8);
|
|
bidAmountInput.value = receiveAmount;
|
|
}
|
|
} else if (value_changed === 'sending') {
|
|
if (bidAmountSendInput && bidAmountInput) {
|
|
const sendAmount = parseFloat(bidAmountSendInput.value) || 0;
|
|
const receiveAmount = (sendAmount / rate).toFixed(8);
|
|
bidAmountInput.value = receiveAmount;
|
|
}
|
|
} else if (value_changed === 'receiving') {
|
|
if (bidAmountInput && bidAmountSendInput) {
|
|
const receiveAmount = parseFloat(bidAmountInput.value) || 0;
|
|
const sendAmount = (receiveAmount * rate).toFixed(8);
|
|
bidAmountSendInput.value = sendAmount;
|
|
}
|
|
}
|
|
|
|
validateAmountsAfterChange();
|
|
|
|
xhr_bid_params.open('POST', '/json/rate');
|
|
xhr_bid_params.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
|
|
xhr_bid_params.send(`coin_from=${coin_from}&coin_to=${coin_to}&rate=${rate}&amt_from=${bidAmountInput?.value || '0'}`);
|
|
|
|
updateModalValues();
|
|
}
|
|
|
|
function validateAmountsAfterChange() {
|
|
const bidAmountSendInput = document.getElementById('bid_amount_send');
|
|
const bidAmountInput = document.getElementById('bid_amount');
|
|
|
|
if (bidAmountSendInput) {
|
|
const maxSend = parseFloat(bidAmountSendInput.getAttribute('max'));
|
|
validateMaxAmount(bidAmountSendInput, maxSend);
|
|
}
|
|
if (bidAmountInput) {
|
|
const maxReceive = parseFloat(bidAmountInput.getAttribute('max'));
|
|
validateMaxAmount(bidAmountInput, maxReceive);
|
|
}
|
|
}
|
|
|
|
function validateMaxAmount(input, maxAmount) {
|
|
if (!input) return;
|
|
const value = parseFloat(input.value) || 0;
|
|
if (value > maxAmount) {
|
|
input.value = maxAmount;
|
|
}
|
|
}
|
|
|
|
function showConfirmModal() {
|
|
updateModalValues();
|
|
const modal = document.getElementById('confirmModal');
|
|
if (modal) {
|
|
modal.classList.remove('hidden');
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function hideConfirmModal() {
|
|
const modal = document.getElementById('confirmModal');
|
|
if (modal) {
|
|
modal.classList.add('hidden');
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function updateModalValues() {
|
|
const bidAmountInput = document.getElementById('bid_amount');
|
|
const bidAmountSendInput = document.getElementById('bid_amount_send');
|
|
|
|
if (bidAmountInput) {
|
|
const modalAmtReceive = document.getElementById('modal-amt-receive');
|
|
if (modalAmtReceive) {
|
|
modalAmtReceive.textContent = bidAmountInput.value;
|
|
}
|
|
|
|
const modalReceiveCurrency = document.getElementById('modal-receive-currency');
|
|
if (modalReceiveCurrency) {
|
|
modalReceiveCurrency.textContent = ' {{ data.tla_from }}';
|
|
}
|
|
}
|
|
|
|
if (bidAmountSendInput) {
|
|
const modalAmtSend = document.getElementById('modal-amt-send');
|
|
if (modalAmtSend) {
|
|
modalAmtSend.textContent = bidAmountSendInput.value;
|
|
}
|
|
|
|
const modalSendCurrency = document.getElementById('modal-send-currency');
|
|
if (modalSendCurrency) {
|
|
modalSendCurrency.textContent = ' {{ data.tla_to }}';
|
|
}
|
|
}
|
|
|
|
const modalFeeInfo = document.getElementById('modal-fee-info');
|
|
if (modalFeeInfo) {
|
|
{% if data.xmr_type == true %}
|
|
modalFeeInfo.textContent = `(excluding estimated {{ data.amt_from_lock_spend_tx_fee }} {{ data.tla_from }} in tx fees)`;
|
|
{% else %}
|
|
modalFeeInfo.textContent = '(excluding a tx fee)';
|
|
{% endif %}
|
|
}
|
|
|
|
const addrSelect = document.querySelector('select[name="addr_from"]');
|
|
if (addrSelect) {
|
|
const modalAddrFrom = document.getElementById('modal-addr-from');
|
|
if (modalAddrFrom) {
|
|
const selectedOption = addrSelect.options[addrSelect.selectedIndex];
|
|
const addrText = selectedOption.value === '-1' ? 'New Address' : selectedOption.text.split(' ')[0];
|
|
modalAddrFrom.textContent = addrText;
|
|
}
|
|
}
|
|
|
|
const validMinsInput = document.querySelector('input[name="validmins"]');
|
|
if (validMinsInput) {
|
|
const modalValidMins = document.getElementById('modal-valid-mins');
|
|
if (modalValidMins) {
|
|
modalValidMins.textContent = validMinsInput.value;
|
|
}
|
|
}
|
|
}
|
|
|
|
function handleBidsPageAddress() {
|
|
const selectElement = document.querySelector('select[name="addr_from"]');
|
|
const STORAGE_KEY = 'lastUsedAddressBids';
|
|
|
|
if (!selectElement) return;
|
|
|
|
function loadInitialAddress() {
|
|
try {
|
|
const savedAddressJSON = localStorage.getItem(STORAGE_KEY);
|
|
if (savedAddressJSON) {
|
|
const savedAddress = JSON.parse(savedAddressJSON);
|
|
if (savedAddress && savedAddress.value) {
|
|
selectElement.value = savedAddress.value;
|
|
} else {
|
|
selectFirstAddress();
|
|
}
|
|
} else {
|
|
selectFirstAddress();
|
|
}
|
|
} catch (e) {
|
|
console.error('Error loading saved address:', e);
|
|
selectFirstAddress();
|
|
}
|
|
}
|
|
|
|
function selectFirstAddress() {
|
|
if (selectElement.options.length > 1) {
|
|
const firstOption = selectElement.options[1];
|
|
if (firstOption) {
|
|
selectElement.value = firstOption.value;
|
|
saveAddress(firstOption.value, firstOption.text);
|
|
}
|
|
}
|
|
}
|
|
|
|
selectElement.addEventListener('change', (event) => {
|
|
if (event.target.selectedOptions[0]) {
|
|
saveAddress(event.target.value, event.target.selectedOptions[0].text);
|
|
}
|
|
});
|
|
|
|
loadInitialAddress();
|
|
}
|
|
|
|
function saveAddress(value, text) {
|
|
try {
|
|
const addressData = { value, text };
|
|
localStorage.setItem('lastUsedAddressBids', JSON.stringify(addressData));
|
|
} catch (e) {
|
|
console.error('Error saving address:', e);
|
|
}
|
|
}
|
|
|
|
function confirmPopup() {
|
|
return confirm("Are you sure?");
|
|
}
|
|
|
|
function handleCancelClick(event) {
|
|
if (event) event.preventDefault();
|
|
const pathParts = window.location.pathname.split('/');
|
|
const offerId = pathParts[pathParts.indexOf('offer') + 1];
|
|
window.location.href = `/offer/${offerId}`;
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
|
|
const sendBidBtn = document.querySelector('button[name="sendbid"][value="Send Bid"]');
|
|
if (sendBidBtn) {
|
|
sendBidBtn.onclick = showConfirmModal;
|
|
}
|
|
|
|
const modalCancelBtn = document.querySelector('#confirmModal .flex button:last-child');
|
|
if (modalCancelBtn) {
|
|
modalCancelBtn.onclick = hideConfirmModal;
|
|
}
|
|
|
|
const mainCancelBtn = document.querySelector('button[name="cancel"]');
|
|
if (mainCancelBtn) {
|
|
mainCancelBtn.onclick = handleCancelClick;
|
|
}
|
|
|
|
const validMinsInput = document.querySelector('input[name="validmins"]');
|
|
if (validMinsInput) {
|
|
validMinsInput.addEventListener('input', updateModalValues);
|
|
}
|
|
|
|
const addrFromSelect = document.querySelector('select[name="addr_from"]');
|
|
if (addrFromSelect) {
|
|
addrFromSelect.addEventListener('change', updateModalValues);
|
|
}
|
|
|
|
handleBidsPageAddress();
|
|
});
|
|
</script>
|
|
|
|
{% else %}
|
|
<section>
|
|
<div class="pl-6 pr-6 pt-0 pb-0 mt-5 h-full overflow-hidden">
|
|
<div class="pt-6 pb-6 bg-coolGray-100 dark:bg-gray-500 rounded-xl">
|
|
<div class="px-6">
|
|
<div class="w-full overflow-x-auto">
|
|
<div class="rounded-b-md">
|
|
<div class="w-full md:w-0/12">
|
|
<div class="flex flex-wrap justify-end">
|
|
<div class="w-full md:w-auto p-1.5">
|
|
<button name="newbid" value="New Bid" type="submit" class="flex flex-wrap justify-center w-full px-4 py-2.5 font-medium text-sm bg-blue-500 hover:bg-blue-600 border-blue-500 text-white border rounded-md shadow-button focus:ring-0 focus:outline-none">New Bid</button>
|
|
</div>
|
|
{% if data.sent %}
|
|
<div class="w-full md:w-auto p-1.5">
|
|
<button name="repeat_offer" value="Repeat Offer" type="submit" class="flex flex-wrap justify-center w-full px-4 py-2.5 font-medium text-sm text-coolGray-500 hover:text-coolGray-600 border border-coolGray-200 hover:border-coolGray-300 bg-white rounded-md shadow-button focus:ring-0 focus:outline-none dark:text-white dark:hover:text-white dark:bg-gray-600 dark:hover:bg-gray-700 dark:border-gray-600 dark:hover:border-gray-600">Repeat Offer</button>
|
|
</div>
|
|
<!-- todo icon -->
|
|
<div class="w-full md:w-auto p-1.5">
|
|
<button name="edit_offer" value="Edit Offer" type="submit" class="flex flex-wrap justify-center w-full px-4 py-2.5 font-medium text-sm text-coolGray-500 hover:text-coolGray-600 border border-coolGray-200 hover:border-coolGray-300 bg-white rounded-md shadow-button focus:ring-0 focus:outline-none dark:text-white dark:hover:text-white dark:bg-gray-600 dark:hover:bg-gray-700 dark:border-gray-600 dark:hover:border-gray-600">Edit Offer</button>
|
|
</div>
|
|
<!-- todo
|
|
{% if data.active_ind == 1 %}
|
|
<div class="w-full md:w-auto p-1.5"><button name="archive_offer" value="Archive Offer" type="submit" onclick="return confirmPopup();" class="flex flex-wrap justify-center w-full px-4 py-2.5 font-medium text-sm text-red-500 hover:text-red-600 border border-red-400 hover:border-red-500 bg-white rounded-md shadow-button focus:ring-0 focus:outline-none"><svg class="text-gray-500 w-5 h-5 mr-2"
|
|
xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24"><g stroke-linecap="round" stroke-width="2" fill="none" stroke="#ef5844" stroke-linejoin="round"><polyline data-cap="butt" points="23 15 16 15 16 18 8 18 8 15 1 15"></polyline><line data-cap="butt" x1="12" y1="1" x2="12" y2="11" stroke="#ef5844"></line><path d="M18.558,6a2,2,0,0,1,1.9,1.368L23,15v6a2,2,0,0,1-2,2H3a2,2,0,0,1-2-2V15L3.544,7.368A2,2,0,0,1,5.442,6"></path><polyline points="15 8 12 11 9 8" stroke="#ef5844"></polyline></g></svg>Archive Offer</button></div>
|
|
{% endif %}
|
|
-->
|
|
{% if data.was_revoked != true %}
|
|
<div class="w-full md:w-auto p-1.5">
|
|
<button name="revoke_offer" value="Revoke Offer" type="submit" onclick="return confirmPopup();" class="flex flex-wrap justify-center w-full px-4 py-2.5 font-medium text-sm text-white hover:text-red border border-red-500 hover:border-red-500 hover:bg-red-600 bg-red-500 rounded-md shadow-button focus:ring-0 focus:outline-none">Revoke Offer</button>
|
|
</div>
|
|
{% endif %}
|
|
{% endif %}
|
|
<!-- todo
|
|
<div class="w-full md:w-auto p-1.5 ml-2"><button name="check_rates" type="button" value="Lookup Rates" onclick='lookup_rates();' class="flex flex-wrap justify-center w-full px-4 py-2.5 font-medium text-sm text-coolGray-500 hover:text-coolGray-600 border border-coolGray-200 hover:border-coolGray-300 bg-white rounded-md shadow-button focus:ring-0 focus:outline-none"><svg class="mr-2"
|
|
xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 24 24"><g fill="#556987"><path fill="#556987" d="M12,3c1.989,0,3.873,0.65,5.43,1.833l-3.604,3.393l9.167,0.983L22.562,0l-3.655,3.442 C16.957,1.862,14.545,1,12,1C5.935,1,1,5.935,1,12h2C3,7.037,7.037,3,12,3z"></path><path data-color="#556987" d="M12,21c-1.989,0-3.873-0.65-5.43-1.833l3.604-3.393l-9.167-0.983L1.438,24l3.655-3.442 C7.043,22.138,9.455,23,12,23c6.065,0,11-4.935,11-11h-2C21,16.963,16.963,21,12,21z"></path></g></svg><span>Lookup Rates</span></button></div>
|
|
-->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
{% endif %}
|
|
|
|
<input type="hidden" name="sendbid" value="true">
|
|
<input type="hidden" name="confirm" value="true">
|
|
<input type="hidden" id="coin_from" value="{{ data.coin_from_ind }}">
|
|
<input type="hidden" id="coin_to" value="{{ data.coin_to_ind }}">
|
|
<input type="hidden" id="amt_var" value="{{ data.amount_negotiable }}">
|
|
<input type="hidden" id="rate_var" value="{{ data.rate_negotiable }}">
|
|
<input type="hidden" id="amount_from" value="{{ data.amt_from }}">
|
|
<input type="hidden" id="offer_rate" value="{{ data.rate }}">
|
|
<input type="hidden" name="formid" value="{{ form_id }}">
|
|
</form>
|
|
<p id="rates_display"></p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
{% include 'footer.html' %}
|
|
</body>
|
|
</html>
|