| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- <template>
- <q-dialog ref="dialogRef">
- <div class="code-dialog-wrapper column items-center">
- <q-card class="code-card bg-white">
- <q-card-section class="q-pt-lg q-pb-none q-px-lg text-center">
- <p class="code-title text-primary font16 fontbold">
- {{ $t('profile.favorites.code_title') }}
- </p>
- <p class="code-subtitle text-grey-7 font12 fontregular q-mt-sm">
- {{ $t('profile.favorites.code_subtitle') }}
- </p>
- </q-card-section>
- <q-card-section class="q-px-lg q-pt-md q-pb-none">
- <q-input
- v-model="code"
- autofocus
- class="code-input"
- input-class="text-center text-text font16 fontbold"
- mask="XXXXXX"
- outlined
- :disable="loading"
- :error="!!errorMessage"
- :error-message="errorMessage"
- :placeholder="$t('profile.favorites.code_placeholder')"
- @keyup.enter="confirm"
- @update:model-value="onCodeInput"
- />
- </q-card-section>
- <q-card-actions class="row q-px-lg q-pb-lg q-gutter-x-sm justify-center">
- <q-btn
- class="col code-btn font12 fontbold"
- color="grey-6"
- no-caps
- rounded
- text-color="grey-2"
- unelevated
- :disable="loading"
- :label="$t('profile.favorites.code_cancel')"
- @click="onDialogCancel"
- />
- <q-btn
- class="col code-btn font12 fontbold"
- color="secondary"
- no-caps
- rounded
- unelevated
- :disable="!isValid"
- :label="$t('profile.favorites.code_confirm')"
- :loading="loading"
- @click="confirm"
- />
- </q-card-actions>
- </q-card>
- </div>
- </q-dialog>
- </template>
- <script setup>
- import { computed, ref } from 'vue';
- import { useDialogPluginComponent } from 'quasar';
- import { useI18n } from 'vue-i18n';
- import { createClientFavoriteProviderByCode } from 'src/api/clientFavoriteProvider';
- import { userStore } from 'src/stores/user';
- defineEmits([...useDialogPluginComponent.emits]);
- const { dialogRef, onDialogOK, onDialogCancel } = useDialogPluginComponent();
- const { t } = useI18n();
- const store = userStore();
- const CODE_LENGTH = 6;
- const code = ref('');
- const errorMessage = ref('');
- const loading = ref(false);
- const isValid = computed(() => code.value.length === CODE_LENGTH && !loading.value);
- const onCodeInput = (value) => {
- code.value = String(value ?? '').toUpperCase();
- errorMessage.value = '';
- };
- const confirm = async () => {
- if (!isValid.value) {
- return;
- }
- const clientId = store.user?.client_id;
- if (!clientId) {
- errorMessage.value = t('profile.favorites.code_error');
- return;
- }
- loading.value = true;
- try {
- const favorite = await createClientFavoriteProviderByCode(clientId, code.value);
- onDialogOK(favorite);
- } catch (error) {
- errorMessage.value = error?.response?.status === 422
- ? (error?.response?.data?.message ?? t('profile.favorites.code_error'))
- : '';
- } finally {
- loading.value = false;
- }
- };
- </script>
- <style scoped lang="scss">
- .code-dialog-wrapper {
- width: 320px;
- max-width: 90vw;
- }
- .code-card {
- width: 100%;
- border-radius: 20px;
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
- }
- .code-title {
- line-height: 1.4;
- margin: 0;
- }
- .code-subtitle {
- line-height: 1.4;
- margin: 0;
- }
- .code-input :deep(input) {
- letter-spacing: 4px;
- text-transform: uppercase;
- }
- .code-input :deep(input::placeholder) {
- color: #bbbbbb;
- font-weight: 400;
- letter-spacing: 4px;
- opacity: 1;
- }
- .code-input :deep(input::selection) {
- background: rgba(139, 92, 246, 0.2);
- color: #555555;
- }
- .code-btn {
- padding: 6px 12px;
- }
- </style>
|