Forráskód Böngészése

feat: ✨ feat (landingpage e verificacao automatica cadastro) criado novos campos dinamicos na landingpage e aprovacao automatica do associado

foram criados 4 novos campos na landingpage: visao, missao, valores e historia, preenchiveis no sistema web, e tambem foi finalizado o fluxo de cadastro -> aprovacao -> primeiro acesso e efetivacao do usuario, criando a aprovacao automatica caso o primeiro acesso seja do usuario que foi registrado pela importacao de excel

fase:dev | origin:escopo
Gustavo Zanatta 2 napja
szülő
commit
78d1f8cc27

+ 6 - 2
src/api/firstAccess.js

@@ -1,7 +1,11 @@
 import api from "src/api";
 
 export const checkFirstAccess = async (registration) => {
-  const { data } = await api.post("/first-access/check", { registration });
+  const { data } = await api.post(
+    "/first-access/check",
+    { registration },
+    { skipSuccessNotify: true },
+  );
   return { ...data.payload, message: data.message };
 };
 
@@ -17,7 +21,7 @@ export const registerFirstAccess = async (payload) => {
     headers: { "Content-Type": "multipart/form-data" },
     skipSuccessNotify: true,
   });
-  return data.payload;
+  return { ...data.payload, message: data.message };
 };
 
 export const getPublicPositions = async () => {

+ 5 - 0
src/i18n/locales/en.json

@@ -265,6 +265,7 @@
       "button": "My First Access",
       "title": "First Access",
       "registration": "Badge",
+      "last_name": "Last name",
       "registration_hint": "Enter your badge number to get started.",
       "form_title": "Complete your registration",
       "form_hint": "Fill in the fields below to finish your first access. Grey fields are filled in by the administration.",
@@ -275,7 +276,11 @@
       "finish": "Finish Registration",
       "success": "Registration completed successfully!",
       "success_login": "Registration completed! Sign in to access the system.",
+      "pending_approval": "Registration completed! Your membership is under review by the administration — you will be able to sign in once it is approved.",
       "already_done": "The first access for this badge has already been completed. Please sign in or use \"Forgot your password?\".",
+      "not_found": "Badge not found. Request your membership on the Serprati website and wait for the administration to approve it.",
+      "not_approved": "Your registration is still under review by the administration. You will be able to complete the first access once it is approved.",
+      "refused": "This registration was not approved by the administration. Please contact Serprati.",
       "back_to_login": "Back to login"
     }
   },

+ 5 - 0
src/i18n/locales/es.json

@@ -265,6 +265,7 @@
       "button": "Mi Primer Acceso",
       "title": "Primer Acceso",
       "registration": "Credencial",
+      "last_name": "Apellido",
       "registration_hint": "Ingrese el número de su credencial para comenzar.",
       "form_title": "Complete su registro",
       "form_hint": "Complete los datos a continuación para finalizar su primer acceso. Los campos en gris son completados por la administración.",
@@ -275,7 +276,11 @@
       "finish": "Finalizar Registro",
       "success": "¡Registro completado con éxito!",
       "success_login": "¡Registro completado! Inicie sesión para acceder al sistema.",
+      "pending_approval": "¡Registro completado! Su asociación está en análisis por la administración — podrá acceder en cuanto sea aprobada.",
       "already_done": "El primer acceso de esta credencial ya fue realizado. Inicie sesión normalmente o use \"¿Olvidó su contraseña?\".",
+      "not_found": "Credencial no encontrada. Solicite su asociación en el sitio de Serprati y espere la aprobación de la administración.",
+      "not_approved": "Su registro aún está en análisis por la administración. Podrá concluir el primer acceso en cuanto sea aprobado.",
+      "refused": "Este registro no fue aprobado por la administración. Póngase en contacto con Serprati.",
       "back_to_login": "Volver al inicio de sesión"
     }
   },

+ 5 - 0
src/i18n/locales/pt.json

@@ -265,6 +265,7 @@
       "button": "Meu Primeiro Acesso",
       "title": "Primeiro Acesso",
       "registration": "Crachá",
+      "last_name": "Sobrenome",
       "registration_hint": "Informe o número do seu crachá para começar.",
       "form_title": "Complete seu cadastro",
       "form_hint": "Preencha os dados abaixo para concluir seu primeiro acesso. Os campos em cinza são preenchidos pela administração.",
@@ -275,7 +276,11 @@
       "finish": "Concluir Cadastro",
       "success": "Cadastro concluído com sucesso!",
       "success_login": "Cadastro concluído! Faça login para acessar o sistema.",
