Arreglos estéticos y traducciones

This commit is contained in:
David Arranz 2024-08-12 12:52:11 +02:00
parent 37c87d820e
commit 95edcbcdb7
7 changed files with 313 additions and 263 deletions

View File

@ -99,187 +99,187 @@ export const SettingsEditor = () => {
} }
return ( return (
<> <Form {...form}>
<div className='grid w-full max-w-6xl gap-2 mx-auto'> <div className='grid w-full max-w-6xl gap-2 mx-auto'>
<h1 className='text-2xl font-semibold md:text-3xl'> <h1 className='text-2xl font-semibold md:text-3xl'>
<Trans i18nKey='settings.edit.title' /> <Trans i18nKey='settings.edit.title' />
</h1> </h1>
</div> </div>
<Form {...form}> <form onSubmit={handleSubmit(onSubmit)}>
<form onSubmit={handleSubmit(onSubmit)}> <div className='mx-auto grid w-full max-w-6xl items-start gap-6 md:grid-cols-[180px_1fr] lg:grid-cols-[250px_1fr]'>
<div className='mx-auto grid w-full max-w-6xl items-start gap-6 md:grid-cols-[180px_1fr] lg:grid-cols-[250px_1fr]'> {form.formState.errors.root?.message && (
{form.formState.errors.root?.message && ( <Alert variant='destructive'>
<Alert variant='destructive'> <AlertCircleIcon className='w-4 h-4' />
<AlertCircleIcon className='w-4 h-4' /> <AlertTitle>
<AlertTitle> <Trans i18nKey='common.error' />
<Trans i18nKey='common.error' /> </AlertTitle>
</AlertTitle> <AlertDescription>{form.formState.errors.root?.message}</AlertDescription>
<AlertDescription>{form.formState.errors.root?.message}</AlertDescription> </Alert>
</Alert> )}
)}
<nav className='grid gap-4 text-sm text-muted-foreground'> <nav className='grid gap-4 text-sm text-muted-foreground'>
<a <a
onClick={() => setActiveSection("profile")} onClick={() => setActiveSection("profile")}
className={ className={
activeSection === "profile" ? "font-semibold text-primary" : "cursor-pointer" activeSection === "profile" ? "font-semibold text-primary" : "cursor-pointer"
} }
> >
<Trans i18nKey='settings.edit.tabs.profile' /> <Trans i18nKey='settings.edit.tabs.profile' />
</a> </a>
<a <a
onClick={() => setActiveSection("quotes")} onClick={() => setActiveSection("quotes")}
className={ className={
activeSection === "quotes" ? "font-semibold text-primary" : "cursor-pointer " activeSection === "quotes" ? "font-semibold text-primary" : "cursor-pointer "
} }
> >
<Trans i18nKey='settings.edit.tabs.quotes' /> <Trans i18nKey='settings.edit.tabs.quotes' />
</a> </a>
<a <a
onClick={() => setActiveSection("legal")} onClick={() => setActiveSection("legal")}
className={ className={
activeSection === "legal" ? "font-semibold text-primary" : "cursor-pointer " activeSection === "legal" ? "font-semibold text-primary" : "cursor-pointer "
} }
> >
<Trans i18nKey='settings.edit.tabs.legal' /> <Trans i18nKey='settings.edit.tabs.legal' />
</a> </a>
</nav> </nav>
<div className={cn("grid gap-6", activeSection === "profile" ? "visible" : "hidden")}> <div className={cn("grid gap-6", activeSection === "profile" ? "visible" : "hidden")}>
<Card> <Card>
<CardHeader> <CardHeader>
<CardTitle> <CardTitle>
<Trans i18nKey='settings.form_fields.contact_information.label' /> <Trans i18nKey='settings.form_fields.contact_information.label' />
</CardTitle> </CardTitle>
<CardDescription> <CardDescription>
<Trans i18nKey='settings.form_fields.contact_information.desc' /> <Trans i18nKey='settings.form_fields.contact_information.desc' />
</CardDescription> </CardDescription>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<FormTextAreaField <FormTextAreaField
autoSize //autoSize
placeholder={t("settings.form_fields.contact_information.placeholder")} rows={8}
{...form.register("contact_information", { placeholder={t("settings.form_fields.contact_information.placeholder")}
required: true, {...form.register("contact_information", {
})} required: true,
errors={form.formState.errors} })}
/> errors={form.formState.errors}
</CardContent> />
<CardFooter className='px-6 py-4 border-t'> </CardContent>
<Button> <CardFooter className='px-6 py-4 border-t'>
<Trans i18nKey='common.save' /> <Button>
</Button> <Trans i18nKey='common.save' />
</CardFooter> </Button>
</Card> </CardFooter>
</div> </Card>
<div className={cn("grid gap-6", activeSection === "quotes" ? "visible" : "hidden")}>
<Card>
<CardHeader>
<CardTitle>
<Trans i18nKey='settings.form_fields.default_payment_method.label' />
</CardTitle>
<CardDescription>
<Trans i18nKey='settings.form_fields.default_payment_method.desc' />
</CardDescription>
</CardHeader>
<CardContent>
<FormTextAreaField
autoSize
placeholder={t("settings.form_fields.default_payment_method.placeholder")}
{...form.register("default_payment_method", {
required: true,
})}
errors={form.formState.errors}
/>
</CardContent>
<CardFooter className='px-6 py-4 border-t'>
<Button>
<Trans i18nKey='common.save' />
</Button>
</CardFooter>
</Card>
<Card>
<CardHeader>
<CardTitle>
<Trans i18nKey='settings.form_fields.default_quote_validity.label' />
</CardTitle>
<CardDescription>
<Trans i18nKey='settings.form_fields.default_quote_validity.desc' />
</CardDescription>
</CardHeader>
<CardContent>
<FormTextAreaField
autoSize
placeholder={t("settings.form_fields.default_quote_validity.placeholder")}
{...form.register("default_quote_validity", {
required: true,
})}
errors={form.formState.errors}
/>
</CardContent>
<CardFooter className='px-6 py-4 border-t'>
<Button>
<Trans i18nKey='common.save' />
</Button>
</CardFooter>
</Card>
<Card>
<CardHeader>
<CardTitle>
<Trans i18nKey='settings.form_fields.default_notes.label' />
</CardTitle>
<CardDescription>
<Trans i18nKey='settings.form_fields.default_notes.desc' />
</CardDescription>
</CardHeader>
<CardContent>
<FormTextAreaField
autoSize
placeholder={t("settings.form_fields.default_notes.placeholder")}
{...form.register("default_notes", {
required: true,
})}
errors={form.formState.errors}
/>
</CardContent>
<CardFooter className='px-6 py-4 border-t'>
<Button>
<Trans i18nKey='common.save' />
</Button>
</CardFooter>
</Card>
</div>
<div className={cn("grid gap-6", activeSection === "legal" ? "visible" : "hidden")}>
<Card>
<CardHeader>
<CardTitle>
<Trans i18nKey='settings.form_fields.default_legal_terms.label' />
</CardTitle>
<CardDescription>
<Trans i18nKey='settings.form_fields.default_legal_terms.desc' />
</CardDescription>
</CardHeader>
<CardContent>
<FormTextAreaField
autoSize
placeholder={t("settings.form_fields.default_legal_terms.placeholder")}
{...form.register("default_legal_terms", {
required: true,
})}
errors={form.formState.errors}
/>
</CardContent>
<CardFooter className='px-6 py-4 border-t'>
<Button>
<Trans i18nKey='common.save' />
</Button>
</CardFooter>
</Card>
</div>
</div> </div>
</form> <div className={cn("grid gap-6", activeSection === "quotes" ? "visible" : "hidden")}>
</Form> <Card>
</> <CardHeader>
<CardTitle>
<Trans i18nKey='settings.form_fields.default_payment_method.label' />
</CardTitle>
<CardDescription>
<Trans i18nKey='settings.form_fields.default_payment_method.desc' />
</CardDescription>
</CardHeader>
<CardContent>
<FormTextAreaField
autoSize
placeholder={t("settings.form_fields.default_payment_method.placeholder")}
{...form.register("default_payment_method", {
required: true,
})}
errors={form.formState.errors}
/>
</CardContent>
<CardFooter className='px-6 py-4 border-t'>
<Button>
<Trans i18nKey='common.save' />
</Button>
</CardFooter>
</Card>
<Card>
<CardHeader>
<CardTitle>
<Trans i18nKey='settings.form_fields.default_quote_validity.label' />
</CardTitle>
<CardDescription>
<Trans i18nKey='settings.form_fields.default_quote_validity.desc' />
</CardDescription>
</CardHeader>
<CardContent>
<FormTextAreaField
autoSize
placeholder={t("settings.form_fields.default_quote_validity.placeholder")}
{...form.register("default_quote_validity", {
required: true,
})}
errors={form.formState.errors}
/>
</CardContent>
<CardFooter className='px-6 py-4 border-t'>
<Button>
<Trans i18nKey='common.save' />
</Button>
</CardFooter>
</Card>
<Card>
<CardHeader>
<CardTitle>
<Trans i18nKey='settings.form_fields.default_notes.label' />
</CardTitle>
<CardDescription>
<Trans i18nKey='settings.form_fields.default_notes.desc' />
</CardDescription>
</CardHeader>
<CardContent>
<FormTextAreaField
autoSize
placeholder={t("settings.form_fields.default_notes.placeholder")}
{...form.register("default_notes", {
required: true,
})}
errors={form.formState.errors}
/>
</CardContent>
<CardFooter className='px-6 py-4 border-t'>
<Button>
<Trans i18nKey='common.save' />
</Button>
</CardFooter>
</Card>
</div>
<div className={cn("grid gap-6", activeSection === "legal" ? "visible" : "hidden")}>
<Card className='h-'>
<CardHeader>
<CardTitle>
<Trans i18nKey='settings.form_fields.default_legal_terms.label' />
</CardTitle>
<CardDescription>
<Trans i18nKey='settings.form_fields.default_legal_terms.desc' />
</CardDescription>
</CardHeader>
<CardContent>
<FormTextAreaField
//autoSize
rows={25}
placeholder={t("settings.form_fields.default_legal_terms.placeholder")}
{...form.register("default_legal_terms", {
required: true,
})}
errors={form.formState.errors}
/>
</CardContent>
<CardFooter className='px-6 py-4 border-t'>
<Button>
<Trans i18nKey='common.save' />
</Button>
</CardFooter>
</Card>
</div>
</div>
</form>
</Form>
); );
}; };

