diff --git a/public/form.js b/public/form.js index cbedef6..9249033 100644 --- a/public/form.js +++ b/public/form.js @@ -1,57 +1,23 @@ // TODO // -// 1. See if I can stop using hosted buttons and use -// https://developer.paypal.com/integration-builder/ instead -// to use components=buttons only. Or, Try to load both, -// components=buttons,hosted-buttons etc. -// See Buttons SDK Reference -// https://developer.paypal.com/sdk/js/reference/ -// -// 2. Try to disable asking for shipping info (although could be +// 1. Try to disable asking for shipping info (although could be // useful to mark as sent). // -// 3. Read about IPN and Webhooks to automate registering process. +// 2. Read about IPN and Webhooks to automate registering process. -const PayPalSdkOneTime = ""; -const PayPalSdkSub = ""; const clientId = ""; const OneTimePID = ""; const PlanID = ""; -loadOneTimeButton().then(() => {loadSubButton()}) +const form = document.getElementById('mainForm'); -function loadOneTimeButton() { - return new Promise((resolve, reject) => { - var script = document.createElement('script'); - script.src = PayPalSdkOneTime; - script.onload = function() { - paypal.HostedButtons({ - hostedButtonId: OneTimePID, - }).render("#paypalOneTimeButton"); - }; - document.head.appendChild(script); - resolve(); - }); -} - -function loadSubButton() { - var script = document.createElement('script'); - script.src = PayPalSdkSub; - script.onload = function() { - paypal.Buttons({ - style: { shape: 'pill', color: 'black', layout: 'vertical', label: 'subscribe' }, - createSubscription: function(data, actions) { - return actions.subscription.create({ - plan_id: PlanID - }); - }, - onApprove: function(data, actions) { - alert(data.subscriptionID); // You can add optional success message for the subscriber here - } - }).render('#paypalSubButton'); - }; - document.head.appendChild(script); -} +['name', 'email', 'phone'].forEach(id => { + const input = document.createElement('input'); + input.type = 'hidden'; + input.name = id; + input.value = document.getElementById(id).value; + form.appendChild(input); +}); function hideDialog() { document.getElementById('overlay').style.display = 'none'; @@ -87,12 +53,58 @@ function togglePaymentMethod(selectedButtonId) { } } +function isFormValid(form) { + return form.checkValidity(); +} + +paypal_onetime.Buttons({ + style: { shape: 'pill', color: 'black', layout: 'vertical', label: 'pay' }, + createOrder: function(data, actions) { + return actions.order.create({ + intent: 'CAPTURE', + purchase_units: [{ + amount: { + currency_code: 'USD', + value: '20.00' + } + }] + }); + }, + onApprove: function(data, actions) { + return actions.order.capture().then(function(details) { + alert('Transaction completed by ' + details.payer.name.given_name); + }); + } +}).render("#paypalOneTimeButton"); + +paypal_subscribe.Buttons({ + style: { shape: 'pill', color: 'black', layout: 'vertical', label: 'subscribe' }, + createSubscription: function(data, actions) { + return actions.subscription.create({ + plan_id: PlanID + }); + }, + onApprove: function(data, actions) { + alert(data.subscriptionID); // You can add optional success message for the subscriber here + } +}).render('#paypalSubButton'); + document.getElementById('showOneTimeButton').addEventListener('click', function() { + if (isFormValid(form)) { + document.getElementById('warning-message').style.display = 'none'; togglePaymentMethod('showOneTimeButton'); + } else { + document.getElementById('warning-message').style.display = 'block'; + } }); document.getElementById('showSubButton').addEventListener('click', function() { + if (isFormValid(form)) { + document.getElementById('warning-message').style.display = 'none'; togglePaymentMethod('showSubButton'); + } else { + document.getElementById('warning-message').style.display = 'block'; + } }); document.getElementById('openDialogButton').addEventListener('click', () => { diff --git a/public/index.html b/public/index.html index 844a199..24746a7 100644 --- a/public/index.html +++ b/public/index.html @@ -9,46 +9,75 @@ - - - + + + + + + + + + + + + + + + + +
+
-
- -
+
-

Información de Contacto

+
+

Información de Contacto

+ +

Utilizaremos esta información para contactarle acerca de la publicación del sitio.

-

Por favor digite los campos requeridos.

-
- - - +
+ + + +
+

Tipo de Pago

+
+

