359 lines
11 KiB
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>
|