View File

@ -13,7 +13,7 @@ import {
} from "@/ui"; } from "@/ui";
import { CellContext } from "@tanstack/react-table"; import { CellContext } from "@tanstack/react-table";
import { t } from "i18next"; import { t } from "i18next";
import { MoreVerticalIcon } from "lucide-react"; import { MoreHorizontalIcon } from "lucide-react";
export type DataTablaRowActionFunction<TData> = ( export type DataTablaRowActionFunction<TData> = (
props: CellContext<TData, unknown> props: CellContext<TData, unknown>
@ -46,7 +46,7 @@ export function DataTableRowActions<TData = any, TValue = unknown>({
variant='link' variant='link'
className={cn("w-4 h-4 mt-2 text-ring hover:text-muted-foreground", className)} className={cn("w-4 h-4 mt-2 text-ring hover:text-muted-foreground", className)}
> >
<MoreVerticalIcon className='w-4 h-4' /> <MoreHorizontalIcon className='w-4 h-4' />
<span className='sr-only'>{t("common.open_menu")}</span> <span className='sr-only'>{t("common.open_menu")}</span>
</Button> </Button>
</DropdownMenuTrigger> </DropdownMenuTrigger>

View File

@ -1,5 +1,6 @@
import * as UI from "@/ui"; import * as UI from "@/ui";
import * as LabelPrimitive from "@radix-ui/react-label"; import * as LabelPrimitive from "@radix-ui/react-label";
import { t } from "i18next";
import React from "react"; import React from "react";
import { FormInputProps } from "./FormProps"; import { FormInputProps } from "./FormProps";
@ -16,7 +17,7 @@ export const FormLabel = React.forwardRef<
>(({ label, hint, required, ...props }, ref) => { >(({ label, hint, required, ...props }, ref) => {
const { error } = UI.useFormField(); const { error } = UI.useFormField();
const _hint = hint ? hint : required ? "obligatorio" : undefined; const _hint = hint ? hint : required ? t("common.required") : undefined;
const _hintClassName = error ? "text-destructive font-semibold" : ""; const _hintClassName = error ? "text-destructive font-semibold" : "";
return ( return (
<UI.FormLabel ref={ref} className='flex justify-between text-sm' {...props}> <UI.FormLabel ref={ref} className='flex justify-between text-sm' {...props}>

View File

@ -10,7 +10,7 @@ export const LayoutContent = ({
return ( return (
<main <main
className={cn( className={cn(
"flex min-h-[calc(100vh_-_theme(spacing.16))] flex-1 flex-col gap-4 bg-muted/40 p-4 md:gap-8 md:p-10", "flex min-h-[calc(100vh_-_theme(spacing.36))] flex-1 flex-col gap-4 bg-muted/40 p-4 md:gap-8 md:p-10",
className className
)} )}
> >

View File

@ -25,9 +25,10 @@ export const UserButton = () => {
const [userMenuOpened, setUserMenuOpened] = useState(false); const [userMenuOpened, setUserMenuOpened] = useState(false);
const navigate = useNavigate(); const navigate = useNavigate();
const { openDialog: openLogoutDialog, DialogComponent: LogoutDialog } = useCustomDialog({ const { openDialog: openLogoutDialog, DialogComponent: LogoutDialog } = useCustomDialog({
title: "Salir de la cuenta", title: t("main_menu.logout_dialog.title"),
description: "¿Desea salir de su cuenta?", description: t("main_menu.logout_dialog.description"),
confirmLabel: t("main_menu.user.logout"), confirmLabel: t("main_menu.logout_dialog.confirm_label"),
cancelLabel: t("main_menu.logout_dialog.cancel_label"),
onConfirm: () => { onConfirm: () => {
navigate("/logout"); navigate("/logout");
}, },

View File

@ -1,6 +1,7 @@
{ {
"translation": { "translation": {
"common": { "common": {
"required": "required",
"cancel": "Cancel", "cancel": "Cancel",
"no": "No", "no": "No",
"yes": "Yes", "yes": "Yes",
@ -12,28 +13,35 @@
"upload": "Upload", "upload": "Upload",
"continue": "Continue", "continue": "Continue",
"sort_asc": "Asc", "sort_asc": "Asc",
"sort_asc_description": "En order ascendente. Click para ordenar descendentemente.", "sort_asc_description": "In ascending order. Click to sort descending order.",
"sort_desc": "Desc", "sort_desc": "Desc",
"sort_desc_description": "En orden descendente. Click para ordenar ascendentemente.", "sort_desc_description": "In descending order. Click to sort in ascending order.",
"sort_none_description": "Sin orden. Click para ordenar ascendentemente.", "sort_none_description": "No sorting order. Click to sort in ascending order.",
"rows_selected": "{{count}} de {{total}} fila(s) seleccionadas.", "rows_selected": "{{count}} of {{total}} row(s) selected.",
"rows_per_page": "Filas por página", "rows_per_page": "Rows per page",
"num_page_of_total": "Página {{count}} de {{total}}", "num_page_of_total": "Page {{count}} of {{total}}",
"go_to_first_page": "Ir a la primera página", "go_to_first_page": "Go to first page",
"go_to_prev_page": "Ir a la página anterior", "go_to_prev_page": "Go to previous page",
"go_to_next_page": "Ir a la página siguiente", "go_to_next_page": "Go to next page",
"go_to_last_page": "Ir a la última página", "go_to_last_page": "Go to last page",
"filter_placeholder": "Escribe aquí para filtrar...", "filter_placeholder": "Type here to filter...",
"reset_filter": "Quitar el filtro", "reset_filter": "Remove the results filter",
"error": "Error", "error": "Error",
"actions": "Actions", "actions": "Actions",
"open_menu": "Open menu", "open_menu": "Open menu",
"duplicate_rows": "Duplicate", "duplicate_rows": "Duplicate",
"duplicate_rows_tooltip": "Duplica las fila(s) seleccionadas(s)", "duplicate_rows_tooltip": "Duplicate selected row(s)",
"pick_date": "Elige una fecha", "append_empty_row": "Append row",
"required_field": "Este campo es obligatorio", "append_empty_row_tooltip": "Append a empty row",
"unsaved_changes_prompt": "Los últimos cambios no se han guardado. Si continúas, se perderán", "append_article": "Append article",
"edit": "Editar" "append_article_tooltip": "Select and add an item from the catalog",
"remove_row": "Remove",
"insert_row_above": "Insert row above",
"insert_row_below": "Insert row below",
"pick_date": "Select a date",
"required_field": "This field is required",
"unsaved_changes_prompt": "There are unsaved changes. If you leave, you'll lose your changes.",
"edit": "Edit"
}, },
"main_menu": { "main_menu": {
"home": "Home", "home": "Home",
@ -50,29 +58,34 @@
"support": "Support", "support": "Support",
"logout": "Logout" "logout": "Logout"
}, },
"logout": {} "logout_dialog": {
"title": "Confirm",
"description": "Are you sure you want to log out?",
"confirm_label": "Log out",
"cancel_label": "Cancel"
}
}, },
"login_page": { "login_page": {
"title": "Presupuestador para distribuidores", "title": "Partner intranet",
"description": "Introduzca su dirección de correo electrónico y contraseña para acceder", "description": "Enter your email address and password to login",
"email_label": "Email", "email_label": "Email",
"email_placeholder": "micorreo@ejemplo.com", "email_placeholder": "myemail@sample.com",
"password_label": "Contraseña", "password_label": "Password",
"forgotten_password": "¿Has olvidado tu contraseña?", "forgotten_password": "Forgot your password?",
"become_dealer": "¿Quieres ser distribuidor de Uecko?", "become_dealer": "Do you want to become a Uecko partner?",
"contact_us": "Contacta con nosotros", "contact_us": "Contact us",
"login": "Entrar" "login": "Log in"
}, },
"dashboard": { "dashboard": {
"welcome": "Bienvenido" "welcome": "Welcome"
}, },
"catalog": { "catalog": {
"list": { "list": {
"title": "Catálogo de artículos", "title": "Catalog of articles",
"columns": { "columns": {
"description": "Descripción", "description": "Description",
"points": "Puntos", "points": "Points",
"retail_price": "PVP" "retail_price": "Retail price"
} }
} }
}, },
@ -96,31 +109,32 @@
"create": { "create": {
"title": "New quote", "title": "New quote",
"tabs": { "tabs": {
"general": "Datos generales", "general": "General data",
"items": "Contenido", "items": "Quote items",
"documents": "Documentos", "preview": "Quote preview",
"history": "Historial" "documents": "Documents",
"history": "History"
}, },
"form_groups": { "form_groups": {
"general": { "general": {
"title": "Datos generales", "title": "General Data",
"desc": "Datos generales y cliente al que va la cotización" "desc": "General data and quote customer"
}, },
"status": { "status": {
"title": "Estado", "title": "Status",
"desc": "Estado de la cotización" "desc": "Quote status"
}, },
"items": { "items": {
"title": "Contenido de la cotización", "title": "Quote Items",
"desc": "Líneas de detalle de la cotización. Ayúdese del catálogo para rellenar más fácilmente el contenido." "desc": "Quote detail lines. Use the catalog to make it easier to fill in the content."
}, },
"documents": { "documents": {
"title": "Documentos", "title": "Attached Documents",
"desc": "Añada adjuntar con su cotización documentos como fotos, planos, croquis, etc." "desc": "Attach documents such as photos, drawings, sketches, etc. to your quotation."
}, },
"history": { "history": {
"title": "", "title": "History",
"desc": "" "desc": "Quote history"
} }
}, },
"edit": { "edit": {
@ -141,54 +155,69 @@
}, },
"reference": { "reference": {
"label": "Reference", "label": "Reference",
"desc": "Referencia para esta cotización", "desc": "Quote reference",
"placeholder": "" "placeholder": ""
}, },
"lang_code": { "lang_code": {
"label": "Idioma", "label": "Language",
"desc": "Idioma de la cotización", "desc": "Quote language",
"placeholder": "" "placeholder": ""
}, },
"currency_code": { "currency_code": {
"label": "Moneda", "label": "Currency",
"desc": "Moneda de la cotización", "desc": "Quote currency",
"placeholder": "" "placeholder": ""
}, },
"customer_information": { "customer_information": {
"label": "Customer's contact data", "label": "Customer's contact data",
"desc": "Escriba el nombre del cliente en la primera línea, la direccion en la segunda y el código postal y ciudad en la tercera.", "desc": "Recommendation: enter the customer's name on the first line, the address on the second line, and the zip code and city/state on the third line.",
"placeholder": "Nombre y apellidos\nCalle y número\nCódigo postal y ciudad..." "placeholder": "Name and surname\nStreet and number\nzip code and city or state..."
}, },
"payment_method": { "payment_method": {
"label": "Forma de pago", "label": "Payment method",
"placeholder": "placeholder", "placeholder": "",
"desc": "desc" "desc": "Method of payment of the quote"
}, },
"notes": { "notes": {
"label": "Notas", "label": "Notes",
"placeholder": "", "placeholder": "",
"desc": "desc" "desc": "Quote's notes"
}, },
"validity": { "validity": {
"label": "Validez de la cotización", "label": "Validity time",
"placeholder": "", "placeholder": "",
"desc": "desc" "desc": "Quote's validity time"
},
"discount": {
"label": "Discount",
"placeholder": "%",
"desc": "Percentage discount"
},
"tax": {
"label": "Tax",
"placeholder": "%",
"desc": "Percentage Tax"
},
"subtotal_price": {
"label": "Subtotal",
"placeholder": "",
"desc": "Quote subtotal"
}, },
"items": { "items": {
"quantity": { "quantity": {
"label": "Cantidad", "label": "Quantity",
"placeholder": "", "placeholder": "",
"desc": "" "desc": ""
}, },
"description": { "description": {
"label": "Descripción", "label": "Description",
"placeholder": "", "placeholder": "",
"desc": "" "desc": ""
}, },
"unit_price": { "unit_price": {
"label": "Imp. unitario", "label": "Unit price",
"placeholder": "", "placeholder": "",
"desc": "Importe unitario del artículo" "desc": "Item unit price"
}, },
"subtotal_price": { "subtotal_price": {
"label": "Subtotal", "label": "Subtotal",
@ -198,12 +227,12 @@
"discount": { "discount": {
"label": "Dto (%)", "label": "Dto (%)",
"placeholder": "", "placeholder": "",
"desc": "Porcentaje de descuento" "desc": "Percentage discount"
}, },
"total_price": { "total_price": {
"label": "Imp. total", "label": "Total price",
"placeholder": "", "placeholder": "",
"desc": "Importe total con el descuento ya aplicado" "desc": "Total price with percentage discount"
} }
} }
} }
@ -220,34 +249,34 @@
}, },
"form_fields": { "form_fields": {
"image": { "image": {
"label": "Información de contacto", "label": "Logotype",
"placeholder": "placeholder", "placeholder": "placeholder",
"desc": "Información de contacto" "desc": "Información de contacto"
}, },
"contact_information": { "contact_information": {
"label": "Información de contacto", "label": "Your contact information",
"placeholder": "placeholder", "placeholder": "placeholder",
"desc": "Información de contacto" "desc": "Your contact information as a dealer that will appear on the quotes given to your customers."
}, },
"default_legal_terms": { "default_legal_terms": {
"label": "Cláusulas legales", "label": "Legal terms",
"placeholder": "", "placeholder": "",
"desc": "desc" "desc": "Legal information to be included at the end of your quotes"
}, },
"default_payment_method": { "default_payment_method": {
"label": "Forma de pago", "label": "Payment method",
"placeholder": "placeholder", "placeholder": "placeholder",
"desc": "desc" "desc": "Default payment method to be used for new quotes"
}, },
"default_notes": { "default_notes": {
"label": "Notas", "label": "Notes",
"placeholder": "", "placeholder": "",
"desc": "desc" "desc": "Default notes to be used for new quotes"
}, },
"default_quote_validity": { "default_quote_validity": {
"label": "Validez por defecto", "label": "Quote validity",
"placeholder": "", "placeholder": "",
"desc": "" "desc": "Default validity time to be used for new quotes"
} }
} }
} }

View File

@ -1,6 +1,7 @@
{ {
"translation": { "translation": {
"common": { "common": {
"required": "obligatorio",
"cancel": "Cancelar", "cancel": "Cancelar",
"no": "No", "no": "No",
"yes": "Sí", "yes": "Sí",
@ -30,9 +31,16 @@
"open_menu": "Abrir el menú", "open_menu": "Abrir el menú",
"duplicate_rows": "Duplicar", "duplicate_rows": "Duplicar",
"duplicate_rows_tooltip": "Duplica las fila(s) seleccionadas(s)", "duplicate_rows_tooltip": "Duplica las fila(s) seleccionadas(s)",
"append_empty_row": "Añadir fila",
"append_empty_row_tooltip": "Añadir una fila vacía",
"append_article": "Añadir artículo",
"append_article_tooltip": "Elegir un artículo del catálogo y añadirlo",
"remove_row": "Eliminar",
"insert_row_above": "Insertar fila encima",
"insert_row_below": "Insertar fila debajo",
"pick_date": "Elige una fecha", "pick_date": "Elige una fecha",
"required_field": "Este campo es obligatorio", "required_field": "Este campo es obligatorio",
"unsaved_changes_prompt": "Los últimos cambios no se han guardado. Si continúas, se perderán", "unsaved_changes_prompt": "Los últimos cambios no se han guardado. Si continúas, se perderán.",
"edit": "Editar" "edit": "Editar"
}, },
"main_menu": { "main_menu": {
@ -50,7 +58,12 @@
"support": "Soporte", "support": "Soporte",
"logout": "Salir" "logout": "Salir"
}, },
"logout": {} "logout_dialog": {
"title": "Salir de la cuenta",
"description": "¿Desea salir de su cuenta?",
"confirm_label": "Salir",
"cancel_label": "Cancelar"
}
}, },
"login_page": { "login_page": {
"title": "Presupuestador para distribuidores", "title": "Presupuestador para distribuidores",
@ -99,6 +112,7 @@
"tabs": { "tabs": {
"general": "Datos generales", "general": "Datos generales",
"items": "Contenido", "items": "Contenido",
"preview": "Vista previa",
"documents": "Documentos", "documents": "Documentos",
"history": "Historial" "history": "Historial"
}, },
@ -157,7 +171,7 @@
}, },
"customer_information": { "customer_information": {
"label": "Datos del cliente", "label": "Datos del cliente",
"desc": "Escriba el nombre del cliente en la primera línea, la direccion en la segunda y el código postal y ciudad en la tercera.", "desc": "Recomensación: escriba el nombre del cliente en la primera línea, la direccion en la segunda y el código postal y ciudad en la tercera.",
"placeholder": "Nombre y apellidos\nCalle y número\nCódigo postal y ciudad..." "placeholder": "Nombre y apellidos\nCalle y número\nCódigo postal y ciudad..."
}, },
"payment_method": { "payment_method": {
@ -177,11 +191,16 @@
}, },
"discount": { "discount": {
"label": "Descuento", "label": "Descuento",
"placeholder": "", "placeholder": "%",
"desc": "" "desc": "Porcentaje de descuento"
}, },
"tax": { "tax": {
"label": "IVA", "label": "IVA",
"placeholder": "%",
"desc": "Porcentaje de IVA"
},
"subtotal_price": {
"label": "Importe neto",
"placeholder": "", "placeholder": "",
"desc": "" "desc": ""
}, },