Pago Único: El pago debe realizarse manualmente un año después de contratar el servicio, le enviaremos notificaciones al correo electrónico recordando el pago.

+

Pago Automático: Requiere cuenta de PayPal para rebajo automático, si no tiene una le pedirá configurar rápidamente los datos.

+
+

Por favor digite los campos requeridos.

-
+
- + + diff --git a/public/static/css/style.css b/public/static/css/style.css index 42c6ece..bfe2ab4 100644 --- a/public/static/css/style.css +++ b/public/static/css/style.css @@ -1,6 +1,7 @@ :root { --background-color: white; --color: black; + --warning-color: #b24629; --page-width: 768px; --navbar-width: 50%; --font-family: sans-serif; @@ -179,13 +180,17 @@ footer { margin: 1em auto; } -#error-message { +#form-container { + padding-bottom: 1em; +} + +#warning-message { display: none; } -#error-message p { +#warning-message p { text-decoration: underline; - color: var(--unemph-color); + color: var(--warning-color); } button { @@ -205,8 +210,8 @@ button { #openDialogButton { position: fixed; bottom: 2em; - right: 2em; - height: 4em; + right: 1em; + height: 2.5em; cursor: pointer; font-size: 1em; z-index: 1001; @@ -251,6 +256,23 @@ button { display: block; } +#cancelDialogButton { + justify-content: center; + align-items: center; + display: flex; + background-color: var(--background); + border: 1px solid var(--hover-border); + color: var(--unemph-color); + position: absolute; + transition: 0.3s; + border-radius: 50%; + width: 1em; + height: 1em; + top: 0.5em; + right: 0.5em; + font-size: 1.1em; +} + /* Custom SimpleMDE styling */ .CodeMirror { border-radius: 10px; @@ -264,3 +286,5 @@ button { font-size: 1em; font-family: sans-serif; } + + diff --git a/public/static/js/config.editor.js b/public/static/js/config.editor.js new file mode 100644 index 0000000..56721de --- /dev/null +++ b/public/static/js/config.editor.js @@ -0,0 +1,219 @@ +var editor = new EditorJS({ + readOnly: false, + holder: 'editorjs', + + inlineToolbar: ['link', 'marker', 'bold', 'italic'], + inlineToolbar: true, + tools: { + /** + * Each Tool is a Plugin. Pass them via 'class' option with necessary settings {@link docs/tools.md} + */ + header: { + class: Header, + inlineToolbar: ['marker', 'link'], + config: { + placeholder: 'Header' + }, + shortcut: 'CMD+SHIFT+H' + }, + + image: SimpleImage, + + list: { + class: List, + inlineToolbar: true, + shortcut: 'CMD+SHIFT+L' + }, + + quote: { + class: Quote, + inlineToolbar: true, + config: { + quotePlaceholder: 'Enter a quote', + captionPlaceholder: 'Quote\'s author', + }, + shortcut: 'CMD+SHIFT+O' + }, + + linkTool: LinkTool, + + embed: Embed, + + table: { + class: Table, + inlineToolbar: true, + shortcut: 'CMD+ALT+T' + }, + + }, + + /** + * This Tool will be used as default + */ + // defaultBlock: 'paragraph', + + data: { + blocks: [ + { + type: "header", + data: { + text: "Acerca de [Empresa]", + level: 1 + } + }, + { + type : 'paragraph', + data : { + text : 'En [Nombre de Tu Empresa], nos dedicamos a ofrecer [tu servicio/producto] de la más alta calidad con un servicio al cliente excepcional. Nuestro equipo de expertos se asegura de que cada aspecto de tu experiencia sea manejado con profesionalismo y cuidado.' + } + }, + { + type : 'list', + data : { + items : [ + 'It is a block-styled editor', + 'It returns clean data output in JSON', + 'Designed to be extendable and pluggable with a simple API', + ], + style: 'unordered' + } + }, + { + type: 'table', + data: { + content: [ + ['Header 1', 'Header 2', 'Header 3'], + ['Row 1, Cell 1', 'Row 1, Cell 2', 'Row 1, Cell 3'], + ['Row 2, Cell 1', 'Row 2, Cell 2', 'Row 2, Cell 3'] + ] + } + }, + ] + }, + i18n: { + messages: { + ui: { + "blockTunes": { + "toggler": { + "Click to tune": "Modificar", + "or drag to move": "or drag to move" + }, + }, + "inlineToolbar": { + "converter": { + "Convert to": "Convertir a" + } + }, + "toolbar": { + "toolbox": { + "Add": "Insertar" + } + } + }, + + /** + * Section for translation Tool Names: both block and inline tools + */ + toolNames: { + "Text": "Texto", + "Heading": "Título", + "List": "Lista", + "Warning": "Advertencia", + "Quote": "Quote", + "Table": "Tabla", + "Link": "Link", + "Bold": "Negrita", + "Italic": "Itálicas", + "InlineCode": "InlineCode", + }, + + /** + * Section for passing translations to the external tools classes + */ + tools: { + /** + * Each subsection is the i18n dictionary that will be passed to the corresponded plugin + * The name of a plugin should be equal the name you specify in the 'tool' section for that plugin + */ + "warning": { // <-- 'Warning' tool will accept this dictionary section + "Title": "Título", + "Message": "Mensaje", + }, + + /** + * Link is the internal Inline Tool + */ + "link": { + "Add a link": "Agregar link" + }, + /** + * The "stub" is an internal block tool, used to fit blocks that does not have the corresponded plugin + */ + "stub": { + 'The block can not be displayed correctly.': 'No se puede visualizar este bloque' + } + }, + + /** + * Section allows to translate Block Tunes + */ + blockTunes: { + /** + * Each subsection is the i18n dictionary that will be passed to the corresponded Block Tune plugin + * The name of a plugin should be equal the name you specify in the 'tunes' section for that plugin + * + * Also, there are few internal block tunes: "delete", "moveUp" and "moveDown" + */ + "delete": { + "Delete": "Quitar bloque" + }, + "moveUp": { + "Move up": "Mover arriba" + }, + "moveDown": { + "Move down": "Mover abajo" + } + }, + } + }, + onReady: function(){ + saveButton.click(); + }, + onChange: function(api, event) { + console.log('something changed', event); + } + +}); + +/** + * Saving button + */ +const saveButton = document.getElementById('saveButton'); + +/** + * Toggle read-only button + */ +const toggleReadOnlyButton = document.getElementById('toggleReadOnlyButton'); +const readOnlyIndicator = document.getElementById('readonly-state'); + +/** + * Saving example + */ +saveButton.addEventListener('click', function () { + editor.save() + .then((savedData) => { + cPreview.show(savedData, document.getElementById("output")); + }) + .catch((error) => { + console.error('Saving error', error); + }); +}); + +/** + * Toggle read-only example + */ +toggleReadOnlyButton.addEventListener('click', async () => { + const readOnlyState = await editor.readOnly.toggle(); + + readOnlyIndicator.textContent = readOnlyState ? 'On' : 'Off'; +}); diff --git a/public/static/js/simplemde.config.js b/public/static/js/simplemde.config.js index 0999499..4b1263e 100644 --- a/public/static/js/simplemde.config.js +++ b/public/static/js/simplemde.config.js @@ -1,9 +1,12 @@ var simplemde = new SimpleMDE({ element: document.getElementById("editor"), + autosave: { + enabled: true, + uniqueId: "main-editor", + delay: 1000, + }, toolbar: ["preview", "|", "heading", "bold", "italic", "unordered-list", "ordered-list", "|", "link", "image", "table"], spellChecker: false, -}); -simplemde.value("# Bienvenido a [Empresa]\n\nUbicados en [Dirección de la Empresa]\n\n✉️ contacto@empresa.com\n☎️ +506 8888 8888\n\n# Servicios\n\n| Servicio | Descripción | Monto |\n| -------- | ----------- | --------- |\n| Uno | Una | 1.000,00 |\n| Dos | Breve | 10.000,00 |\n| Tres | Explicación | 7.500,00 |\n\n![Imagen ejemplo](https://0x0.st/XWHZ.jpg)\n\n# Acerca de Nosotros\n\nEn [Empresa], nos especializamos en [breve descripción de tus servicios/productos]. Nuestro equipo está dedicado a ofrecer [propuesta de valor o punto de venta único].\n\n# Síguenos\n\n[Facebook](https://facebook.com) | [Instagram](https://instagram.com)\n"); -document.getElementById('openDialogButton').addEventListener('click', () => { - document.getElementById('dialog').style.display = 'block'; + status: false, + placeholder: "Contruye tu página aquí utilizando la barra de herramientas de arriba.\n\nRecuerde editar también\n[Nombre Ejemplo] y [Slogan]." });