exchange/resources/js/Components/CreateRequestModal.vue

359 lines
11 KiB
Vue

<template>
<a-modal
v-model="visible"
:title="trans('Create request') + ' (Enter your account credentials)'"
:after-close="() => $emit('close')"
:destroy-on-close="true"
:width="960"
>
<a-form
:label-col="{ span: 4 }"
:wrapper-col="{ span: 20 }"
label-align="left"
@keypress.enter.native="submit"
>
<div class="flex space-x-3">
<div class="w-8/12">
<a-form-item
:label="trans('Phone')"
>
<a-row :gutter="8" type="flex" align="middle">
<a-col :span="3">
<vue-country-code
@onSelect="onSelect"
:preferredCountries="['tm']"
:defaultCountry="'tm'">
</vue-country-code>
</a-col>
<a-col :span="2">
<span>{{ countryCode }}</span>
</a-col>
<a-col :span="19">
<a-input v-model="form.phone" :placeholder="trans('Phone')" />
</a-col>
</a-row>
<template v-if="validationErrorsObj.phone">
<span class="validation-error" v-for="item in validationErrorsObj.phone" :key="item">{{ item }}</span>
</template>
</a-form-item>
<a-form-item
:label="'Password'"
>
<a-input v-model="form.password" type="password" :placeholder="trans('Password')" />
<template v-if="validationErrorsObj.password">
<span class="validation-error" v-for="item in validationErrorsObj.password" :key="item">{{ item }}</span>
</template>
</a-form-item>
</div>
<!-- Warning text -->
<div class="w-4/12 warning-text not-registered" v-show="warningMessages.notRegistered">
<p>You have to be resgistered and have enough money on your balance to make a request.</p>
<p>Not Registered? <a href="https://tmex.gov.tm#register" class="font-bold text-primary">Click here</a></p>
</div>
<div class="w-4/12 warning-text low-balance" v-show="warningMessages.lowBalance">
<p>Low balance. Please fill up your balance.</p>
<p>Not Registered? <a href="https://tmex.gov.tm/tm/balance" class="font-bold text-primary">Click here</a></p>
</div>
<!-- Warning text end -->
</div>
<!-- Additional info for creating a request -->
<div class="flex space-x-3 border-t pt-4 border-gray-300">
<div class="w-8/12">
<a-form-item
:label="'First name'"
>
<a-input v-model="form.first_name" :placeholder="'First name'" />
<template v-if="validationErrorsObj.first_name">
<span class="validation-error" v-for="item in validationErrorsObj.first_name" :key="item">{{ item }}</span>
</template>
</a-form-item>
<a-form-item
:label="'Last name'"
>
<a-input v-model="form.last_name" :placeholder="'Last name'" />
<template v-if="validationErrorsObj.last_name">
<span class="validation-error" v-for="item in validationErrorsObj.last_name" :key="item">{{ item }}</span>
</template>
</a-form-item>
<a-form-item
:label="trans('Email')"
>
<a-input v-model="form.email" :placeholder="trans('Email')" />
<template v-if="validationErrorsObj.email">
<span class="validation-error" v-for="item in validationErrorsObj.email" :key="item">{{ item }}</span>
</template>
</a-form-item>
<a-form-item
:label="'Organization type'"
>
<a-input v-model="form.org_type" :placeholder="'Organization type'" />
<template v-if="validationErrorsObj.org_type">
<span class="validation-error" v-for="item in validationErrorsObj.org_type" :key="item">{{ item }}</span>
</template>
</a-form-item>
</div>
</div>
<!-- Additional info for creating a request -->
<div
class="flex relative space-x-3"
v-for="(item, index) in form.items"
:key="item.id"
>
<div class="absolute bottom-8 -left-3 w-5 text-right">
{{ index + 1 }}.
</div>
<a-form-item
class="w-full"
:label-col="{ span: 24 }"
:wrapper-col="{ span: 24 }"
label-align="left"
>
<a-input :value="item.title" disabled />
</a-form-item>
<!-- <a-form-item
class="w-3/12"
:label="index === 0 ? 'Mukdary' : ''"
:label-col="{ span: 24 }"
:wrapper-col="{ span: 24 }"
label-align="left"
:validateStatus="formStatus(`items.${index}.count`)"
>
<a-input v-model.number="item.count" :addon-after="item.unit" />
</a-form-item> -->
</div>
</a-form>
<div class="border-t pt-4 border-gray-300 text-right">
<span class="font-bold"
>{{ trans("Total") }}: {{ selectedItems.length }} x {{ price }}
{{ currency }} =</span
>
<span class="font-bold text-primary"
>{{ totalPrice }} {{ currency }}</span
>
</div>
<div slot="footer" class="flex items-center justify-end">
<!-- <google-re-captcha-v3
ref="captcha"
v-model="form.captcha"
inline
action="create_request"
/> -->
<a-button
type="primary"
class="ml-5"
size="large"
@click="submit"
:loading="form.processing"
:disabled="loader"
>{{ loader ? '...' : trans("Create") }}</a-button
>
</div>
</a-modal>
</template>
<script>
// import GoogleReCaptchaV3 from "./GoogleReCaptchaV3";
export default {
props: {
selectedItems: { type: Array, default: () => [] },
},
// components: {
// GoogleReCaptchaV3,
// },
data() {
return {
warningMessages:{
notRegistered: true,
lowBalance: false
},
visible: true,
type: "local",
form: this.$inertia.form({
phone: undefined,
password: undefined,
first_name: undefined,
last_name: undefined,
email: undefined,
org_type: undefined,
// captcha: undefined,
items: [
{
id: undefined,
title: undefined,
// count: undefined,
},
],
}),
validationErrorsObj: {},
loader: false,
countryCode: '',
};
},
computed: {
currency() {
return this.countryCode === "993" ? "TMT" : "USD";
},
price() {
const { local_price, int_price } = this.$page.props;
return this.countryCode === "993" ? local_price : int_price;
},
totalPrice() {
return this.selectedItems.length * this.price;
},
},
mounted() {
this.fill();
},
beforeDestroy() {
window.location.reload();
},
methods: {
fill() {
this.form = {
...this.form,
items: this.selectedItems.map((item) => ({
...item,
// count: undefined,
})),
totalPrice: undefined,
currency: undefined
};
},
onSelect({name, iso2, dialCode}) {
console.log(name, iso2, dialCode);
this.countryCode = dialCode
},
deleteDangerClass() {
let warningParagraphs = document.querySelectorAll('.warning-text')
warningParagraphs.forEach(elem => elem.classList.remove('danger-color'))
},
addDangerClass() {
let warningParagraphs = document.querySelectorAll('.warning-text')
warningParagraphs.forEach(elem => elem.classList.add('danger-color'))
},
submit() {
this.deleteDangerClass()
this.loader = true
this.form.totalPrice = this.totalPrice
this.form.currency = this.currency
this.form.dial_code = this.countryCode
fetch(this.route('requests.store'), {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
},
body: JSON.stringify(this.form) // body data type must match "Content-Type" header
})
.then(res => res.json())
.then(res => {
alert('we are in success section')
this.validationErrorsObj = {}
switch (res.status) {
case 400: // validation failed
let errorValidation = res.validationErrors
for (let key in errorValidation) {
this.validationErrorsObj[key] = []
for(let i = 0; i < errorValidation[key].length; i++) {
this.validationErrorsObj[key].push(errorValidation[key][i])
}
}
console.log(this.validationErrorsObj)
break;
case 401: // not registered yet or invalid credentials
this.$message.error('Unauthorized');
// Show a warning text in red! Add a class.
this.warningMessages.notRegistered = true
this.warningMessages.lowBalance = false
this.addDangerClass()
break;
case 500:
this.$message.error('Internal Server Error');
break;
case 201: // success: withdraw from a balance and create a request
this.visible = false;
this.$message.success(this.trans("Success message"));
break;
case 300: // not enough money on a balance
this.$message.error(res.message);
// Show a warning text in red! Add a class & show low balance paragraph
this.warningMessages.lowBalance = true
this.warningMessages.notRegistered = false
this.addDangerClass()
break;
default:
this.$message.error('Something went wrong. Try later.');
break;
}
this.loader = false
})
.catch(err => {
alert('we are in errors section')
this.validationErrorsObj = {}
console.log(err)
this.$message.error('Internal Server Error');
this.loader = false
})
},
},
};
</script>
<style>
.validation-error {
color: rgb(255, 0, 0);
}
.vue-country-select {
border-color: #004691 !important;
}
.vue-country-select .dropdown {
padding: 0 0.3em 0 0!important;
}
.vue-country-select .dropdown-list {
z-index: 2 !important;
border-color: #004691 !important;
}
.vue-country-select .dropdown-item.last-preferred {
border-bottom: 1px solid #004691 !important;
}
.ant-form-item label {
white-space: pre-wrap;
}
.warning-text.danger-color * {
color: rgb(255, 0, 0);
}
</style>