219 lines
8.3 KiB
Vue
219 lines
8.3 KiB
Vue
<script setup>
|
|
import { useForm, apiURL } from '@Services/Api';
|
|
|
|
import Modal from '@Holos/Modal.vue';
|
|
import FormInput from '@Holos/Form/Input.vue';
|
|
import FormError from '@Holos/Form/Elements/Error.vue';
|
|
|
|
/** Eventos */
|
|
const emit = defineEmits(['close', 'created']);
|
|
|
|
/** Propiedades */
|
|
const props = defineProps({
|
|
show: Boolean
|
|
});
|
|
|
|
/** Formulario */
|
|
const form = useForm({
|
|
name: '',
|
|
email: '',
|
|
phone: '',
|
|
address: '',
|
|
rfc: '',
|
|
razon_social: '',
|
|
regimen_fiscal: '',
|
|
cp_fiscal: '',
|
|
uso_cfdi: ''
|
|
});
|
|
|
|
/** Métodos */
|
|
const createClient = () => {
|
|
form.post(apiURL('clients'), {
|
|
onSuccess: () => {
|
|
window.Notify.success('Cliente creado exitosamente');
|
|
emit('created');
|
|
closeModal();
|
|
},
|
|
onError: () => {
|
|
window.Notify.error('Error al crear el cliente');
|
|
}
|
|
});
|
|
};
|
|
|
|
const closeModal = () => {
|
|
form.reset();
|
|
emit('close');
|
|
};
|
|
|
|
</script>
|
|
|
|
<template>
|
|
<Modal :show="show" max-width="md" @close="closeModal">
|
|
<div class="p-6">
|
|
<!-- Header -->
|
|
<div class="flex items-center justify-between mb-6">
|
|
<h3 class="text-lg font-bold text-gray-900 dark:text-gray-100">
|
|
Crear Cliente
|
|
</h3>
|
|
<button
|
|
@click="closeModal"
|
|
class="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300"
|
|
>
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Formulario -->
|
|
<form @submit.prevent="createClient" class="space-y-4">
|
|
<div class="grid grid-cols-2 gap-4">
|
|
<!-- Nombre -->
|
|
<div class="col-span-2">
|
|
<label class="block text-xs font-semibold text-gray-700 dark:text-gray-300 uppercase mb-1.5">
|
|
NOMBRE
|
|
</label>
|
|
<FormInput
|
|
v-model="form.name"
|
|
type="text"
|
|
placeholder="Nombre del cliente"
|
|
required
|
|
/>
|
|
<FormError :message="form.errors?.name" />
|
|
</div>
|
|
|
|
<!-- Email -->
|
|
<div>
|
|
<label class="block text-xs font-semibold text-gray-700 dark:text-gray-300 uppercase mb-1.5">
|
|
EMAIL
|
|
</label>
|
|
<FormInput
|
|
v-model="form.email"
|
|
type="text"
|
|
placeholder="Email"
|
|
required
|
|
/>
|
|
<FormError :message="form.errors?.email" />
|
|
</div>
|
|
<!-- Teléfono -->
|
|
<div>
|
|
<label class="block text-xs font-semibold text-gray-700 dark:text-gray-300 uppercase mb-1.5">
|
|
TELÉFONO
|
|
</label>
|
|
<FormInput
|
|
v-model="form.phone"
|
|
type="text"
|
|
placeholder="9933428818"
|
|
maxlength="10"
|
|
/>
|
|
<FormError :message="form.errors?.phone" />
|
|
</div>
|
|
|
|
<!-- Dirección -->
|
|
<div>
|
|
<label class="block text-xs font-semibold text-gray-700 dark:text-gray-300 uppercase mb-1.5">
|
|
DIRECCIÓN
|
|
</label>
|
|
<FormInput
|
|
v-model="form.address"
|
|
type="text"
|
|
placeholder="Dirección"
|
|
required
|
|
/>
|
|
<FormError :message="form.errors?.address" />
|
|
</div>
|
|
|
|
<!-- RFC -->
|
|
<div>
|
|
<label class="block text-xs font-semibold text-gray-700 dark:text-gray-300 uppercase mb-1.5">
|
|
RFC
|
|
</label>
|
|
<FormInput
|
|
v-model="form.rfc"
|
|
type="text"
|
|
placeholder="RFC"
|
|
required
|
|
/>
|
|
<FormError :message="form.errors?.rfc" />
|
|
</div>
|
|
|
|
<!-- RAZÓN SOCIAL -->
|
|
<div>
|
|
<label class="block text-xs font-semibold text-gray-700 dark:text-gray-300 uppercase mb-1.5">
|
|
RAZÓN SOCIAL
|
|
</label>
|
|
<FormInput
|
|
v-model="form.razon_social"
|
|
type="text"
|
|
placeholder="Razón Social"
|
|
required
|
|
/>
|
|
<FormError :message="form.errors?.razon_social" />
|
|
</div>
|
|
|
|
<!-- REGIMEN FISCAL-->
|
|
<div>
|
|
<label class="block text-xs font-semibold text-gray-700 dark:text-gray-300 uppercase mb-1.5">
|
|
REGIMEN FISCAL
|
|
</label>
|
|
<FormInput
|
|
v-model="form.regimen_fiscal"
|
|
type="text"
|
|
placeholder="Regimen Fiscal"
|
|
required
|
|
/>
|
|
<FormError :message="form.errors?.regimen_fiscal" />
|
|
</div>
|
|
|
|
<!-- CP FISCAL-->
|
|
<div>
|
|
<label class="block text-xs font-semibold text-gray-700 dark:text-gray-300 uppercase mb-1.5">
|
|
CP FISCAL
|
|
</label>
|
|
<FormInput
|
|
v-model="form.cp_fiscal"
|
|
type="text"
|
|
placeholder="CP Fiscal"
|
|
required
|
|
/>
|
|
<FormError :message="form.errors?.cp_fiscal" />
|
|
</div>
|
|
|
|
<!-- USO CFDI -->
|
|
<div>
|
|
<label class="block text-xs font-semibold text-gray-700 dark:text-gray-300 uppercase mb-1.5">
|
|
USO DE CFDI
|
|
</label>
|
|
<FormInput
|
|
v-model="form.uso_cdfi"
|
|
type="text"
|
|
placeholder="03 - Gastos en general"
|
|
required
|
|
/>
|
|
<FormError :message="form.errors?.uso_cdfi" />
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Botones -->
|
|
<div class="flex items-center justify-end gap-3 mt-6">
|
|
<button
|
|
type="button"
|
|
@click="closeModal"
|
|
class="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition-colors"
|
|
>
|
|
Cancelar
|
|
</button>
|
|
<button
|
|
type="submit"
|
|
:disabled="form.processing"
|
|
class="px-4 py-2 text-sm font-semibold text-white bg-gray-900 rounded-lg hover:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-900 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
|
|
>
|
|
<span v-if="form.processing">Guardando...</span>
|
|
<span v-else>Guardar</span>
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</Modal>
|
|
</template>
|