Server IP : 185.86.78.101 / Your IP : 216.73.216.124 Web Server : Apache System : Linux 675867-vds-valikoshka1996.gmhost.pp.ua 5.4.0-150-generic #167-Ubuntu SMP Mon May 15 17:35:05 UTC 2023 x86_64 User : www ( 1000) PHP Version : 7.4.33 Disable Function : passthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /www/wwwroot/mifepriston.org/src/ |
Upload File : |
<template> <div> <div class="modal" :class="{ 'is-active': visible }"> <div class="modal-background" @click="visible = false"></div> <div class="modal-card"> <header class="modal-card-head"> <p class="modal-card-title">{{ t('Shopping Cart') }}</p> <button class="delete" aria-label="close" @click="visible = false"></button> </header> <section class="modal-card-body"> <!-- Product name --> <div class="is-size-5"> {{ t("You're purchasing") }} <span class="has-text-info">{{ productName }}</span> <input type="hidden" name="price" :value="price"> </div><br> <div class="columns is-mobile"> <div class="column"> <!-- Quantity --> <div class="field is-horizontal"> <div class="field-label"> <label class="label">{{ t('Quantity') }}</label> </div> <div class="field-body"> <div class="field is-expanded"> <div class="field has-addons"> <p class="control"> <a href="#" class="button" @click="decCount()"><svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 448 512"><!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M432 256c0 17.7-14.3 32-32 32L48 288c-17.7 0-32-14.3-32-32s14.3-32 32-32l352 0c17.7 0 32 14.3 32 32z"/></svg></a> </p> <p class="control is-expanded"> <input class="input" :class="{'is-danger': invalid.quantity}" name="quantity" type="number" v-model="quantity" @input="resetHelper('quantity')" @blur="validate('quantity')"> </p> <p class="control"> <a href="#" class="button" @click="incCount()"><svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 448 512"><!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M256 80c0-17.7-14.3-32-32-32s-32 14.3-32 32V224H48c-17.7 0-32 14.3-32 32s14.3 32 32 32H192V432c0 17.7 14.3 32 32 32s32-14.3 32-32V288H400c17.7 0 32-14.3 32-32s-14.3-32-32-32H256V80z"/></svg></a> </p> </div> <p v-if="invalid.quantity" class="help is-danger">{{ t('Input a number between') }} {{ minQuantity }} {{ t('and') }} {{ maxQuantity }}</p> </div> </div> </div> </div> <div class="column"> <!-- Cost --> <div class="field is-horizontal"> <div class="field-label is-normal"> <label class="label">{{ t('Cost') }}</label> </div> <div class="field-body"> <div class="field has-addons"> <p class="control"> <input class="input" name="cost" type="text" readonly :value="quantity * price"> </p> <p class="control"> <span class="button is-static">{{ currency }}</span> </p> </div> </div> </div> </div> </div> <!-- Name --> <div class="field is-horizontal"> <div class="field-label is-normal"> <label class="label">{{ t('Your name') }}</label> </div> <div class="field-body"> <div class="field"> <div class="control"> <input class="input" :class="{'is-danger': invalid.name}" type="text" name="name" v-model="name" :placeholder="t('Input your name')" @input="resetHelper('name')" @blur="validate('name')"> </div> <p v-if="invalid.name" class="help is-danger">{{ t('Name is required') }}</p> </div> </div> </div> <!-- Phone --> <div class="field is-horizontal"> <div class="field-label is-normal"> <label class="label">{{ t('Your phone') }}</label> </div> <div class="field-body"> <div class="field"> <div class="control"> <input class="input" :class="{'is-danger': invalid.phone}" type="tel" name="phone" :placeholder="t('In international format')" v-model="phone" @input="resetHelper('phone')" @blur="validate('phone')"> </div> <p v-if="invalid.phone" class="help is-danger">{{ t('Phone is required') }}</p> </div> </div> </div> <!-- Email --> <div class="field is-horizontal"> <div class="field-label is-normal"> <label class="label">{{ t('Email') }}</label> </div> <div class="field-body"> <div class="field"> <div class="control has-icons-left"> <input class="input" :class="{'is-danger': invalid.email}" type="email" name="email" v-model="email" placeholder="you@email.com" @input="resetHelper('email')" @blur="validate('email')"> <span class="icon is-small is-left"> <svg style="fill: #DBDBDB" xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 512 512"><!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M48 64C21.5 64 0 85.5 0 112c0 15.1 7.1 29.3 19.2 38.4L236.8 313.6c11.4 8.5 27 8.5 38.4 0L492.8 150.4c12.1-9.1 19.2-23.3 19.2-38.4c0-26.5-21.5-48-48-48H48zM0 176V384c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V176L294.4 339.2c-22.8 17.1-54 17.1-76.8 0L0 176z"/></svg> </span> </div> <p v-if="invalid.email" class="help is-danger">{{ t('This email is invalid') }}</p> </div> </div> </div> <!-- Shipment --> <div class="field is-horizontal"> <div class="field-label is-normal"> <label class="label">{{ t('Ship to') }}</label> </div> <div class="field-body"> <div class="field is-narrow"> <div class="control"> <div class="select is-fullwidth"> <select name="shipment_id" v-model="shipment_id"> <option v-for="row of shipMethods" :key="row.id" :value="row.id">{{ row.name }}</option> </select> </div> </div> </div> </div> </div> <!-- Address --> <div class="field is-horizontal"> <div class="field-label is-normal"> <label class="label">{{ t('Shipping address') }}</label> </div> <div class="field-body"> <div class="field"> <div class="control"> <textarea class="textarea" :class="{'is-danger': invalid.address}" name="address" v-model="address" :placeholder="t('Please input shipping address carefully')" @input="resetHelper('address')" @blur="validate('address')"></textarea> </div> <p v-if="invalid.address" class="help is-danger">{{ t('Address is required') }}</p> </div> </div> </div> <!-- Comment --> <div class="field is-horizontal"> <div class="field-label is-normal"> <label class="label">{{ t('Comment') }}</label> </div> <div class="field-body"> <div class="field"> <div class="control"> <textarea class="textarea" name="comment" v-model="comment" :placeholder="t('Additional information (optional)')"></textarea> </div> </div> </div> </div> </section> <footer class="modal-card-foot"> <button class="button is-primary" @click.prevent="placeOrder()">{{ t('Place order') }}</button> <button class="button" @click="visible = false">{{ t('Cancel') }}</button> <button class="button" @click="resetForm()">{{ t('Reset form') }}</button> </footer> </div> </div> <div class="modal" :class="{ 'is-active': orderPlaced }"> <div class="modal-background" @click="orderPlaced = false"></div> <div class="modal-content"> <div class="box" @click="orderPlaced = false"> {{ t('You have placed the order successfully') }}.<br> {{ t('Our employee will contact you as soon as possible') }}. </div> </div> <button class="modal-close is-large" aria-label="close" @click="orderPlaced = false"></button> </div> </div> </template> <script> import axios from 'axios'; export default { data() { return { productName: productName, price: price, currency: currency, quantity: 0, translation: {}, visible: false, name: '', phone: '', email: '', shipment_id: 0, address: '', comment: '', shipMethods: [], orderPlaced: false, invalid: {}, minQuantity: 1, maxQuantity: 20, } }, methods: { t(txt) { return this.$data.translation[txt] || txt; }, addToCart(count) { if (Number(count)) this.quantity += Number(count); else this.quantity = this.quantity || 1; this.orderPlaced = false; this.visible = true; }, decCount() { this.quantity--; if (this.quantity < this.minQuantity) this.quantity = this.minQuantity; }, incCount() { this.quantity++; if (this.quantity > this.maxQuantity) this.quantity = this.maxQuantity; }, placeOrder() { const attrs = ['quantity', 'price', 'name', 'phone', 'email', 'shipment_id', 'address', 'comment']; let formValid = true; for (let attr of attrs) formValid = this.validate(attr) && formValid; if (! formValid) return; const formData = new FormData; formData.set(csrfParam, csrfToken); formData.set('Order[lang]', lang); for (let attr of attrs) formData.set('Order[' + attr + ']', this[attr]); axios.post(placeOrderUrl, formData, { headers: {'Content-Type': 'multipart/form-data' } }) .then( response => { if (response.data.result === 'OK') { this.visible = false; this.quantity = 0; this.orderPlaced = true; } else { alert(this.t('An error occured')); } }) .catch( error => { alert(this.t('An error occured')); }); }, resetForm() { this.quantity = 1; this.name = ''; this.phone = ''; this.email = ''; this.shipment_id = this.shipMethods[0].id; this.address = ''; this.comment = ''; this.resetAllHelpers(); }, resetHelper(field) { this.invalid[field] = false; }, resetAllHelpers() { this.invalid = { quantity: false, name: false, phone: false, email: false, address: false, } }, validate(attr) { if (typeof this[attr] === 'string') { this[attr] = this[attr].trim(); } let valid = true; switch (attr) { case 'quantity': valid = typeof this.quantity === 'number' && this.quantity >= this.minQuantity && this.quantity <= this.maxQuantity; break; case 'price': break; case 'name': this.name = this.name.substring(0, 50); valid = this.name.match(/^\S+\s+\S+/); break; case 'phone': this.phone = this.phone.replace(/\D/g, ''); valid = /^(38)?0\d{9}$/.test(this.phone) || /^7\d{10}$/.test(this.phone); break; case 'email': this.email = this.email.substring(0, 50); valid = this.email === '' || this.email.match(/^\S+@\S+$/); break; case 'shipment_id': break; case 'address': this.address = this.address.substring(0, 200); valid = this.address !== ''; break; case 'comment': this.comment = this.comment.substring(0, 300); break; default: console.error('Unknown attribute: ' + attr); valid = false; } this.invalid[attr] = ! valid; return valid; } }, mounted() { axios.get(getTranslationUrl, { params: {lang: lang, category: 'cart'} }) .then( response => { this.$data.translation = response.data; }); axios.get(getShippingUrl, { params: {lang: lang} }) .then( response => { this.$data.shipMethods = response.data.map(row => { return {id: Number(row.id), name: row.name} }); this.$data.shipment_id = this.$data.shipMethods[0].id; }); this.resetAllHelpers(); } } </script> <style> input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { /* display: none; <- Crashes Chrome on hover */ -webkit-appearance: none; margin: 0; /* <-- Apparently some margin are still there even though it's hidden */ } input[type=number] { -moz-appearance:textfield; /* Firefox */ } </style>