فهرست منبع

fix: :bug: fix (documentos) corrigida exibicao e aprovacao de documentos do prestador

corrigida exibicao e aprovacao de documentos do prestador

fase:staging | origin:escopo
Gustavo Zanatta 3 هفته پیش
والد
کامیت
a3e2e0f93b

+ 3 - 2
src/i18n/locales/en.json

@@ -325,8 +325,9 @@
       "birth_date": "Birth Date",
       "selfie_verified": "Selfie Verified",
       "document_verified": "Document Verified",
-      "document_front": "Document Front",
-      "document_back": "Document Back",
+      "document_front": "Document (Front)",
+      "document_back": "Document (Back)",
+      "no_documents": "No documents uploaded",
       "is_approved": "Approved",
       "average_rating": "Average Rating",
       "total_services": "Total Services",

+ 3 - 2
src/i18n/locales/es.json

@@ -325,8 +325,9 @@
       "birth_date": "Fecha de Nacimiento",
       "selfie_verified": "Selfie Verificada",
       "document_verified": "Documento Verificado",
-      "document_front": "Frente del Documento",
-      "document_back": "Verso del Documento",
+      "document_front": "Documento (Frente)",
+      "document_back": "Documento (Reverso)",
+      "no_documents": "Ningún documento enviado",
       "is_approved": "Aprobado",
       "average_rating": "Calificación Promedio",
       "total_services": "Total de Servicios",

+ 3 - 2
src/i18n/locales/pt.json

@@ -325,8 +325,9 @@
       "birth_date": "Data de Nascimento",
       "selfie_verified": "Selfie Verificada",
       "document_verified": "Documento Verificado",
-      "document_front": "Frente do Documento",
-      "document_back": "Verso do Documento",
+      "document_front": "Documento (Frente)",
+      "document_back": "Documento (Verso)",
+      "no_documents": "Nenhum documento enviado",
       "is_approved": "Aprovado",
       "average_rating": "Avaliação Média",
       "total_services": "Total de Serviços",

+ 1 - 1
src/pages/client/components/AddEditClientDialog.vue

@@ -28,7 +28,7 @@
             <q-card-section class="row q-col-gutter-sm">
               <div v-if="client" class="col-12 flex flex-center column q-pb-sm">
                 <q-avatar size="80px" color="grey-3">
-                  <img v-if="avatarPreview" :src="avatarPreview" style="object-fit: cover; width: 100%; height: 100%;" />
+                  <img v-if="avatarPreview" :src="avatarPreview" style="object-fit: cover; width: 100%; height: 100%;" @error="avatarPreview = null" />
                   <q-icon v-else name="mdi-account" size="50px" color="grey-6" />
                 </q-avatar>
                 <input

+ 70 - 35
src/pages/provider/components/AddEditProviderDialog.vue

@@ -97,18 +97,19 @@
                 />
 
                 <div class="col-12">
-                  <q-select
+                  <div class="text-subtitle2 text-grey-7 q-mb-xs">
+                    {{ $t('provider.fields.approval_status') }}
+                  </div>
+                  <q-option-group
                     v-model="form.approval_status"
                     :options="approvalStatusOptions"
-                    :label="$t('provider.fields.approval_status')"
-                    emit-value
-                    map-options
-                    outlined
-                    dense
-                    :error="!!serverErrors?.approval_status"
-                    :error-message="serverErrors?.approval_status"
-                    class="col-12"
+                    type="radio"
+                    color="primary"
+                    inline
                   />
+                  <div v-if="serverErrors?.approval_status" class="text-negative text-caption">
+                    {{ serverErrors.approval_status }}
+                  </div>
                 </div>
 
                 <ProviderSpecialitiesPanel v-if="provider" :provider-id="provider.id" />
@@ -119,7 +120,7 @@
                   <div class="row q-col-gutter-md">
                     <div class="col-auto flex flex-center column">
                       <q-avatar size="80px" color="grey-3">
-                        <img v-if="avatarPreview" :src="avatarPreview" style="object-fit: cover; width: 100%; height: 100%;" />
+                        <img v-if="avatarPreview" :src="avatarPreview" style="object-fit: cover; width: 100%; height: 100%;" @error="avatarPreview = null" />
                         <q-icon v-else name="mdi-account" size="50px" color="grey-6" />
                       </q-avatar>
                       <input
@@ -163,52 +164,67 @@
                       </div>
 
                       <div class="col-md-6 col-12">
-
                         <div class="text-subtitle2 text-grey-7 q-mb-sm">
                           {{ $t('provider.fields.selfie_verified') }}
                         </div>
-
                         <q-checkbox
                           v-model="form.selfie_verified"
-                          label="Verificar foto"
+                          :label="$t('provider.fields.selfie_verified')"
                           color="primary"
                         />
