Files
tehran_taj/apps/user-app-v2/src/views/user/MakeOrderView.vue
T

198 lines
5.7 KiB
Vue
Raw Normal View History

<!--
"سفارش ساخت" — ask for a piece to be made.
Ported from henza_pwa/src/views/user/src/components/makeOrder.vue (route
/makeOrder, name makeOrderList), restyled into this app's design language.
Kept from the reference:
- the header title "سفارش ساخت"
- the photo of the piece first, then the questions: رنگ محصول، سایز محصول،
رنگ مینا، رنگ سنگ، تعداد، توضیحات (the last one optional)
- every field but the description required, with the reference's own messages
- POST create-custom-order -> customer/me/pre-orders here; the customer is the
token's, nothing about WHO is sent
The reference then sent the customer home; this goes to «وضعیت سفارش» so the
request just placed is the first thing seen.
-->
<template>
<div class="mko">
<PageBar title="سفارش ساخت" back-to="userPage::hasSubRoute" />
<Spinner :spinning="submitting" tip="در حال ثبت اطلاعات">
<container class="mko__body">
<form class="mko__form" novalidate @submit.prevent="submit">
<SingleImageUploader
upload-text="بارگذاری عکس سفارش"
purpose="preorder-design"
@done="(id: string) => (form.file_id = id)"
/>
<p class="mko__lead">لطفا به سوالات زیر پاسخ دهید</p>
<label class="mko__field">
<span>رنگ محصول</span>
<input v-model.trim="form.color" type="text" maxlength="100" />
</label>
<label class="mko__field">
<span>سایز محصول</span>
<input v-model.trim="form.size" type="text" maxlength="100" />
</label>
<label class="mko__field">
<span>رنگ مینا</span>
<input v-model.trim="form.color_mina" type="text" maxlength="100" />
</label>
<label class="mko__field">
<span>رنگ سنگ</span>
<input v-model.trim="form.color_stone" type="text" maxlength="100" />
</label>
<label class="mko__field">
<span>تعداد</span>
<input v-model.number="form.sum" type="number" inputmode="numeric" min="1" step="1" />
</label>
<label class="mko__field">
<span>توضیحات</span>
<textarea v-model.trim="form.description" rows="3" maxlength="1000" />
</label>
<p v-if="error" class="mko__error">{{ error }}</p>
<button type="submit" class="mko__submit" :disabled="submitting">ارسال اطلاعات</button>
</form>
</container>
</Spinner>
</div>
</template>
<script setup lang="ts">
import { reactive, ref, watch } from 'vue'
import { useRouter } from 'vue-router'
import { toast } from '../../composables/useToast'
import PageBar from '../../components/ui/PageBar.vue'
import Spinner from '../../components/Spinner.vue'
import SingleImageUploader from '../../components/upload/SingleImageUploader.vue'
import { api } from '../../api/client'
const router = useRouter()
const form = reactive({
file_id: null as string | null,
color: '',
size: '',
color_mina: '',
color_stone: '',
sum: 1,
description: '',
})
const submitting = ref(false)
const error = ref<string | null>(null)
/** A message about a missing field must not outlive the fix (e.g. the photo being uploaded). */
watch(form, () => (error.value = null))
/** The reference's required-field messages, in the order it asked. */
function firstMissing(): string | null {
if (!form.file_id) return 'لطفا تصویر سفارش را آپلود کنید'
if (!form.color) return 'لطفا رنگ محصول را وارد کنید'
if (!form.size) return 'لطفا سایز محصول را وارد کنید'
if (!form.color_mina) return 'لطفا رنگ مینا را وارد کنید'
if (!form.color_stone) return 'لطفا رنگ سنگ را وارد کنید'
if (!Number.isInteger(form.sum) || form.sum < 1) return 'لطفا تعداد را وارد کنید'
return null
}
async function submit() {
error.value = firstMissing()
if (error.value) return
submitting.value = true
try {
await api.createPreOrder({
color: form.color,
size: form.size,
color_mina: form.color_mina,
color_stone: form.color_stone,
sum: form.sum,
file_id: form.file_id,
description: form.description || undefined,
})
toast.success('سفارش با موفقیت ثبت شد')
router.replace({ name: 'makeOrderStatus' })
} catch {
error.value = 'خطا در ثبت سفارش'
} finally {
submitting.value = false
}
}
</script>
<style scoped lang="less">
.mko__body {
padding-top: 84px;
padding-bottom: 110px;
}
.mko__form {
display: flex;
flex-direction: column;
}
.mko__lead {
margin: 18px 2px 4px;
font-size: 13px;
font-weight: 700;
color: @inkMuted;
}
.mko__field {
display: flex;
flex-direction: column;
gap: 6px;
padding: 12px 0;
border-bottom: 1px solid @hairline;
font-size: 12.5px;
color: @inkSoft;
}
.mko__field input,
.mko__field textarea {
width: 100%;
padding: 11px 12px;
border: 1px solid @hairline;
border-radius: 12px;
background: transparent;
color: @ink;
font-family: inherit;
font-size: 14px;
}
.mko__error {
margin: 12px 2px 0;
font-size: 12.5px;
color: @red;
}
.mko__submit {
position: fixed;
left: 16px;
right: 16px;
bottom: 20px;
z-index: 20;
max-width: 736px;
margin: 0 auto;
padding: 15px;
border: none;
border-radius: 999px;
background: @wine;
color: #fff;
font-family: inherit;
font-size: 15px;
font-weight: 700;
cursor: pointer;
}
.mko__submit:disabled {
opacity: 0.6;
cursor: progress;
}
</style>