+      "pending_approval": "Cadastro concluído! Sua associação está em análise pela administração — você poderá acessar assim que for aprovada.",
       "already_done": "O primeiro acesso deste crachá já foi realizado. Faça login normalmente ou use \"Esqueceu a senha?\".",
+      "not_found": "Crachá não encontrado. Solicite sua associação pelo site da Serprati e aguarde a liberação da administração.",
+      "not_approved": "Seu cadastro ainda está em análise pela administração. Você poderá concluir o primeiro acesso assim que for aprovado.",
+      "refused": "Este cadastro não foi aprovado pela administração. Entre em contato com a Serprati.",
       "back_to_login": "Voltar ao login"
     }
   },

+ 31 - 10
src/pages/login/FirstAccessFormPage.vue

@@ -56,6 +56,16 @@
             :label="$t('auth.first_access.registration')"
           />
 
+          <DefaultInput
+            v-model="form.cpf"
+            v-model:error="validationErrors.cpf"
+            :readonly="isLocked('cpf')"
+            :bg-color="isLocked('cpf') ? 'grey-2' : undefined"
+            :mask="masks.Brasil.cpf"
+            :label="$t('common.terms.cpf')"
+            :rules="[inputRules.required, inputRules.cpf]"
+          />
+
           <DefaultInput
             v-model="form.name"
             v-model:error="validationErrors.name"
@@ -66,13 +76,12 @@
           />
 
           <DefaultInput
-            v-model="form.cpf"
-            v-model:error="validationErrors.cpf"
-            :readonly="isLocked('cpf')"
-            :bg-color="isLocked('cpf') ? 'grey-2' : undefined"
-            :mask="masks.Brasil.cpf"
-            :label="$t('common.terms.cpf')"
-            :rules="[inputRules.required, inputRules.cpf]"
+            v-model="form.last_name"
+            v-model:error="validationErrors.last_name"
+            :readonly="isLocked('last_name')"
+            :bg-color="isLocked('last_name') ? 'grey-2' : undefined"
+            :label="$t('auth.first_access.last_name')"
+            :rules="[inputRules.required]"
           />
 
           <DefaultInput
@@ -209,8 +218,9 @@ const sectorOptions = ref([]);
 
 const form = ref({
   registration: null,
-  name: null,
   cpf: null,
+  name: null,
+  last_name: null,
   email: null,
   phone: null,
   position_id: null,
@@ -271,6 +281,7 @@ const {
 
 const prefillRules = {
   name: [inputRules.required],
+  last_name: [inputRules.required],
   cpf: [inputRules.required, inputRules.cpf],
   email: [inputRules.required, inputRules.email],
   phone: [inputRules.required],
@@ -325,7 +336,7 @@ const onSubmit = async () => {
 
   const password = form.value.password;
 
-  const user = await submitForm(() =>
+  const result = await submitForm(() =>
     registerFirstAccess({
       ...form.value,
       token: token.value,
@@ -333,10 +344,20 @@ const onSubmit = async () => {
     }),
   );
 
-  if (!user) return;
+  if (!result) return;
 
   clearFirstAccessData();
 
+  if (!result.can_login) {
+    $q.notify({
+      type: "warning",
+      message: result.message ?? t("auth.first_access.pending_approval"),
+      timeout: 8000,
+    });
+    router.push({ name: "LoginPage" });
+    return;
+  }
+
   try {
     await login(form.value.registration, password, { skipSuccessNotify: true });
     $q.notify({ type: "positive", message: t("auth.first_access.success") });

+ 13 - 2
src/pages/login/FirstAccessPage.vue

@@ -78,14 +78,25 @@ const {
   execute: submitForm,
 } = useSubmitHandler({ formRef });
 
+const ALLOWED_STATUS = "pending_first_access";
+
+const BLOCKED_MESSAGES = {
+  already_done: "auth.first_access.already_done",
+  not_found: "auth.first_access.not_found",
+  not_approved: "auth.first_access.not_approved",
+  refused: "auth.first_access.refused",
+};
+
 const onSubmit = async () => {
   const payload = await submitForm(() => checkFirstAccess(form.value.registration));
   if (!payload) return;
 
-  if (payload.status === "already_done") {
+  if (payload.status !== ALLOWED_STATUS) {
     $q.notify({
       type: "warning",
-      message: payload.message ?? t("auth.first_access.already_done"),
+      message:
+        payload.message ??
+        t(BLOCKED_MESSAGES[payload.status] ?? "auth.first_access.not_found"),
       timeout: 6000,
     });
     return;