-
                       </div>
 
                       <div class="col-12">
-
                         <div class="text-subtitle2 text-grey-7 q-mb-sm">
                           {{ $t('provider.fields.document_verified') }}
                         </div>
 
-                        <div v-if="documentFrontUrl || documentBackUrl" class="row q-col-gutter-sm q-mb-sm">
-                          <div v-if="documentFrontUrl" class="col">
+                        <div class="row q-col-gutter-sm q-mb-sm">
+                          <div class="col-auto">
                             <div class="text-caption text-grey-6 q-mb-xs">{{ $t('provider.fields.document_front') }}</div>
-                            <q-img
-                              :src="documentFrontUrl"
-                              fit="cover"
-                              style="height: 110px; width: 300px; object-fit: contain;border-radius: 6px; cursor: pointer;"
-                              @click="docLightbox = documentFrontUrl"
-                            />
+                            <div
+                              class="doc-frame"
+                              :class="{ 'doc-frame--clickable': documentFrontUrl }"
+                              @click="documentFrontUrl && (docLightbox = documentFrontUrl)"
+                            >
+                              <q-img
+                                v-if="documentFrontUrl"
+                                :src="documentFrontUrl"
+                                fit="contain"
+                                style="height: 100%; width: 100%;"
+                              />
+                              <div v-else class="column flex-center text-grey-5">
+                                <q-icon name="mdi-image-off-outline" size="34px" />
+                                <div class="text-caption q-mt-xs">{{ $t('provider.fields.no_documents') }}</div>
+                              </div>
+                            </div>
                           </div>
-                          <div v-if="documentBackUrl" class="col">
+                          <div class="col-auto">
                             <div class="text-caption text-grey-6 q-mb-xs">{{ $t('provider.fields.document_back') }}</div>
-                            <q-img
-                              :src="documentBackUrl"
-                              fit="cover"
-                              style="height: 110px; width: 300px; object-fit: contain;border-radius: 6px; cursor: pointer;"
-                              @click="docLightbox = documentBackUrl"
-                            />
+                            <div
+                              class="doc-frame"
+                              :class="{ 'doc-frame--clickable': documentBackUrl }"
+                              @click="documentBackUrl && (docLightbox = documentBackUrl)"
+                            >
+                              <q-img
+                                v-if="documentBackUrl"
+                                :src="documentBackUrl"
+                                fit="contain"
+                                style="height: 100%; width: 100%;"
+                              />
+                              <div v-else class="column flex-center text-grey-5">
+                                <q-icon name="mdi-image-off-outline" size="34px" />
+                                <div class="text-caption q-mt-xs">{{ $t('provider.fields.no_documents') }}</div>
+                              </div>
+                            </div>
                           </div>
                         </div>
 
                         <q-checkbox
                           v-model="form.document_verified"
-                          label="Validar documentos"
+                          :label="$t('provider.fields.document_verified')"
                           color="primary"
                         />
-
                       </div>
                     </div>
                   </div>
@@ -339,8 +355,8 @@ const { form, getUpdatedFields, hasUpdatedFields } = useFormUpdateTracker({
   document: provider ? provider?.document : "",
   rg: provider ? provider?.rg : "",
   birth_date: provider ? provider?.birth_date : null,
- selfie_verified: provider? provider?.selfie_verified:false,
- document_verified: provider? provider?.document_verified:false,
+  selfie_verified: provider ? provider?.selfie_verified : false,
+  document_verified: provider ? provider?.document_verified : false,
   approval_status: provider ? provider?.approval_status : "pending",
   daily_price_8h: provider ? Number(provider?.daily_price_8h) : null,
   daily_price_6h: provider ? Number(provider?.daily_price_6h) : null,
@@ -382,7 +398,7 @@ const onOKClick = async () => {
       const fields = getUpdatedFields.value;
       Object.entries(fields).forEach(([key, value]) => {
         if (value !== null && value !== undefined) {
-          formData.append(key, String(value));
+          formData.append(key, typeof value === 'boolean' ? (value ? '1' : '0') : String(value));
         }
       });
       formData.append('avatar', avatarFile.value);
@@ -419,8 +435,27 @@ onMounted(async () => {
     avatarPreview.value = provider.profile_media?.url ?? null;
 
     const full = await getProvider(provider.id);
+    avatarPreview.value = full.profile_media?.url ?? avatarPreview.value;
     documentFrontUrl.value = full.document_front_media?.url ?? null;
     documentBackUrl.value = full.document_back_media?.url ?? null;
   }
 });
 </script>
+
+<style scoped>
+.doc-frame {
+  width: 300px;
+  height: 170px;
+  border: 1px solid #e0e0e0;
+  border-radius: 6px;
+  background: #fafafa;
+  overflow: hidden;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.doc-frame--clickable {
+  cursor: pointer;
+}
+</style>