2025-03-15 15:28:44 +01:00
|
|
|
const PublishOfferButton = require('../components/PublishOfferButton');
|
2025-03-15 16:36:31 +01:00
|
|
|
const BuyOrSellButtonGroup = require('../components/BuyOrSellButtonGroup');
|
2025-03-15 17:28:48 +01:00
|
|
|
const PremiumSelector = require('../components/PremiumSelector');
|
2025-03-17 17:52:15 +01:00
|
|
|
const PriceDisplay = require('../components/PriceDisplay');
|
2025-03-22 17:11:24 +01:00
|
|
|
const AmountInput = require('../components/AmountInput');
|
2025-03-22 17:46:27 +01:00
|
|
|
const PlaceInput = require('../components/PlaceInput');
|
|
|
|
|
const TimeInput = require('../components/TimeInput');
|
2025-03-23 11:10:36 +01:00
|
|
|
const BitcoinMethodCheckboxes = require('../components/BitcoinMethodCheckboxes');
|
2025-03-25 16:14:18 +01:00
|
|
|
const TrustCheckboxes = require('../components/TrustCheckboxes');
|
2025-03-25 16:56:10 +01:00
|
|
|
const BigNotesCheckbox = require('../components/BigNotesCheckbox');
|
2025-03-25 16:52:24 +01:00
|
|
|
|
2025-03-30 19:05:09 +02:00
|
|
|
const offerCreatedPopup = document.getElementById('offer-created-confirmation');
|
2025-03-30 18:47:06 +02:00
|
|
|
function toggleOfferCreatedAlert() {
|
|
|
|
|
offerCreatedPopup.classList.remove('max-size-zero');
|
|
|
|
|
offerCreatedPopup.classList.add('revealed');
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
offerCreatedPopup.classList.remove('revealed');
|
|
|
|
|
}, 3000);
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
offerCreatedPopup.classList.add('max-size-zero');
|
|
|
|
|
}, 4000);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class CreateOfferModal {
|
2025-03-30 19:05:09 +02:00
|
|
|
// Actual creation logic to be provided by a service
|
|
|
|
|
// Stop relying on IDs
|
|
|
|
|
constructor({ parentElement, onCreationCallback }) {
|
2025-03-30 18:47:06 +02:00
|
|
|
this.element = null;
|
|
|
|
|
this.parentElement = parentElement;
|
2025-03-30 19:05:09 +02:00
|
|
|
this.onCreationCallback = onCreationCallback;
|
2025-03-30 18:47:06 +02:00
|
|
|
|
|
|
|
|
this.publishOfferButton = null;
|
|
|
|
|
this.buyOrSellButtonGroup = null;
|
|
|
|
|
this.premiumSelector = null;
|
|
|
|
|
this.amountInput = null;
|
|
|
|
|
this.placeInput = null;
|
|
|
|
|
this.timeInput = null;
|
|
|
|
|
this.btcMethodCheckboxes = null;
|
|
|
|
|
this.trustCheckboxes = null;
|
|
|
|
|
this.bigNotesCheckbox = null;
|
|
|
|
|
}
|
2025-03-15 15:26:57 +01:00
|
|
|
|
2025-03-30 18:47:06 +02:00
|
|
|
render() {
|
|
|
|
|
const modalRoot = document.createElement('div');
|
|
|
|
|
this.element = modalRoot;
|
|
|
|
|
modalRoot.id = 'create-offer-modal-root';
|
|
|
|
|
modalRoot.className = 'full-screen-modal-background';
|
|
|
|
|
|
|
|
|
|
const modal = document.createElement('div');
|
|
|
|
|
modal.className = 'full-screen-modal';
|
|
|
|
|
modal.id = 'create-offer-root';
|
|
|
|
|
|
|
|
|
|
const controls = document.createElement('div');
|
|
|
|
|
controls.id = 'create-offer-controls';
|
|
|
|
|
|
|
|
|
|
const title = document.createElement('h2');
|
|
|
|
|
title.textContent = 'Añade los detalles de tu oferta';
|
|
|
|
|
|
|
|
|
|
const sections = [
|
|
|
|
|
{ id: 'buy-or-sell-area', class: 'create-offer-step', title: '' },
|
|
|
|
|
{
|
|
|
|
|
id: 'premium-area',
|
|
|
|
|
class: 'create-offer-step',
|
|
|
|
|
title: 'Premium',
|
|
|
|
|
contentId: 'premium-content-area',
|
|
|
|
|
},
|
|
|
|
|
{ id: 'amount-area', class: 'create-offer-step', title: '¿Cuánto?' },
|
|
|
|
|
{
|
|
|
|
|
id: 'place-and-time-area',
|
|
|
|
|
class: 'create-offer-step',
|
|
|
|
|
title: '¿Dónde y cuándo?',
|
|
|
|
|
contentId: 'place-and-time-boxes',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 'bitcoin-methods-area',
|
|
|
|
|
class: 'create-offer-step',
|
|
|
|
|
title: '¿Cómo se mueve el Bitcoin?',
|
|
|
|
|
contentId: 'bitcoin-methods-checkboxes',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 'trust-area',
|
|
|
|
|
class: 'create-offer-step',
|
|
|
|
|
title: '¿Quién puede ver la oferta?',
|
|
|
|
|
contentId: 'trusted-checkboxes-area',
|
|
|
|
|
},
|
|
|
|
|
{ id: 'other-area', class: 'create-offer-step', title: 'Extras' },
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
controls.appendChild(title);
|
|
|
|
|
|
|
|
|
|
sections.forEach((section) => {
|
|
|
|
|
const div = document.createElement('div');
|
|
|
|
|
div.id = section.id;
|
|
|
|
|
div.className = section.class;
|
|
|
|
|
if (section.title) {
|
|
|
|
|
const heading = document.createElement('h3');
|
|
|
|
|
heading.textContent = section.title;
|
|
|
|
|
div.appendChild(heading);
|
|
|
|
|
}
|
|
|
|
|
if (section.contentId) {
|
|
|
|
|
const contentDiv = document.createElement('div');
|
|
|
|
|
contentDiv.id = section.contentId;
|
|
|
|
|
div.appendChild(contentDiv);
|
|
|
|
|
}
|
|
|
|
|
controls.appendChild(div);
|
|
|
|
|
});
|
2025-03-15 16:36:31 +01:00
|
|
|
|
2025-03-30 18:47:06 +02:00
|
|
|
const submitButtonArea = document.createElement('div');
|
|
|
|
|
submitButtonArea.id = 'submit-button-area';
|
2025-03-17 16:45:20 +01:00
|
|
|
|
2025-03-30 18:47:06 +02:00
|
|
|
const closeButtonArea = document.createElement('div');
|
|
|
|
|
closeButtonArea.id = 'close-offer-controls-area';
|
|
|
|
|
const closeButton = document.createElement('button');
|
|
|
|
|
closeButton.id = 'close-offer';
|
|
|
|
|
closeButton.className = 'button-secondary button-medium';
|
|
|
|
|
closeButton.textContent = 'Volver';
|
|
|
|
|
closeButtonArea.appendChild(closeButton);
|
2025-03-19 19:17:23 +01:00
|
|
|
|
2025-03-30 18:47:06 +02:00
|
|
|
controls.appendChild(submitButtonArea);
|
|
|
|
|
controls.appendChild(closeButtonArea);
|
2025-03-22 17:24:25 +01:00
|
|
|
|
2025-03-30 18:47:06 +02:00
|
|
|
modal.appendChild(controls);
|
|
|
|
|
modalRoot.appendChild(modal);
|
2025-03-22 17:24:25 +01:00
|
|
|
|
2025-03-30 18:47:06 +02:00
|
|
|
this.parentElement.appendChild(this.element);
|
2025-03-22 17:46:27 +01:00
|
|
|
|
2025-03-30 18:47:06 +02:00
|
|
|
const createOfferEventBus = new EventTarget();
|
2025-03-22 17:46:27 +01:00
|
|
|
|
2025-03-30 18:47:06 +02:00
|
|
|
const mockPriceProvidingCallback = () => {
|
|
|
|
|
return Math.floor(Math.random() * (95000 - 70000 + 1) + 70000);
|
|
|
|
|
};
|
2025-03-23 11:00:06 +01:00
|
|
|
|
2025-03-30 18:47:06 +02:00
|
|
|
this.publishOfferButton = new PublishOfferButton({
|
|
|
|
|
parentElement: document.getElementById('submit-button-area'),
|
|
|
|
|
id: 'button-submit-offer',
|
|
|
|
|
onClickCallback: async () => {
|
|
|
|
|
await this.createOffer();
|
2025-03-30 19:05:09 +02:00
|
|
|
await this.onCreationCallback();
|
2025-03-30 19:14:34 +02:00
|
|
|
await this.toggleOfferCreatedAlert();
|
2025-03-30 18:47:06 +02:00
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
this.publishOfferButton.render();
|
2025-03-23 11:00:06 +01:00
|
|
|
|
2025-03-30 18:47:06 +02:00
|
|
|
this.buyOrSellButtonGroup = new BuyOrSellButtonGroup({
|
|
|
|
|
parentElement: document.getElementById('buy-or-sell-area'),
|
|
|
|
|
id: 'button-group-buy-or-sell',
|
|
|
|
|
});
|
|
|
|
|
this.buyOrSellButtonGroup.render();
|
2025-03-25 16:11:17 +01:00
|
|
|
|
2025-03-30 18:47:06 +02:00
|
|
|
this.premiumSelector = new PremiumSelector({
|
|
|
|
|
parentElement: document.getElementById('premium-content-area'),
|
|
|
|
|
id: 'premium-selector-area',
|
|
|
|
|
eventSink: createOfferEventBus,
|
|
|
|
|
});
|
|
|
|
|
this.premiumSelector.render();
|
2025-03-25 16:11:17 +01:00
|
|
|
|
2025-03-30 18:47:06 +02:00
|
|
|
const priceDisplay = new PriceDisplay({
|
|
|
|
|
parentElement: document.getElementById('premium-content-area'),
|
|
|
|
|
id: 'premium-price-display-area',
|
|
|
|
|
premiumProvidingCallback: () => {
|
|
|
|
|
return this.premiumSelector.getPremium();
|
|
|
|
|
},
|
|
|
|
|
priceProvidingCallback: mockPriceProvidingCallback,
|
|
|
|
|
});
|
|
|
|
|
priceDisplay.render();
|
|
|
|
|
createOfferEventBus.addEventListener('premium-changed', () => {
|
|
|
|
|
priceDisplay.updatePrices();
|
|
|
|
|
});
|
2025-03-25 16:11:17 +01:00
|
|
|
|
2025-03-30 18:47:06 +02:00
|
|
|
this.amountInput = new AmountInput({
|
|
|
|
|
parentElement: document.getElementById('amount-area'),
|
|
|
|
|
id: 'amount-area-content',
|
|
|
|
|
});
|
2025-03-25 16:52:24 +01:00
|
|
|
|
2025-03-30 18:47:06 +02:00
|
|
|
this.amountInput.render();
|
2025-03-13 11:28:07 +01:00
|
|
|
|
2025-03-30 18:47:06 +02:00
|
|
|
this.placeInput = new PlaceInput({
|
|
|
|
|
parentElement: document.getElementById('place-and-time-boxes'),
|
|
|
|
|
id: 'place-input',
|
|
|
|
|
});
|
2025-03-13 11:28:07 +01:00
|
|
|
|
2025-03-30 18:47:06 +02:00
|
|
|
this.placeInput.render();
|
2025-03-13 11:28:07 +01:00
|
|
|
|
2025-03-30 18:47:06 +02:00
|
|
|
this.timeInput = new TimeInput({
|
|
|
|
|
parentElement: document.getElementById('place-and-time-boxes'),
|
|
|
|
|
id: 'time-input',
|
|
|
|
|
});
|
2025-03-12 16:28:44 +01:00
|
|
|
|
2025-03-30 18:47:06 +02:00
|
|
|
this.timeInput.render();
|
2025-03-12 16:28:44 +01:00
|
|
|
|
2025-03-30 18:47:06 +02:00
|
|
|
this.btcMethodCheckboxes = new BitcoinMethodCheckboxes({
|
|
|
|
|
parentElement: document.getElementById('bitcoin-methods-checkboxes'),
|
|
|
|
|
});
|
2025-03-12 16:28:44 +01:00
|
|
|
|
2025-03-30 18:47:06 +02:00
|
|
|
this.btcMethodCheckboxes.render();
|
|
|
|
|
|
|
|
|
|
this.trustCheckboxes = new TrustCheckboxes({
|
|
|
|
|
parentElement: document.getElementById('trusted-checkboxes-area'),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
this.trustCheckboxes.render();
|
|
|
|
|
|
|
|
|
|
this.bigNotesCheckbox = new BigNotesCheckbox({
|
|
|
|
|
parentElement: document.getElementById('other-area'),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
this.bigNotesCheckbox.render();
|
2025-03-12 16:28:44 +01:00
|
|
|
}
|
|
|
|
|
|
2025-03-30 18:47:06 +02:00
|
|
|
toggle() {
|
|
|
|
|
this.element.classList.toggle('shown');
|
2025-03-12 16:28:44 +01:00
|
|
|
}
|
|
|
|
|
|
2025-03-30 18:47:06 +02:00
|
|
|
async createOffer() {
|
|
|
|
|
const wants = this.buyOrSellButtonGroup.wants();
|
2025-03-12 16:28:44 +01:00
|
|
|
|
2025-03-30 18:47:06 +02:00
|
|
|
const premium = this.premiumSelector.getPremium();
|
|
|
|
|
const trade_amount_eur = this.amountInput.intEurAmount;
|
|
|
|
|
const location_details = this.placeInput.inputText;
|
|
|
|
|
const time_availability_details = this.timeInput.inputText;
|
|
|
|
|
const is_onchain_accepted = this.btcMethodCheckboxes.isOnchainAccepted;
|
|
|
|
|
const is_lightning_accepted = this.btcMethodCheckboxes.isLightningAccepted;
|
|
|
|
|
const show_offer_to_trusted = this.trustCheckboxes.showOfferToTrusted;
|
2025-03-25 16:11:17 +01:00
|
|
|
const show_offer_to_trusted_trusted =
|
2025-03-30 18:47:06 +02:00
|
|
|
this.trustCheckboxes.showOfferToTrustedTrusted;
|
|
|
|
|
const show_offer_to_all_members =
|
|
|
|
|
this.trustCheckboxes.showOfferToAllMembers;
|
|
|
|
|
const are_big_notes_accepted = this.bigNotesCheckbox.areBigNotesAccepted;
|
2025-03-12 16:28:44 +01:00
|
|
|
|
|
|
|
|
const offerDetails = {
|
|
|
|
|
wants,
|
|
|
|
|
premium,
|
|
|
|
|
trade_amount_eur,
|
|
|
|
|
location_details,
|
|
|
|
|
time_availability_details,
|
|
|
|
|
is_onchain_accepted,
|
|
|
|
|
is_lightning_accepted,
|
|
|
|
|
show_offer_to_trusted,
|
|
|
|
|
show_offer_to_trusted_trusted,
|
|
|
|
|
show_offer_to_all_members,
|
|
|
|
|
are_big_notes_accepted,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
await fetch('/api/offer', {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
headers: {
|
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
|
},
|
|
|
|
|
body: JSON.stringify({ offerDetails }),
|
|
|
|
|
});
|
|
|
|
|
|
2025-03-30 18:47:06 +02:00
|
|
|
this.toggle();
|
2025-03-12 16:28:44 +01:00
|
|
|
}
|
2025-03-30 18:47:06 +02:00
|
|
|
}
|
2025-03-12 16:28:44 +01:00
|
|
|
|
2025-03-30 18:47:06 +02:00
|
|
|
function offersPage() {
|
|
|
|
|
const createOfferModal = new CreateOfferModal({
|
|
|
|
|
parentElement: document.body,
|
2025-03-30 19:05:09 +02:00
|
|
|
onCreationCallback: async () => {
|
|
|
|
|
await myOffers.getOffersFromApi();
|
|
|
|
|
await myOffers.render();
|
2025-03-30 19:14:34 +02:00
|
|
|
await toggleOfferCreatedAlert();
|
2025-03-30 19:05:09 +02:00
|
|
|
},
|
2025-03-30 18:47:06 +02:00
|
|
|
});
|
|
|
|
|
createOfferModal.render();
|
|
|
|
|
// -----------
|
|
|
|
|
const navbuttonHome = document.getElementById('navbutton-home');
|
|
|
|
|
const navbuttonOffers = document.getElementById('navbutton-offers');
|
|
|
|
|
|
|
|
|
|
navbuttonHome.addEventListener('click', () => {
|
|
|
|
|
window.location.href = '/home';
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
navbuttonOffers.addEventListener('click', () => {
|
|
|
|
|
window.location.href = '/offers';
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const buttonStartCreateOffer = document.getElementById(
|
|
|
|
|
'button-start-create-offer'
|
|
|
|
|
);
|
|
|
|
|
const buttonViewMyOffers = document.getElementById('button-view-my-offers');
|
|
|
|
|
const closeOffer = document.getElementById('close-offer');
|
|
|
|
|
const createOfferModalRoot = document.getElementById(
|
|
|
|
|
'create-offer-modal-root'
|
|
|
|
|
);
|
|
|
|
|
const viewMyOffersRoot = document.getElementById('view-my-offers-root');
|
|
|
|
|
|
|
|
|
|
const offerDeletedPopup = document.getElementById(
|
|
|
|
|
'offer-deleted-confirmation'
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const ownOffersContainer = document.getElementById('own-offers-container');
|
|
|
|
|
|
|
|
|
|
function toggleCreateOfferModal() {
|
|
|
|
|
createOfferModalRoot.classList.toggle('shown');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function toggleViewMyOffersPanel() {
|
|
|
|
|
viewMyOffersRoot.style.display =
|
|
|
|
|
viewMyOffersRoot.style.display === 'block' ? 'none' : 'block';
|
2025-03-12 16:28:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function toggleOfferDeletedAlert() {
|
|
|
|
|
offerDeletedPopup.classList.remove('max-size-zero');
|
|
|
|
|
offerDeletedPopup.classList.add('revealed');
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
offerDeletedPopup.classList.remove('revealed');
|
|
|
|
|
}, 3000);
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
offerDeletedPopup.classList.add('max-size-zero');
|
|
|
|
|
}, 4000);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class Offer {
|
|
|
|
|
constructor(offerData) {
|
|
|
|
|
this.uuid = offerData.uuid;
|
|
|
|
|
this.public_key = offerData.public_key;
|
|
|
|
|
this.wants = offerData.wants;
|
|
|
|
|
this.premium = offerData.premium;
|
|
|
|
|
this.trade_amount_eur = offerData.trade_amount_eur;
|
|
|
|
|
this.location_details = offerData.location_details;
|
|
|
|
|
this.time_availability_details = offerData.time_availability_details;
|
|
|
|
|
this.show_offer_to_trusted = offerData.show_offer_to_trusted;
|
|
|
|
|
this.show_offer_to_trusted_trusted =
|
|
|
|
|
offerData.show_offer_to_trusted_trusted;
|
|
|
|
|
this.show_offer_to_all_members = offerData.show_offer_to_all_members;
|
|
|
|
|
this.is_onchain_accepted = offerData.is_onchain_accepted;
|
|
|
|
|
this.is_lightning_accepted = offerData.is_lightning_accepted;
|
|
|
|
|
this.are_big_notes_accepted = offerData.are_big_notes_accepted;
|
|
|
|
|
this.created_at = offerData.created_at;
|
|
|
|
|
this.last_updated_at = offerData.last_updated_at;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
buildHTML() {
|
|
|
|
|
const offerCard = document.createElement('div');
|
|
|
|
|
offerCard.classList.add('myoffer-card');
|
|
|
|
|
offerCard.classList.add('shadowed-round-area');
|
|
|
|
|
|
|
|
|
|
const tradeDescDiv = document.createElement('div');
|
|
|
|
|
tradeDescDiv.classList.add('trade-desc');
|
|
|
|
|
|
|
|
|
|
const youBuyText = document.createElement('p');
|
|
|
|
|
youBuyText.classList.add('offer-card-content-title');
|
|
|
|
|
youBuyText.innerText = 'Compras';
|
|
|
|
|
tradeDescDiv.append(youBuyText);
|
|
|
|
|
|
|
|
|
|
const youBuyData = document.createElement('p');
|
|
|
|
|
youBuyData.classList.add('offer-card-content-data');
|
|
|
|
|
if (this.wants === 'BTC') {
|
|
|
|
|
youBuyData.innerText = `${this.trade_amount_eur * 1021} sats`;
|
|
|
|
|
}
|
|
|
|
|
if (this.wants === 'EUR') {
|
|
|
|
|
youBuyData.innerText = `${this.trade_amount_eur} €`;
|
|
|
|
|
}
|
|
|
|
|
tradeDescDiv.append(youBuyData);
|
|
|
|
|
|
|
|
|
|
const youSellText = document.createElement('p');
|
|
|
|
|
youSellText.id = 'you-sell-title';
|
|
|
|
|
youSellText.classList.add('offer-card-content-title');
|
|
|
|
|
youSellText.innerText = 'Vendes';
|
|
|
|
|
tradeDescDiv.append(youSellText);
|
|
|
|
|
|
|
|
|
|
const youSellData = document.createElement('p');
|
|
|
|
|
youSellData.classList.add('offer-card-content-data');
|
|
|
|
|
if (this.wants === 'BTC') {
|
|
|
|
|
youSellData.innerText = `${this.trade_amount_eur} €`;
|
|
|
|
|
}
|
|
|
|
|
if (this.wants === 'EUR') {
|
|
|
|
|
youSellData.innerText = `${this.trade_amount_eur * 1021} sats`;
|
|
|
|
|
}
|
|
|
|
|
tradeDescDiv.append(youSellData);
|
|
|
|
|
|
|
|
|
|
const premiumDescDiv = document.createElement('div');
|
|
|
|
|
premiumDescDiv.classList.add('premium-desc');
|
|
|
|
|
|
|
|
|
|
const premiumTitle = document.createElement('p');
|
|
|
|
|
premiumTitle.classList.add('offer-card-content-title');
|
|
|
|
|
premiumTitle.innerText = 'Premium';
|
|
|
|
|
premiumDescDiv.append(premiumTitle);
|
|
|
|
|
|
|
|
|
|
const premiumData = document.createElement('p');
|
|
|
|
|
premiumData.classList.add('offer-card-content-data');
|
|
|
|
|
premiumData.innerText = `${this.premium * 100} %`;
|
|
|
|
|
premiumDescDiv.append(premiumData);
|
|
|
|
|
|
|
|
|
|
const offerPriceTitle = document.createElement('p');
|
|
|
|
|
offerPriceTitle.classList.add('offer-card-content-title');
|
|
|
|
|
offerPriceTitle.innerText = 'Precio oferta';
|
|
|
|
|
premiumDescDiv.append(offerPriceTitle);
|
|
|
|
|
|
|
|
|
|
const offerPriceData = document.createElement('p');
|
|
|
|
|
offerPriceData.classList.add('offer-card-content-data');
|
|
|
|
|
offerPriceData.innerText = `90000 €/BTC`;
|
|
|
|
|
premiumDescDiv.append(offerPriceData);
|
|
|
|
|
|
|
|
|
|
const marketPriceTitle = document.createElement('p');
|
|
|
|
|
marketPriceTitle.classList.add('offer-card-content-title');
|
|
|
|
|
marketPriceTitle.innerText = 'Precio mercado';
|
|
|
|
|
premiumDescDiv.append(marketPriceTitle);
|
|
|
|
|
|
|
|
|
|
const marketPriceData = document.createElement('p');
|
|
|
|
|
marketPriceData.innerText = `88000 €/BTC`;
|
|
|
|
|
premiumDescDiv.append(marketPriceData);
|
|
|
|
|
|
|
|
|
|
const whereDescDiv = document.createElement('div');
|
|
|
|
|
whereDescDiv.classList.add('where-desc');
|
|
|
|
|
|
|
|
|
|
const whereDescTitle = document.createElement('p');
|
|
|
|
|
whereDescTitle.classList.add('offer-card-content-title');
|
|
|
|
|
whereDescTitle.innerText = 'Dónde';
|
|
|
|
|
whereDescDiv.append(whereDescTitle);
|
|
|
|
|
|
|
|
|
|
const whereDescData = document.createElement('p');
|
|
|
|
|
whereDescData.classList.add('offer-long-text');
|
|
|
|
|
whereDescData.innerText = `${this.location_details}`;
|
|
|
|
|
whereDescDiv.append(whereDescData);
|
|
|
|
|
|
|
|
|
|
const whenDescDiv = document.createElement('div');
|
|
|
|
|
whenDescDiv.classList.add('when-desc');
|
|
|
|
|
|
|
|
|
|
const whenDescTitle = document.createElement('p');
|
|
|
|
|
whenDescTitle.classList.add('offer-card-content-title');
|
|
|
|
|
whenDescTitle.innerText = 'Cúando';
|
|
|
|
|
whenDescDiv.append(whenDescTitle);
|
|
|
|
|
|
|
|
|
|
const whenDescData = document.createElement('p');
|
|
|
|
|
whenDescData.classList.add('offer-long-text');
|
|
|
|
|
whenDescData.innerText = `${this.time_availability_details}`;
|
|
|
|
|
whenDescDiv.append(whenDescData);
|
|
|
|
|
|
|
|
|
|
const bitcoinMethodsDiv = document.createElement('div');
|
|
|
|
|
bitcoinMethodsDiv.classList.add('bitcoin-methods-desc');
|
|
|
|
|
|
|
|
|
|
const bitcoinMethodsTitle = document.createElement('p');
|
|
|
|
|
bitcoinMethodsTitle.classList.add('offer-card-content-title');
|
|
|
|
|
bitcoinMethodsTitle.innerText = 'Protocolos Bitcoin aceptados';
|
|
|
|
|
bitcoinMethodsDiv.append(bitcoinMethodsTitle);
|
|
|
|
|
|
|
|
|
|
const onchainAcceptedContainer = document.createElement('div');
|
|
|
|
|
onchainAcceptedContainer.classList.add('left-icon-checkboxed-field');
|
|
|
|
|
if (this.is_onchain_accepted) {
|
|
|
|
|
const onchainIcon = document.createElement('img');
|
|
|
|
|
onchainIcon.src = '/img/chains-lasecagold.svg';
|
|
|
|
|
const onchainText = document.createElement('p');
|
|
|
|
|
onchainText.innerText = 'Onchain';
|
|
|
|
|
const checkIcon = document.createElement('img');
|
|
|
|
|
checkIcon.src = '/img/circle-check-green.svg';
|
|
|
|
|
|
|
|
|
|
onchainAcceptedContainer.append(onchainIcon, onchainText, checkIcon);
|
|
|
|
|
} else {
|
|
|
|
|
const onchainIcon = document.createElement('img');
|
|
|
|
|
onchainIcon.src = '/img/chains-gray.svg';
|
|
|
|
|
const onchainText = document.createElement('p');
|
|
|
|
|
onchainText.innerText = 'Onchain';
|
|
|
|
|
const checkIcon = document.createElement('img');
|
|
|
|
|
checkIcon.src = '/img/circle-xmark-gray.svg';
|
|
|
|
|
|
|
|
|
|
onchainAcceptedContainer.append(onchainIcon, onchainText, checkIcon);
|
|
|
|
|
}
|
|
|
|
|
const lightningAcceptedContainer = document.createElement('div');
|
|
|
|
|
|
|
|
|
|
lightningAcceptedContainer.classList.add('left-icon-checkboxed-field');
|
|
|
|
|
if (this.is_lightning_accepted) {
|
|
|
|
|
const lightningIcon = document.createElement('img');
|
|
|
|
|
lightningIcon.src = '/img/bolt-lightning-lasecagold.svg';
|
|
|
|
|
const lightningText = document.createElement('p');
|
|
|
|
|
lightningText.innerText = 'Lightning';
|
|
|
|
|
const checkIcon = document.createElement('img');
|
|
|
|
|
checkIcon.src = '/img/circle-check-green.svg';
|
|
|
|
|
|
|
|
|
|
lightningAcceptedContainer.append(
|
|
|
|
|
lightningIcon,
|
|
|
|
|
lightningText,
|
|
|
|
|
checkIcon
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
const lightningIcon = document.createElement('img');
|
|
|
|
|
lightningIcon.src = '/img/bolt-lightning-gray.svg';
|
|
|
|
|
const lightningText = document.createElement('p');
|
|
|
|
|
lightningText.innerText = 'Lightning';
|
|
|
|
|
const checkIcon = document.createElement('img');
|
|
|
|
|
checkIcon.src = '/img/circle-xmark-gray.svg';
|
|
|
|
|
|
|
|
|
|
lightningAcceptedContainer.append(
|
|
|
|
|
lightningIcon,
|
|
|
|
|
lightningText,
|
|
|
|
|
checkIcon
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bitcoinMethodsDiv.append(
|
|
|
|
|
onchainAcceptedContainer,
|
|
|
|
|
lightningAcceptedContainer
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const visibilityDiv = document.createElement('div');
|
|
|
|
|
visibilityDiv.classList.add('visibility-desc');
|
|
|
|
|
|
|
|
|
|
const visibilityTitle = document.createElement('p');
|
|
|
|
|
visibilityTitle.classList.add('offer-card-content-title');
|
|
|
|
|
visibilityTitle.innerText = 'Visibilidad';
|
|
|
|
|
visibilityDiv.append(visibilityTitle);
|
|
|
|
|
|
|
|
|
|
const showOfferToTrustedContainer = document.createElement('div');
|
|
|
|
|
showOfferToTrustedContainer.classList.add('right-icon-checkboxed-field');
|
|
|
|
|
|
|
|
|
|
if (this.show_offer_to_trusted) {
|
|
|
|
|
const showOfferToTrustedIcon = document.createElement('img');
|
|
|
|
|
showOfferToTrustedIcon.src = '/img/user-lasecagold.svg';
|
|
|
|
|
const showOfferToTrustedText = document.createElement('p');
|
|
|
|
|
showOfferToTrustedText.innerText = 'Confiados';
|
|
|
|
|
const checkIcon = document.createElement('img');
|
|
|
|
|
checkIcon.src = '/img/circle-check-green.svg';
|
|
|
|
|
|
|
|
|
|
showOfferToTrustedContainer.append(
|
|
|
|
|
showOfferToTrustedIcon,
|
|
|
|
|
showOfferToTrustedText,
|
|
|
|
|
checkIcon
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
const showOfferToTrustedIcon = document.createElement('img');
|
|
|
|
|
showOfferToTrustedIcon.src = '/img/user-gray.svg';
|
|
|
|
|
const showOfferToTrustedText = document.createElement('p');
|
|
|
|
|
showOfferToTrustedText.innerText = 'Confiados';
|
|
|
|
|
const checkIcon = document.createElement('img');
|
|
|
|
|
checkIcon.src = '/img/circle-xmark-gray.svg';
|
|
|
|
|
|
|
|
|
|
showOfferToTrustedContainer.append(
|
|
|
|
|
showOfferToTrustedIcon,
|
|
|
|
|
showOfferToTrustedText,
|
|
|
|
|
checkIcon
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const showOfferToTrustedTrustedContainer = document.createElement('div');
|
|
|
|
|
showOfferToTrustedTrustedContainer.classList.add(
|
|
|
|
|
'right-icon-checkboxed-field'
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (this.show_offer_to_trusted_trusted) {
|
|
|
|
|
const showOfferToTrustedTrustedIcon = document.createElement('img');
|
|
|
|
|
showOfferToTrustedTrustedIcon.src = '/img/user-group-lasecagold.svg';
|
|
|
|
|
const showOfferToTrustedTrustedText = document.createElement('p');
|
|
|
|
|
showOfferToTrustedTrustedText.innerText = 'Sus confiados';
|
|
|
|
|
const checkIcon = document.createElement('img');
|
|
|
|
|
checkIcon.src = '/img/circle-check-green.svg';
|
|
|
|
|
|
|
|
|
|
showOfferToTrustedTrustedContainer.append(
|
|
|
|
|
showOfferToTrustedTrustedIcon,
|
|
|
|
|
showOfferToTrustedTrustedText,
|
|
|
|
|
checkIcon
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
const showOfferToTrustedTrustedIcon = document.createElement('img');
|
|
|
|
|
showOfferToTrustedTrustedIcon.src = '/img/user-group-gray.svg';
|
|
|
|
|
const showOfferToTrustedTrustedText = document.createElement('p');
|
|
|
|
|
showOfferToTrustedTrustedText.innerText = 'Sus confiados';
|
|
|
|
|
const checkIcon = document.createElement('img');
|
|
|
|
|
checkIcon.src = '/img/circle-xmark-gray.svg';
|
|
|
|
|
|
|
|
|
|
showOfferToTrustedTrustedContainer.append(
|
|
|
|
|
showOfferToTrustedTrustedIcon,
|
|
|
|
|
showOfferToTrustedTrustedText,
|
|
|
|
|
checkIcon
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const showOfferToAllMembersContainer = document.createElement('div');
|
|
|
|
|
showOfferToAllMembersContainer.classList.add(
|
|
|
|
|
'right-icon-checkboxed-field'
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (this.show_offer_to_all_members) {
|
|
|
|
|
const showOfferToAllMembersIcon = document.createElement('img');
|
|
|
|
|
showOfferToAllMembersIcon.src = '/img/many-users-lasecagold.svg';
|
|
|
|
|
const showOfferToAllMembersText = document.createElement('p');
|
|
|
|
|
showOfferToAllMembersText.innerText = 'Todos';
|
|
|
|
|
const checkIcon = document.createElement('img');
|
|
|
|
|
checkIcon.src = '/img/circle-check-green.svg';
|
|
|
|
|
|
|
|
|
|
showOfferToAllMembersContainer.append(
|
|
|
|
|
showOfferToAllMembersIcon,
|
|
|
|
|
showOfferToAllMembersText,
|
|
|
|
|
checkIcon
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
const showOfferToAllMembersIcon = document.createElement('img');
|
|
|
|
|
showOfferToAllMembersIcon.src = '/img/many-users-gray.svg';
|
|
|
|
|
const showOfferToAllMembersText = document.createElement('p');
|
|
|
|
|
showOfferToAllMembersText.innerText = 'Todos';
|
|
|
|
|
const checkIcon = document.createElement('img');
|
|
|
|
|
checkIcon.src = '/img/circle-xmark-gray.svg';
|
|
|
|
|
|
|
|
|
|
showOfferToAllMembersContainer.append(
|
|
|
|
|
showOfferToAllMembersIcon,
|
|
|
|
|
showOfferToAllMembersText,
|
|
|
|
|
checkIcon
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
visibilityDiv.append(
|
|
|
|
|
showOfferToTrustedContainer,
|
|
|
|
|
showOfferToTrustedTrustedContainer,
|
|
|
|
|
showOfferToAllMembersContainer
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const otherOfferFeaturesDiv = document.createElement('div');
|
|
|
|
|
otherOfferFeaturesDiv.classList.add('other-desc');
|
|
|
|
|
|
|
|
|
|
const otherOfferFeaturesTitle = document.createElement('p');
|
|
|
|
|
otherOfferFeaturesTitle.classList.add('offer-card-content-title');
|
|
|
|
|
otherOfferFeaturesTitle.innerText = 'Otros';
|
|
|
|
|
otherOfferFeaturesDiv.append(otherOfferFeaturesTitle);
|
|
|
|
|
|
|
|
|
|
const areBigNotesAcceptedContainer = document.createElement('div');
|
|
|
|
|
areBigNotesAcceptedContainer.classList.add('left-icon-checkboxed-field');
|
|
|
|
|
|
|
|
|
|
if (this.are_big_notes_accepted) {
|
|
|
|
|
const areBigNotesAcceptedIcon = document.createElement('img');
|
|
|
|
|
areBigNotesAcceptedIcon.src = '/img/eur-bill-lasecagold.svg';
|
|
|
|
|
const areBigNotesAcceptedText = document.createElement('p');
|
|
|
|
|
areBigNotesAcceptedText.innerText = 'Billetes grandes';
|
|
|
|
|
const checkIcon = document.createElement('img');
|
|
|
|
|
checkIcon.src = '/img/circle-check-green.svg';
|
|
|
|
|
|
|
|
|
|
areBigNotesAcceptedContainer.append(
|
|
|
|
|
areBigNotesAcceptedIcon,
|
|
|
|
|
areBigNotesAcceptedText,
|
|
|
|
|
checkIcon
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
const areBigNotesAcceptedIcon = document.createElement('img');
|
|
|
|
|
areBigNotesAcceptedIcon.src = '/img/eur-bill-gray.svg';
|
|
|
|
|
const areBigNotesAcceptedText = document.createElement('p');
|
|
|
|
|
areBigNotesAcceptedText.innerText = 'Billetes grandes';
|
|
|
|
|
const checkIcon = document.createElement('img');
|
|
|
|
|
checkIcon.src = '/img/circle-xmark-gray.svg';
|
|
|
|
|
|
|
|
|
|
areBigNotesAcceptedContainer.append(
|
|
|
|
|
areBigNotesAcceptedIcon,
|
|
|
|
|
areBigNotesAcceptedText,
|
|
|
|
|
checkIcon
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
otherOfferFeaturesDiv.append(areBigNotesAcceptedContainer);
|
|
|
|
|
|
|
|
|
|
const actionButtonsArea = document.createElement('p');
|
|
|
|
|
actionButtonsArea.classList.add('offer-action-buttons-area');
|
|
|
|
|
|
|
|
|
|
const editActionArea = document.createElement('div');
|
|
|
|
|
editActionArea.classList.add('offer-action-area');
|
|
|
|
|
editActionArea.classList.add('subtle-box');
|
|
|
|
|
const editActionIcon = document.createElement('img');
|
|
|
|
|
editActionIcon.src = '/img/edit.svg';
|
|
|
|
|
const editActionText = document.createElement('p');
|
|
|
|
|
editActionText.innerText = 'Editar';
|
|
|
|
|
editActionArea.append(editActionIcon, editActionText);
|
|
|
|
|
|
|
|
|
|
const deleteActionArea = document.createElement('div');
|
|
|
|
|
deleteActionArea.classList.add('offer-action-area');
|
|
|
|
|
deleteActionArea.classList.add('subtle-box');
|
|
|
|
|
const deleteActionIcon = document.createElement('img');
|
|
|
|
|
deleteActionIcon.src = '/img/trash-can-darkred.svg';
|
|
|
|
|
const deleteActionText = document.createElement('p');
|
|
|
|
|
deleteActionText.innerText = 'Eliminar';
|
|
|
|
|
deleteActionArea.append(deleteActionIcon, deleteActionText);
|
|
|
|
|
deleteActionArea.addEventListener('click', async () => {
|
|
|
|
|
await deleteOfferByUuid(this.uuid);
|
|
|
|
|
await myOffers.getOffersFromApi();
|
|
|
|
|
await myOffers.render();
|
|
|
|
|
toggleOfferDeletedAlert();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
actionButtonsArea.append(editActionArea, deleteActionArea);
|
|
|
|
|
|
|
|
|
|
offerCard.append(
|
|
|
|
|
tradeDescDiv,
|
|
|
|
|
premiumDescDiv,
|
|
|
|
|
whereDescDiv,
|
|
|
|
|
whenDescDiv,
|
|
|
|
|
bitcoinMethodsDiv,
|
|
|
|
|
visibilityDiv,
|
|
|
|
|
otherOfferFeaturesDiv,
|
|
|
|
|
actionButtonsArea
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return offerCard;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class MyOffers {
|
|
|
|
|
constructor(ownOffersContainerElement) {
|
|
|
|
|
this.ownOffersContainerElement = ownOffersContainerElement;
|
|
|
|
|
this.offers = [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async getOffersFromApi() {
|
|
|
|
|
const offersResponse = await fetch('/api/publickey-offers');
|
|
|
|
|
|
|
|
|
|
this.offers = [];
|
|
|
|
|
|
|
|
|
|
const offersData = (await offersResponse.json()).data;
|
|
|
|
|
if (offersResponse.ok) {
|
|
|
|
|
for (const record of offersData) {
|
|
|
|
|
this.offers.push(new Offer(record));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async render() {
|
|
|
|
|
if (this.offers.length === 0) {
|
|
|
|
|
this.ownOffersContainerElement.innerHTML =
|
|
|
|
|
'<p class="shadowed-round-area">Vaya, no hay nada por aquí...</p>';
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
this.ownOffersContainerElement.innerHTML = '';
|
|
|
|
|
|
|
|
|
|
for (const someOffer of this.offers) {
|
|
|
|
|
this.ownOffersContainerElement.append(someOffer.buildHTML());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function deleteOfferByUuid(offerUuid) {
|
|
|
|
|
await fetch(`/api/offer/${offerUuid}`, {
|
|
|
|
|
method: 'DELETE',
|
|
|
|
|
headers: {
|
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
buttonStartCreateOffer.addEventListener('click', () => {
|
|
|
|
|
toggleCreateOfferModal();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
buttonViewMyOffers.addEventListener('click', async () => {
|
|
|
|
|
await myOffers.getOffersFromApi();
|
|
|
|
|
await myOffers.render();
|
|
|
|
|
toggleViewMyOffersPanel();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
closeOffer.addEventListener('click', () => {
|
|
|
|
|
toggleCreateOfferModal();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const myOffers = new MyOffers(ownOffersContainer);
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-13 11:16:01 +01:00
|
|
|
offersPage();
|