|
@@ -3,155 +3,161 @@
|
|
|
<DefaultHeaderPage title="Cadastro de Usuário" />
|
|
<DefaultHeaderPage title="Cadastro de Usuário" />
|
|
|
|
|
|
|
|
<div class="q-pa-md">
|
|
<div class="q-pa-md">
|
|
|
- <div class="column justify-center items-center q-mb-lg">
|
|
|
|
|
- <AvatarImageComponent @update:file="onAvatarChange" />
|
|
|
|
|
-
|
|
|
|
|
- <div class="row full-width q-mt-md q-col-gutter-sm">
|
|
|
|
|
- <DefaultSelect
|
|
|
|
|
- v-model="form.state"
|
|
|
|
|
- label="Estado / UF"
|
|
|
|
|
- class="col-6"
|
|
|
|
|
- outlined
|
|
|
|
|
- emit-value
|
|
|
|
|
- map-options
|
|
|
|
|
- :options="stateOptions"
|
|
|
|
|
- />
|
|
|
|
|
-
|
|
|
|
|
- <DefaultSelect
|
|
|
|
|
- v-model="form.unit"
|
|
|
|
|
- label="Unidade"
|
|
|
|
|
- class="col-6"
|
|
|
|
|
- outlined
|
|
|
|
|
- emit-value
|
|
|
|
|
- map-options
|
|
|
|
|
- :options="unitOptions"
|
|
|
|
|
- />
|
|
|
|
|
-
|
|
|
|
|
- <DefaultSelect
|
|
|
|
|
- v-model="form.role"
|
|
|
|
|
- label="Tipo de Usuário"
|
|
|
|
|
- class="col-6"
|
|
|
|
|
- outlined
|
|
|
|
|
- emit-value
|
|
|
|
|
- map-options
|
|
|
|
|
- :options="roleOptions"
|
|
|
|
|
- />
|
|
|
|
|
-
|
|
|
|
|
- <DefaultInput
|
|
|
|
|
- v-model="form.cpf"
|
|
|
|
|
- label="CPF"
|
|
|
|
|
- class="col-6"
|
|
|
|
|
- outlined
|
|
|
|
|
- />
|
|
|
|
|
-
|
|
|
|
|
- <DefaultInput
|
|
|
|
|
- v-model="form.name"
|
|
|
|
|
- label="Nome"
|
|
|
|
|
- class="col-6"
|
|
|
|
|
- outlined
|
|
|
|
|
- />
|
|
|
|
|
-
|
|
|
|
|
- <DefaultInput
|
|
|
|
|
- v-model="form.password"
|
|
|
|
|
- label="Senha"
|
|
|
|
|
- class="col-6"
|
|
|
|
|
- outlined
|
|
|
|
|
- type="password"
|
|
|
|
|
- />
|
|
|
|
|
-
|
|
|
|
|
- <DefaultInput
|
|
|
|
|
- v-model="form.surname"
|
|
|
|
|
- label="Sobrenome"
|
|
|
|
|
- class="col-6"
|
|
|
|
|
- outlined
|
|
|
|
|
- />
|
|
|
|
|
-
|
|
|
|
|
- <DefaultInput
|
|
|
|
|
- v-model="form.password_confirmation"
|
|
|
|
|
- label="Repetir Senha"
|
|
|
|
|
- class="col-6"
|
|
|
|
|
- outlined
|
|
|
|
|
- type="password"
|
|
|
|
|
- />
|
|
|
|
|
-
|
|
|
|
|
- <DefaultInput
|
|
|
|
|
- v-model="form.email"
|
|
|
|
|
- label="E-mail"
|
|
|
|
|
- class="col-6"
|
|
|
|
|
- outlined
|
|
|
|
|
- type="email"
|
|
|
|
|
- />
|
|
|
|
|
-
|
|
|
|
|
- <div class="col-6 flex items-center">
|
|
|
|
|
|
|
+ <q-form ref="formRef">
|
|
|
|
|
+ <div class="column justify-center items-center q-mb-lg">
|
|
|
|
|
+ <AvatarImageComponent @update:file="(f) => (avatarFile = f)" />
|
|
|
|
|
+
|
|
|
|
|
+ <div class="row full-width q-mt-md q-col-gutter-sm">
|
|
|
|
|
+ <StateSelect
|
|
|
|
|
+ v-model="form.state"
|
|
|
|
|
+ class="col-6"
|
|
|
|
|
+ outlined
|
|
|
|
|
+ label="Estado / UF"
|
|
|
|
|
+ />
|
|
|
|
|
+
|
|
|
|
|
+ <UnitSelect
|
|
|
|
|
+ v-model="form.unit"
|
|
|
|
|
+ class="col-6"
|
|
|
|
|
+ outlined
|
|
|
|
|
+ label="Unidade"
|
|
|
|
|
+ />
|
|
|
|
|
+
|
|
|
|
|
+ <UserTypeSelect
|
|
|
|
|
+ v-model="form.user_type"
|
|
|
|
|
+ class="col-6"
|
|
|
|
|
+ outlined
|
|
|
|
|
+ label="Tipo de Usuário"
|
|
|
|
|
+ :rules="[inputRules.required]"
|
|
|
|
|
+ />
|
|
|
|
|
+
|
|
|
|
|
+ <DefaultInput
|
|
|
|
|
+ v-model="form.cpf"
|
|
|
|
|
+ label="CPF"
|
|
|
|
|
+ class="col-6"
|
|
|
|
|
+ outlined
|
|
|
|
|
+ mask="###.###.###-##"
|
|
|
|
|
+ :rules="[inputRules.cpf]"
|
|
|
|
|
+ />
|
|
|
|
|
+
|
|
|
|
|
+ <DefaultInput
|
|
|
|
|
+ v-model="form.name"
|
|
|
|
|
+ label="Nome"
|
|
|
|
|
+ class="col-6"
|
|
|
|
|
+ outlined
|
|
|
|
|
+ :rules="[inputRules.required]"
|
|
|
|
|
+ />
|
|
|
|
|
+
|
|
|
|
|
+ <DefaultInput
|
|
|
|
|
+ v-model="form.email"
|
|
|
|
|
+ label="E-mail"
|
|
|
|
|
+ class="col-6"
|
|
|
|
|
+ outlined
|
|
|
|
|
+ type="email"
|
|
|
|
|
+ :rules="[inputRules.required, inputRules.email]"
|
|
|
|
|
+ />
|
|
|
|
|
+
|
|
|
|
|
+ <DefaultInput
|
|
|
|
|
+ v-model="form.password"
|
|
|
|
|
+ label="Senha"
|
|
|
|
|
+ class="col-6"
|
|
|
|
|
+ outlined
|
|
|
|
|
+ type="password"
|
|
|
|
|
+ :rules="[inputRules.required, inputRules.min(8)]"
|
|
|
|
|
+ />
|
|
|
|
|
+
|
|
|
|
|
+ <DefaultInput
|
|
|
|
|
+ v-model="form.password_confirmation"
|
|
|
|
|
+ label="Repetir Senha"
|
|
|
|
|
+ class="col-6"
|
|
|
|
|
+ outlined
|
|
|
|
|
+ type="password"
|
|
|
|
|
+ :rules="[
|
|
|
|
|
+ inputRules.required,
|
|
|
|
|
+ inputRules.samePassword(form.password),
|
|
|
|
|
+ ]"
|
|
|
|
|
+ />
|
|
|
|
|
+
|
|
|
|
|
+ <div class="col-6 flex items-center">
|
|
|
|
|
+ <q-btn
|
|
|
|
|
+ label="Gerar senha segura"
|
|
|
|
|
+ icon="mdi-thumb-up-outline"
|
|
|
|
|
+ color="primary"
|
|
|
|
|
+ @click="generatePassword"
|
|
|
|
|
+ />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="row justify-end q-mt-md full-width">
|
|
|
<q-btn
|
|
<q-btn
|
|
|
- label="Gerar senha segura"
|
|
|
|
|
- icon="mdi-thumb-up-outline"
|
|
|
|
|
|
|
+ label="SALVAR"
|
|
|
|
|
+ icon-right="mdi-check"
|
|
|
color="primary"
|
|
color="primary"
|
|
|
- @click="generatePassword"
|
|
|
|
|
|
|
+ :loading="loading"
|
|
|
|
|
+ @click="onSave"
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
-
|
|
|
|
|
- <div class="row justify-end q-mt-md full-width">
|
|
|
|
|
- <q-btn
|
|
|
|
|
- label="SALVAR"
|
|
|
|
|
- icon-right="mdi-check"
|
|
|
|
|
- color="primary"
|
|
|
|
|
- @click="onSave"
|
|
|
|
|
- />
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
+ </q-form>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup>
|
|
<script setup>
|
|
|
|
|
+import { ref } from "vue";
|
|
|
|
|
+import { useRouter } from "vue-router";
|
|
|
import DefaultHeaderPage from "src/components/layout/DefaultHeaderPage.vue";
|
|
import DefaultHeaderPage from "src/components/layout/DefaultHeaderPage.vue";
|
|
|
import DefaultInput from "src/components/defaults/DefaultInput.vue";
|
|
import DefaultInput from "src/components/defaults/DefaultInput.vue";
|
|
|
-import DefaultSelect from "src/components/defaults/DefaultSelect.vue";
|
|
|
|
|
import AvatarImageComponent from "src/components/shared/AvatarImageComponent.vue";
|
|
import AvatarImageComponent from "src/components/shared/AvatarImageComponent.vue";
|
|
|
-import { ref } from "vue";
|
|
|
|
|
|
|
+import StateSelect from "src/components/selects/StateSelect.vue";
|
|
|
|
|
+import UnitSelect from "src/components/selects/UnitSelect.vue";
|
|
|
|
|
+import UserTypeSelect from "src/components/selects/UserTypeSelect.vue";
|
|
|
|
|
+import { useInputRules } from "src/composables/useInputRules";
|
|
|
|
|
+import { useSubmitHandler } from "src/composables/useSubmitHandler";
|
|
|
|
|
+import { createUser } from "src/api/user";
|
|
|
|
|
+
|
|
|
|
|
+const router = useRouter();
|
|
|
|
|
+const { inputRules } = useInputRules();
|
|
|
|
|
+
|
|
|
|
|
+const formRef = ref(null);
|
|
|
|
|
+const avatarFile = ref(null);
|
|
|
|
|
|
|
|
const form = ref({
|
|
const form = ref({
|
|
|
state: null,
|
|
state: null,
|
|
|
unit: null,
|
|
unit: null,
|
|
|
- role: null,
|
|
|
|
|
|
|
+ user_type: null,
|
|
|
cpf: null,
|
|
cpf: null,
|
|
|
name: null,
|
|
name: null,
|
|
|
- surname: null,
|
|
|
|
|
email: null,
|
|
email: null,
|
|
|
password: null,
|
|
password: null,
|
|
|
password_confirmation: null,
|
|
password_confirmation: null,
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
-const stateOptions = ref([
|
|
|
|
|
- { label: "Paraná", value: "PR" },
|
|
|
|
|
- { label: "São Paulo", value: "SP" },
|
|
|
|
|
- { label: "Santa Catarina", value: "SC" },
|
|
|
|
|
-]);
|
|
|
|
|
-
|
|
|
|
|
-const unitOptions = ref([
|
|
|
|
|
- { label: "Toledo-PR", value: "toledo" },
|
|
|
|
|
- { label: "Arapongas-PR", value: "arapongas" },
|
|
|
|
|
- { label: "Curitiba-PR", value: "curitiba" },
|
|
|
|
|
- { label: "Londrina-PR", value: "londrina" },
|
|
|
|
|
- { label: "Ponta Grossa-PR", value: "ponta_grossa" },
|
|
|
|
|
- { label: "Maringá-PR", value: "maringa" },
|
|
|
|
|
- { label: "Cascavel-PR", value: "cascavel" },
|
|
|
|
|
-]);
|
|
|
|
|
-
|
|
|
|
|
-const roleOptions = ref([
|
|
|
|
|
- { label: "Neurotainer", value: "neurotainer" },
|
|
|
|
|
- { label: "Assessor", value: "assessor" },
|
|
|
|
|
- { label: "Marketing", value: "marketing" },
|
|
|
|
|
- { label: "Comercial", value: "comercial" },
|
|
|
|
|
- { label: "Gestor", value: "gestor" },
|
|
|
|
|
- { label: "Administrativo", value: "administrativo" },
|
|
|
|
|
- { label: "Recepção", value: "recepcao" },
|
|
|
|
|
-]);
|
|
|
|
|
-
|
|
|
|
|
-function onAvatarChange(file) {
|
|
|
|
|
- console.log("Avatar file selected:", file);
|
|
|
|
|
|
|
+const { loading, execute } = useSubmitHandler({
|
|
|
|
|
+ formRef,
|
|
|
|
|
+ onSuccess: () => {
|
|
|
|
|
+ router.push({ name: "UserPage" });
|
|
|
|
|
+ },
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+function buildFormData() {
|
|
|
|
|
+ const fd = new FormData();
|
|
|
|
|
+
|
|
|
|
|
+ if (avatarFile.value) fd.append("avatar", avatarFile.value);
|
|
|
|
|
+ if (form.value.state?.value) fd.append("state_id", form.value.state.value);
|
|
|
|
|
+ if (form.value.unit?.value) fd.append("unit_id", form.value.unit.value);
|
|
|
|
|
+ if (form.value.user_type?.value)
|
|
|
|
|
+ fd.append("user_type", form.value.user_type.value);
|
|
|
|
|
+ if (form.value.cpf) fd.append("cpf", form.value.cpf);
|
|
|
|
|
+
|
|
|
|
|
+ fd.append("name", form.value.name ?? "");
|
|
|
|
|
+ fd.append("email", form.value.email ?? "");
|
|
|
|
|
+ fd.append("password", form.value.password ?? "");
|
|
|
|
|
+
|
|
|
|
|
+ return fd;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+async function onSave() {
|
|
|
|
|
+ await execute(() => createUser(buildFormData()));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function generatePassword() {
|
|
function generatePassword() {
|
|
@@ -163,8 +169,4 @@ function generatePassword() {
|
|
|
form.value.password = password;
|
|
form.value.password = password;
|
|
|
form.value.password_confirmation = password;
|
|
form.value.password_confirmation = password;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-function onSave() {
|
|
|
|
|
- console.log("Saving user:", form.value);
|
|
|
|
|
-}
|
|
|
|
|
</script>
|
|
</script>
|