|
41 | 41 | } |
42 | 42 |
|
43 | 43 | interface BuyerInfo extends EntityInfo {} |
44 | | -
|
45 | 44 | interface SellerInfo extends EntityInfo {} |
46 | 45 |
|
47 | 46 | export let config; |
|
145 | 144 |
|
146 | 145 | onMount(() => { |
147 | 146 | checkInvoice(); |
148 | | - updateStatuses(); |
149 | 147 | }); |
150 | 148 |
|
151 | 149 | $: request, checkInvoice(); |
|
227 | 225 | requestData?.requestId! |
228 | 226 | ); |
229 | 227 |
|
230 | | - // statuses = [...statuses, "SIGN_TRANSACTION"]; |
231 | | -
|
232 | 228 | let paymentSettings = undefined; |
233 | 229 | if ( |
234 | 230 | paymentNetworkExtension?.id === |
|
247 | 243 | paymentSettings = conversion; |
248 | 244 | } |
249 | 245 |
|
| 246 | + // Get the transaction object but don't send it yet |
250 | 247 | const paymentTx = await payRequest( |
251 | 248 | requestData, |
252 | 249 | signer, |
253 | 250 | undefined, |
254 | 251 | undefined, |
255 | 252 | paymentSettings |
256 | 253 | ); |
| 254 | +
|
| 255 | + // Update first status after user has signed (transaction is created) |
| 256 | + statuses[0].done = true; |
| 257 | + statuses = statuses; |
| 258 | +
|
| 259 | + // Wait for transaction to be mined |
257 | 260 | await paymentTx.wait(); |
258 | 261 |
|
259 | | - // statuses = [...statuses, "PAYMENT_DETECTED"]; |
| 262 | + // Update second status after payment is confirmed |
| 263 | + statuses[1].done = true; |
| 264 | + statuses = statuses; |
260 | 265 |
|
| 266 | + // Wait for balance update |
261 | 267 | while (requestData.balance?.balance! < requestData.expectedAmount) { |
262 | 268 | requestData = await _request?.refresh(); |
263 | 269 | await new Promise((resolve) => setTimeout(resolve, 1000)); |
264 | 270 | } |
265 | 271 |
|
266 | | - // statuses = [...statuses, "CORRECT_NETWORK"]; |
| 272 | + // Update final status when everything is complete |
| 273 | + statuses[2].done = true; |
| 274 | + statuses = statuses; |
| 275 | +
|
267 | 276 | isPaid = true; |
268 | 277 | loading = false; |
269 | | - statuses = []; |
270 | 278 | isRequestPayed = true; |
271 | 279 | } catch (err) { |
272 | 280 | console.error("Something went wrong while paying : ", err); |
|
377 | 385 | } |
378 | 386 |
|
379 | 387 | const currentStatusIndex = statuses.length - 1; |
380 | | -
|
381 | | - const getStatusColor = (index: number) => { |
382 | | - if (statuses[index].done) return "green"; |
383 | | - return "blue"; |
384 | | - }; |
385 | | -
|
386 | | - const updateStatuses = async () => { |
387 | | - statuses[0].done = true; |
388 | | - statuses = statuses; |
389 | | -
|
390 | | - await new Promise((resolve) => setTimeout(resolve, 2000)); |
391 | | -
|
392 | | - statuses[1].done = true; |
393 | | - statuses = statuses; |
394 | | -
|
395 | | - await new Promise((resolve) => setTimeout(resolve, 2000)); |
396 | | -
|
397 | | - statuses[2].done = true; |
398 | | - statuses = statuses; |
399 | | - }; |
400 | 388 | </script> |
401 | 389 |
|
402 | 390 | <div |
|
615 | 603 | </div> |
616 | 604 | <div class="status-container"> |
617 | 605 | <div class="statuses"> |
618 | | - {#if statuses.length > 0 && loading} |
619 | | - <div class="status-wrapper"> |
620 | | - <ol class="status-list"> |
621 | | - {#each statuses as status, index} |
622 | | - <li class="status-item"> |
623 | | - <span class={`status-icon-wrapper ${getStatusColor(index)}`}> |
624 | | - {#if status.done} |
625 | | - <Check /> |
626 | | - {:else} |
627 | | - <InfoCircle /> |
628 | | - {/if} |
629 | | - </span> |
630 | | - <span class="status-text">{status.message}</span> |
631 | | - {#if index < 2} |
632 | | - <div class={`progress-line ${getStatusColor(index)}`}></div> |
| 606 | + {#if statuses[0].done} |
| 607 | + <ul class="status-list"> |
| 608 | + {#each statuses as status, index} |
| 609 | + <li class="status-item"> |
| 610 | + <span |
| 611 | + class={`status-icon-wrapper ${status.done ? "bg-success" : "bg-waiting"}`} |
| 612 | + > |
| 613 | + {#if status.done} |
| 614 | + <svg |
| 615 | + width="24" |
| 616 | + height="25" |
| 617 | + viewBox="0 0 24 25" |
| 618 | + fill="none" |
| 619 | + xmlns="http://www.w3.org/2000/svg" |
| 620 | + > |
| 621 | + <path |
| 622 | + d="M6 12.5L10.2426 16.7426L18.727 8.25732" |
| 623 | + stroke="#328965" |
| 624 | + stroke-width="2" |
| 625 | + stroke-linecap="round" |
| 626 | + stroke-linejoin="round" |
| 627 | + /> |
| 628 | + </svg> |
| 629 | + {:else} |
| 630 | + <svg |
| 631 | + width="25" |
| 632 | + height="25" |
| 633 | + viewBox="0 0 25 25" |
| 634 | + fill="none" |
| 635 | + xmlns="http://www.w3.org/2000/svg" |
| 636 | + > |
| 637 | + <path |
| 638 | + d="M12.334 11.5V16.5M12.334 21.5C7.36342 21.5 3.33398 17.4706 3.33398 12.5C3.33398 7.52944 7.36342 3.5 12.334 3.5C17.3045 3.5 21.334 7.52944 21.334 12.5C21.334 17.4706 17.3045 21.5 12.334 21.5ZM12.3838 8.5V8.6L12.2842 8.6002V8.5H12.3838Z" |
| 639 | + stroke="#3D72FF" |
| 640 | + stroke-width="2" |
| 641 | + stroke-linecap="round" |
| 642 | + stroke-linejoin="round" |
| 643 | + /> |
| 644 | + </svg> |
633 | 645 | {/if} |
634 | | - </li> |
635 | | - {/each} |
636 | | - </ol> |
637 | | - </div> |
| 646 | + </span> |
| 647 | + <span class="status-text">{status.message}</span> |
| 648 | + <div |
| 649 | + class={`progress-line ${ |
| 650 | + status.done || statuses[index + 1]?.done |
| 651 | + ? "bg-green" |
| 652 | + : index <= currentStatusIndex |
| 653 | + ? "bg-blue" |
| 654 | + : "bg-zinc-light" |
| 655 | + }`} |
| 656 | + ></div> |
| 657 | + </li> |
| 658 | + {/each} |
| 659 | + </ul> |
638 | 660 | {/if} |
639 | 661 | </div> |
640 | 662 |
|
|
653 | 675 | padding="px-[12px] py-[6px]" |
654 | 676 | onClick={approve} |
655 | 677 | /> |
656 | | - {:else if approved && !isPaid && !isPayee && !unsupportedNetwork} |
| 678 | + {:else if approved && !isPaid && !isPayee && !unsupportedNetwork && !statuses[0].done} |
657 | 679 | <Button |
658 | 680 | type="button" |
659 | 681 | text="Pay" |
|
858 | 880 | .status-container { |
859 | 881 | display: flex; |
860 | 882 | align-items: center; |
861 | | - gap: 10px; |
862 | 883 | justify-content: center; |
863 | 884 | margin-top: 1rem; |
864 | 885 | } |
|
867 | 888 | display: flex; |
868 | 889 | flex-direction: column; |
869 | 890 | gap: 10px; |
| 891 | + width: 100%; |
| 892 | + margin-bottom: 32px; |
870 | 893 | } |
871 | 894 |
|
872 | 895 | .status { |
|
882 | 905 | gap: 0.25rem; |
883 | 906 | } |
884 | 907 |
|
| 908 | + .status-list { |
| 909 | + display: flex; |
| 910 | + align-items: center; |
| 911 | + list-style: none; |
| 912 | + } |
| 913 | +
|
| 914 | + .status-item { |
| 915 | + display: flex; |
| 916 | + align-items: center; |
| 917 | + position: relative; |
| 918 | + text-align: center; |
| 919 | + width: 45%; |
| 920 | + } |
| 921 | +
|
| 922 | + .status-item:first-child { |
| 923 | + padding-left: 50px; |
| 924 | + } |
| 925 | +
|
| 926 | + .status-item:first-child .status-text { |
| 927 | + padding-left: 50px; |
| 928 | + } |
| 929 | +
|
| 930 | + .status-item:last-child { |
| 931 | + width: 20%; |
| 932 | + } |
| 933 | +
|
| 934 | + .status-item:last-child .progress-line { |
| 935 | + width: 170px; |
| 936 | + } |
| 937 | +
|
| 938 | + .progress-line { |
| 939 | + position: absolute; |
| 940 | + left: 40%; |
| 941 | + height: 8px; |
| 942 | + z-index: 0; |
| 943 | + transform: translateX(-50%); |
| 944 | + width: 300px; |
| 945 | + border-radius: 100px; |
| 946 | + z-index: 10; |
| 947 | + } |
| 948 | +
|
| 949 | + .status-icon-wrapper { |
| 950 | + display: flex; |
| 951 | + justify-content: center; |
| 952 | + align-items: center; |
| 953 | + width: 40px; |
| 954 | + height: 40px; |
| 955 | + border-radius: 9999px; |
| 956 | + padding: 4px; |
| 957 | + position: relative; |
| 958 | + z-index: 20; |
| 959 | + } |
| 960 | +
|
| 961 | + .status-text { |
| 962 | + font-size: 14px; |
| 963 | + color: #272d41; |
| 964 | + position: absolute; |
| 965 | + top: -30px; |
| 966 | + left: -30px; |
| 967 | + } |
| 968 | +
|
| 969 | + .checkmark { |
| 970 | + margin-left: 5px; |
| 971 | + color: #58e1a5; |
| 972 | + } |
| 973 | +
|
885 | 974 | .invoice-view-actions { |
886 | 975 | padding: 0.75rem 1rem; |
887 | 976 | font-size: 0.875rem; |
|
921 | 1010 | background-color: var(--secondaryColor); |
922 | 1011 | } |
923 | 1012 |
|
| 1013 | + .bg-blue { |
| 1014 | + background-color: #759aff; |
| 1015 | + } |
| 1016 | +
|
924 | 1017 | .bg-green { |
925 | 1018 | background-color: #0bb489; |
926 | 1019 | } |
927 | 1020 |
|
| 1021 | + .bg-success { |
| 1022 | + background-color: #cdf6e4; |
| 1023 | + } |
| 1024 | +
|
| 1025 | + .bg-waiting { |
| 1026 | + background-color: #c7e7ff; |
| 1027 | + } |
| 1028 | +
|
928 | 1029 | .bg-zinc { |
929 | 1030 | background-color: #a1a1aa; |
930 | 1031 | } |
|
944 | 1045 | .email-link:hover { |
945 | 1046 | text-decoration: underline; |
946 | 1047 | } |
947 | | -
|
948 | | - .status-wrapper { |
949 | | - margin-bottom: 32px; |
950 | | - } |
951 | | -
|
952 | | - .status-list { |
953 | | - display: flex; |
954 | | - align-items: center; |
955 | | - list-style: none; |
956 | | - padding: 0; |
957 | | - } |
958 | | -
|
959 | | - .status-item { |
960 | | - display: flex; |
961 | | - align-items: center; |
962 | | - position: relative; |
963 | | - text-align: center; /* Center text under icons */ |
964 | | - width: 150px; |
965 | | - } |
966 | | -
|
967 | | - .progress-line { |
968 | | - position: absolute; |
969 | | - top: 50%; |
970 | | - left: 50%; |
971 | | - height: 6px; |
972 | | - background-color: #759aff; /* Default line color */ |
973 | | - z-index: 0; |
974 | | - transform: translateX(-50%); |
975 | | - width: 180px; |
976 | | - border-radius: 100px; |
977 | | - z-index: 10; |
978 | | - } |
979 | | -
|
980 | | - .status-icon-wrapper { |
981 | | - display: flex; |
982 | | - justify-content: center; |
983 | | - align-items: center; |
984 | | - width: 29px; |
985 | | - height: 29px; |
986 | | - background-color: #dbeafe; |
987 | | - border-radius: 9999px; |
988 | | - padding: 4px; |
989 | | - box-shadow: 0 0 0 8px white; |
990 | | - position: relative; |
991 | | - z-index: 20; |
992 | | - } |
993 | | -
|
994 | | - .status-text { |
995 | | - font-size: 14px; /* Adjust font size */ |
996 | | - color: #272d41; /* Text color */ |
997 | | - position: absolute; |
998 | | - top: -30px; |
999 | | - left: -25px; |
1000 | | - } |
1001 | | -
|
1002 | | - .checkmark { |
1003 | | - margin-left: 5px; /* Space between icon and checkmark */ |
1004 | | - color: #58e1a5; /* Checkmark color */ |
1005 | | - } |
1006 | 1048 | </style> |
0 commit comments