Uecko_ERP/modules/customer-invoices/src/web/pages/create/customer-invoice-edit-form.tsx

962 lines
32 KiB
TypeScript

import { zodResolver } from "@hookform/resolvers/zod";
import { useFieldArray, useForm } from "react-hook-form";
import * as z from "zod";
import { ClientSelector } from "@erp/customers/components";
import { DevTool } from "@hookform/devtools";
import { DatePickerInputField, TextAreaField, TextField } from "@repo/rdx-ui/components";
import {
Button,
Calendar,
Card,
CardAction,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
Input,
Label,
Popover,
PopoverContent,
PopoverTrigger,
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
Separator,
Textarea,
} from "@repo/shadcn-ui/components";
import { format } from "date-fns";
import { es } from "date-fns/locale";
import { CalendarIcon, PlusIcon, Save, Trash2Icon, X } from "lucide-react";
import { CustomerInvoicePricesCard } from "../../components";
import { CustomerInvoiceItemsCardEditor } from "../../components/items";
import { useTranslation } from "../../i18n";
import { CustomerInvoiceData } from "./customer-invoice.schema";
import { formatCurrency } from "./utils";
const invoiceFormSchema = z.object({
id: z.string(),
invoice_status: z.string(),
invoice_number: z.string().min(1, "Número de factura requerido"),
invoice_series: z.string().min(1, "Serie requerida"),
issue_date: z.string(),
operation_date: z.string(),
language_code: z.string(),
currency: z.string(),
customer_id: z.string().min(1, "ID de cliente requerido"),
items: z
.array(
z.object({
description: z.string().optional(),
quantity: z
.object({
amount: z.number().nullable(),
scale: z.number(),
})
.optional(),
unit_price: z
.object({
amount: z.number().nullable(),
scale: z.number(),
currency_code: z.string(),
})
.optional(),
subtotal_price: z
.object({
amount: z.number().nullable(),
scale: z.number(),
currency_code: z.string(),
})
.optional(),
discount: z
.object({
amount: z.number().min(0).max(100).nullable(),
scale: z.number(),
})
.optional(),
discount_price: z
.object({
amount: z.number().nullable(),
scale: z.number(),
currency_code: z.string(),
})
.optional(),
total_price: z
.object({
amount: z.number().nullable(),
scale: z.number(),
currency_code: z.string(),
})
.optional(),
})
)
.min(1, "Al menos un item es requerido"),
subtotal_price: z.object({
amount: z.number().nullable(),
scale: z.number(),
currency_code: z.string(),
}),
discount: z.object({
amount: z.number().nullable(),
scale: z.number(),
}),
discount_price: z.object({
amount: z.number().nullable(),
scale: z.number(),
currency_code: z.string(),
}),
before_tax_price: z.object({
amount: z.number().nullable(),
scale: z.number(),
currency_code: z.string(),
}),
tax: z.object({
amount: z.number().nullable(),
scale: z.number(),
}),
tax_price: z.object({
amount: z.number().nullable(),
scale: z.number(),
currency_code: z.string(),
}),
total_price: z.object({
amount: z.number().nullable(),
scale: z.number(),
currency_code: z.string(),
}),
metadata: z.object({
entity: z.string(),
}),
});
const defaultInvoiceData = {
id: "34ae34af-1ffc-4de5-b0a8-c2cf203ef011",
invoice_status: "draft",
invoice_number: "1",
invoice_series: "A",
issue_date: "2025-04-30T00:00:00.000Z",
operation_date: "2025-04-30T00:00:00.000Z",
description: "",
language_code: "ES",
currency: "EUR",
customer_id: "5e4dc5b3-96b9-4968-9490-14bd032fec5f",
items: [
{
description: "",
quantity: {
amount: 100,
scale: 2,
},
unit_price: {
amount: 100,
scale: 2,
currency_code: "EUR",
},
subtotal_price: {
amount: 100,
scale: 2,
currency_code: "EUR",
},
discount: {
amount: 0,
scale: 2,
},
discount_price: {
amount: 0,
scale: 2,
currency_code: "EUR",
},
total_price: {
amount: 100,
scale: 2,
currency_code: "EUR",
},
},
],
subtotal_price: {
amount: 0,
scale: 2,
currency_code: "EUR",
},
discount: {
amount: 0,
scale: 0,
},
discount_price: {
amount: 0,
scale: 0,
currency_code: "EUR",
},
before_tax_price: {
amount: 0,
scale: 2,
currency_code: "EUR",
},
tax: {
amount: 2100,
scale: 2,
},
tax_price: {
amount: 0,
scale: 2,
currency_code: "EUR",
},
total_price: {
amount: 0,
scale: 2,
currency_code: "EUR",
},
};
interface InvoiceFormProps {
initialData?: CustomerInvoiceData;
isPending?: boolean;
/**
* Callback function to handle form submission.
* @param data - The invoice data submitted by the form.
*/
onSubmit?: (data: CustomerInvoiceData) => void;
}
export const CustomerInvoiceEditForm = ({
initialData = defaultInvoiceData,
onSubmit,
isPending,
}: InvoiceFormProps) => {
const { t } = useTranslation();
const form = useForm<CustomerInvoiceData>({
resolver: zodResolver(invoiceFormSchema),
defaultValues: initialData,
});
const { fields, append, remove } = useFieldArray({
control: form.control,
name: "items",
});
const watchedItems = form.watch("items");
const watchedTaxRate = form.watch("tax.amount");
const addItem = () => {
append({
id_article: "",
description: "",
quantity: { amount: 100, scale: 2 },
unit_price: { amount: 0, scale: 2, currency_code: form.getValues("currency") },
subtotal_price: { amount: 0, scale: 2, currency_code: form.getValues("currency") },
discount: { amount: 0, scale: 2 },
discount_price: { amount: 0, scale: 2, currency_code: form.getValues("currency") },
total_price: { amount: 0, scale: 2, currency_code: form.getValues("currency") },
});
};
const handleSubmit = (data: CustomerInvoiceData) => {
console.log("Datos del formulario:", data);
onSubmit?.(data);
};
const handleError = (errors: any) => {
console.error("Errores en el formulario:", errors);
// Aquí puedes manejar los errores, por ejemplo, mostrar un mensaje al usuario
};
const handleCancel = () => {
form.reset(initialData);
};
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(handleSubmit, handleError)}>
<div className='grid xl:grid-cols-2 space-y-6'>
<Card className='border-0 shadow-none xl:border-r xl:border-dashed rounded-none'>
<CardHeader>
<CardTitle>Cliente</CardTitle>
<CardDescription>Description</CardDescription>
<CardAction>
<Button variant='link'>Sign Up</Button>
<Button variant='link'>Sign Up</Button>
<Button variant='link'>Sign Up</Button>
<Button variant='link'>Sign Up</Button>
</CardAction>
</CardHeader>
<CardContent className='grid grid-cols-1 gap-4 space-y-6'>
<ClientSelector />
</CardContent>
<CardFooter className='flex-col gap-2'>
<Button type='submit' className='w-full'>
Login
</Button>
<Button variant='outline' className='w-full'>
Login with Google
</Button>
</CardFooter>{" "}
</Card>
{/* Información básica */}
<Card className='@container border-0 shadow-none'>
<CardHeader>
<CardTitle>Información Básica</CardTitle>
<CardDescription>Detalles generales de la factura</CardDescription>
</CardHeader>
<CardContent className='@xl:grid @xl:grid-cols-2 @xl:gap-x-6 gap-y-8'>
<TextField
control={form.control}
name='invoice_number'
required
disabled
readOnly
label={t("form_fields.invoice_number.label")}
placeholder={t("form_fields.invoice_number.placeholder")}
description={t("form_fields.invoice_number.description")}
/>
<TextField
control={form.control}
name='invoice_series'
required
label={t("form_fields.invoice_series.label")}
placeholder={t("form_fields.invoice_series.placeholder")}
description={t("form_fields.invoice_series.description")}
/>
<DatePickerInputField
control={form.control}
name='issue_date'
required
label={t("form_fields.issue_date.label")}
placeholder={t("form_fields.issue_date.placeholder")}
description={t("form_fields.issue_date.description")}
/>
<TextField
className='@xl:col-start-1 @xl:col-span-full'
control={form.control}
name='description'
required
label={t("form_fields.description.label")}
placeholder={t("form_fields.description.placeholder")}
description={t("form_fields.description.description")}
/>
<TextAreaField
className='field-sizing-content @xl:col-start-1 @xl:col-span-full'
control={form.control}
name='notes'
label={t("form_fields.notes.label")}
placeholder={t("form_fields.notes.placeholder")}
description={t("form_fields.notes.description")}
/>
</CardContent>
</Card>
</div>
</form>
</Form>
);
return (
<Form {...form}>
<form
onSubmit={form.handleSubmit(handleSubmit, handleError)}
className='grid grid-cols-1 md:gap-6 md:grid-cols-6'
>
<Card className='border-0 shadow-none md:grid-span-2'>
<CardHeader>
<CardTitle>Cliente</CardTitle>
<CardDescription>Description</CardDescription>
<CardAction>
<Button variant='link'>Sign Up</Button>
<Button variant='link'>Sign Up</Button>
<Button variant='link'>Sign Up</Button>
<Button variant='link'>Sign Up</Button>
</CardAction>
</CardHeader>
<CardContent className='grid grid-cols-1 gap-4 space-y-6'>
<div>
<div className='space-y-1'>
<h4 className='text-sm leading-none font-medium'>Radix Primitives</h4>
<p className='text-muted-foreground text-sm'>
An open-source UI component library.
</p>
</div>
<Separator className='my-4' />
<div className='flex h-5 items-center space-x-4 text-sm'>
<div>Blog</div>
<Separator orientation='vertical' />
<div>Docs</div>
<Separator orientation='vertical' />
<div>Source</div>
</div>
</div>
</CardContent>
<CardFooter className='flex-col gap-2'>
<Button type='submit' className='w-full'>
Login
</Button>
<Button variant='outline' className='w-full'>
Login with Google
</Button>
</CardFooter>{" "}
</Card>
{/* Información básica */}
<Card className='border-0 shadow-none '>
<CardHeader>
<CardTitle>Información Básica</CardTitle>
<CardDescription>Detalles generales de la factura</CardDescription>
</CardHeader>
<CardContent className='space-y-8'>
<div className='grid gap-y-6 gap-x-8 md:grid-cols-4'>
<TextField
control={form.control}
name='invoice_number'
required
disabled
readOnly
label={t("form_fields.invoice_number.label")}
placeholder={t("form_fields.invoice_number.placeholder")}
description={t("form_fields.invoice_number.description")}
/>
<DatePickerInputField
control={form.control}
name='issue_date'
required
label={t("form_fields.issue_date.label")}
placeholder={t("form_fields.issue_date.placeholder")}
description={t("form_fields.issue_date.description")}
/>
<TextField
control={form.control}
name='invoice_series'
required
label={t("form_fields.invoice_series.label")}
placeholder={t("form_fields.invoice_series.placeholder")}
description={t("form_fields.invoice_series.description")}
/>
</div>
<div className='grid gap-y-6 gap-x-8 grid-cols-1'>
<TextField
control={form.control}
name='description'
required
label={t("form_fields.description.label")}
placeholder={t("form_fields.description.placeholder")}
description={t("form_fields.description.description")}
/>
</div>
<div className='grid gap-y-6 gap-x-8 grid-cols-1'>
<TextAreaField
control={form.control}
name='notes'
required
label={t("form_fields.notes.label")}
placeholder={t("form_fields.notes.placeholder")}
description={t("form_fields.notes.description")}
/>
</div>
</CardContent>
</Card>
{/* Cliente */}
<Card className='col-span-full'>
<CardHeader>
<CardTitle>Cliente</CardTitle>
</CardHeader>
<CardContent className='grid grid-cols-1 gap-4 space-y-6'>
<ClientSelector />
<TextField
control={form.control}
name='customer_id'
required
label={t("form_fields.customer_id.label")}
placeholder={t("form_fields.customer_id.placeholder")}
description={t("form_fields.customer_id.description")}
/>
</CardContent>
</Card>
{/*Items */}
<CustomerInvoiceItemsCardEditor
defaultValues={defaultInvoiceData}
className='col-span-full'
/>
{/* Items */}
<Card>
<CardHeader className='flex flex-row items-center justify-between'>
<div>
<CardTitle>Artículos</CardTitle>
<CardDescription>Lista de productos o servicios facturados</CardDescription>
</div>
<Button type='button' onClick={addItem} size='sm'>
<PlusIcon className='h-4 w-4 mr-2' />
Agregar Item
</Button>
</CardHeader>
<CardContent className='space-y-4'>
{fields.map((field, index) => (
<Card key={field.id} className='p-4'>
<div className='flex justify-between items-start mb-4'>
<div className='flex items-center gap-2'>
<h4 className='font-medium'>Item {index + 1}</h4>
</div>
{fields.length > 1 && (
<Button type='button' variant='outline' size='sm' onClick={() => remove(index)}>
<Trash2Icon className='h-4 w-4' />
</Button>
)}
</div>
<div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-4'>
<FormField
control={form.control}
name={`items.${index}.id_article`}
render={({ field }) => (
<FormItem>
<FormLabel>Código Artículo</FormLabel>
<FormControl>
<Input placeholder='Código' {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name={`items.${index}.description`}
render={({ field }) => (
<FormItem className='md:col-span-2'>
<FormLabel>Descripción</FormLabel>
<FormControl>
<Textarea placeholder='Descripción del producto/servicio' {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<TextAreaField
control={form.control}
name={`items.${index}.description`}
label={t("form_fields.items.description.label")}
placeholder={t("form_fields.items.description.placeholder")}
description={t("form_fields.items.description.description")}
/>
<FormField
control={form.control}
name={`items.${index}.quantity.amount`}
render={({ field }) => (
<FormItem>
<FormLabel>Cantidad</FormLabel>
<FormControl>
<Input
type='number'
step='0.01'
min='0'
{...field}
onChange={(e) => field.onChange(Number(e.target.value) * 100)}
value={field.value / 100}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name={`items.${index}.unit_price.amount`}
render={({ field }) => (
<FormItem>
<FormLabel>Precio Unitario</FormLabel>
<FormControl>
<Input
type='number'
step='0.01'
min='0'
{...field}
onChange={(e) => field.onChange(Number(e.target.value) * 100)}
value={field.value / 100}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name={`items.${index}.discount.amount`}
render={({ field }) => (
<FormItem>
<FormLabel>Descuento (%)</FormLabel>
<FormControl>
<Input
type='number'
step='0.01'
min='0'
max='100'
{...field}
onChange={(e) => field.onChange(Number(e.target.value) * 100)}
value={field.value / 100}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
<div className='mt-4 p-3 bg-muted rounded-lg'>
<div className='text-sm text-muted-foreground'>
Total del item:{" "}
{formatCurrency(
watchedItems[index]?.total_price?.amount || 0,
2,
form.getValues("currency")
)}
</div>
</div>
</Card>
))}
</CardContent>
</Card>
<CustomerInvoicePricesCard />
{/* Configuración de Impuestos */}
<Card>
<CardHeader>
<CardTitle>Impuestos y Totales</CardTitle>
<CardDescription>Configuración de impuestos y resumen de totales</CardDescription>
</CardHeader>
<CardContent className='space-y-4'>
<div className='grid grid-cols-1 md:grid-cols-2 gap-4'>
<FormField
control={form.control}
name='tax.amount'
render={({ field }) => (
<FormItem>
<FormLabel>Tasa de Impuesto (%)</FormLabel>
<FormControl>
<Input
type='number'
step='0.01'
min='0'
max='100'
{...field}
onChange={(e) => field.onChange(Number(e.target.value) * 100)}
value={field.value / 100}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
<Separator />
{/* Resumen de totales */}
<div className='space-y-3'>
<div className='flex justify-between text-sm'>
<span>Subtotal:</span>
<span>
{formatCurrency(form.watch("subtotal_price.amount"), 2, form.watch("currency"))}
</span>
</div>
<div className='flex justify-between text-sm'>
<span>Descuento:</span>
<span>
-{formatCurrency(form.watch("discount_price.amount"), 2, form.watch("currency"))}
</span>
</div>
<div className='flex justify-between text-sm'>
<span>Base imponible:</span>
<span>
{formatCurrency(form.watch("before_tax_price.amount"), 2, form.watch("currency"))}
</span>
</div>
<div className='flex justify-between text-sm'>
<span>Impuestos ({(form.watch("tax.amount") / 100).toFixed(2)}%):</span>
<span>
{formatCurrency(form.watch("tax_price.amount"), 2, form.watch("currency"))}
</span>
</div>
<Separator />
<div className='flex justify-between text-lg font-semibold'>
<span>Total:</span>
<span>
{formatCurrency(form.watch("total_price.amount"), 2, form.watch("currency"))}
</span>
</div>
</div>
</CardContent>
</Card>
<div className='flex justify-end space-x-4'>
<Button type='button' variant='outline' disabled={isPending} onClick={handleCancel}>
Cancelar
</Button>
<Button type='submit' disabled={isPending}>
Guardar Factura
</Button>
</div>
</form>
<DevTool control={form.control} />
</Form>
);
return (
<div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 bg-muted/50'>
<form onSubmit={handleSubmit} className='space-y-6'>
{/* Información básica */}
<div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4'>
<div className='space-y-2'>
<Label htmlFor='id'>ID de Factura</Label>
<Input id='id' value={formData.id} disabled className='bg-muted' />
</div>
<div className='space-y-2'>
<Label htmlFor='invoice_status'>Estado</Label>
<Select
value={formData.invoice_status}
onValueChange={(value) => handleInputChange("invoice_status", value)}
>
<SelectTrigger>
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value='draft'>Borrador</SelectItem>
<SelectItem value='sent'>Enviada</SelectItem>
<SelectItem value='paid'>Pagada</SelectItem>
<SelectItem value='cancelled'>Cancelada</SelectItem>
</SelectContent>
</Select>
</div>
<div className='space-y-2'>
<Label htmlFor='language_code'>Idioma</Label>
<Select
value={formData.language_code}
onValueChange={(value) => handleInputChange("language_code", value)}
>
<SelectTrigger>
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value='ES'>Español</SelectItem>
<SelectItem value='EN'>English</SelectItem>
<SelectItem value='FR'>Français</SelectItem>
<SelectItem value='DE'>Deutsch</SelectItem>
</SelectContent>
</Select>
</div>
</div>
{/* Numeración */}
<div className='grid grid-cols-1 md:grid-cols-3 gap-4'>
<div className='space-y-2'>
<Label htmlFor='invoice_series'>Serie</Label>
<Input
id='invoice_series'
value={formData.invoice_series}
onChange={(e) => handleInputChange("invoice_series", e.target.value)}
placeholder='A'
/>
</div>
<div className='space-y-2'>
<Label htmlFor='invoice_number'>Número</Label>
<Input
id='invoice_number'
value={formData.invoice_number}
onChange={(e) => handleInputChange("invoice_number", e.target.value)}
placeholder='1'
/>
</div>
<div className='space-y-2 hidden'>
<Label htmlFor='currency'>Moneda</Label>
<Select
value={formData.currency}
onValueChange={(value) => handleInputChange("currency", value)}
>
<SelectTrigger>
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value='EUR'>EUR ()</SelectItem>
<SelectItem value='USD'>USD ($)</SelectItem>
<SelectItem value='GBP'>GBP (£)</SelectItem>
<SelectItem value='JPY'>JPY (¥)</SelectItem>
</SelectContent>
</Select>
</div>
</div>
{/* Fechas */}
<div className='grid grid-cols-1 md:grid-cols-2 gap-4'>
<div className='space-y-2'>
<Label>Fecha de Emisión</Label>
<Popover>
<PopoverTrigger asChild>
<Button variant='outline' className='w-full justify-start text-left font-normal'>
<CalendarIcon className='mr-2 h-4 w-4' />
{format(issueDate, "PPP", { locale: es })}
</Button>
</PopoverTrigger>
<PopoverContent className='w-auto p-0' align='start'>
<Calendar
mode='single'
selected={issueDate}
onSelect={(date) => handleDateChange("issue_date", date)}
initialFocus
/>
</PopoverContent>
</Popover>
</div>
<div className='space-y-2'>
<Label>Fecha de Operación</Label>
<Popover>
<PopoverTrigger asChild>
<Button variant='outline' className='w-full justify-start text-left font-normal'>
<CalendarIcon className='mr-2 h-4 w-4' />
{format(operationDate, "PPP", { locale: es })}
</Button>
</PopoverTrigger>
<PopoverContent className='w-auto p-0' align='start'>
<Calendar
mode='single'
selected={operationDate}
onSelect={(date) => handleDateChange("operation_date", date)}
initialFocus
/>
</PopoverContent>
</Popover>
</div>
</div>
{/* Importes */}
<div className='space-y-4'>
<h3 className='text-lg font-semibold'>Importes</h3>
<div className='grid grid-cols-1 md:grid-cols-2 gap-6'>
<Card>
<CardHeader className='pb-3'>
<CardTitle className='text-base'>Subtotal</CardTitle>
</CardHeader>
<CardContent className='space-y-3'>
<div className='space-y-2'>
<Label htmlFor='subtotal_amount'>Importe</Label>
<Input
id='subtotal_amount'
type='number'
step='0.01'
value={formData.subtotal.amount / Math.pow(10, formData.subtotal.scale)}
onChange={(e) =>
handleNestedChange(
"subtotal",
"amount",
Number.parseFloat(e.target.value) * Math.pow(10, formData.subtotal.scale)
)
}
/>
</div>
<div className='space-y-2'>
<Label htmlFor='subtotal_currency'>Moneda</Label>
<Select
value={formData.subtotal.currency_code}
onValueChange={(value) =>
handleNestedChange("subtotal", "currency_code", value)
}
>
<SelectTrigger>
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value='EUR'>EUR</SelectItem>
<SelectItem value='USD'>USD</SelectItem>
<SelectItem value='GBP'>GBP</SelectItem>
</SelectContent>
</Select>
</div>
</CardContent>
</Card>
<Card>
<CardHeader className='pb-3'>
<CardTitle className='text-base'>Total</CardTitle>
</CardHeader>
<CardContent className='space-y-3'>
<div className='space-y-2'>
<Label htmlFor='total_amount'>Importe</Label>
<Input
id='total_amount'
type='number'
step='0.01'
value={formData.total.amount / Math.pow(10, formData.total.scale)}
onChange={(e) =>
handleNestedChange(
"total",
"amount",
Number.parseFloat(e.target.value) * Math.pow(10, formData.total.scale)
)
}
/>
</div>
<div className='space-y-2'>
<Label htmlFor='total_currency'>Moneda</Label>
<Select
value={formData.total.currency_code}
onValueChange={(value) => handleNestedChange("total", "currency_code", value)}
>
<SelectTrigger>
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value='EUR'>EUR</SelectItem>
<SelectItem value='USD'>USD</SelectItem>
<SelectItem value='GBP'>GBP</SelectItem>
</SelectContent>
</Select>
</div>
</CardContent>
</Card>
</div>
</div>
{/* Botones de acción */}
<div className='flex justify-end gap-3 pt-6 border-t'>
<Button
type='button'
variant='outline'
onClick={handleCancel}
className='flex items-center gap-2'
>
<X className='h-4 w-4' />
Cancelar
</Button>
<Button type='submit' className='flex items-center gap-2'>
<Save className='h-4 w-4' />
Guardar Cambios
</Button>
</div>
</form>
</div>
);
};