- Updated CancelButton and SubmitButton to use i18next for localization. - Modified DataTableColumnHeader and DataTableFacetedFilter to include translations for sorting and filtering messages. - Enhanced DataTableSelectionColumn with localized aria-labels for accessibility. - Localized titles and messages in SimpleEmptyState and ErrorOverlay components. - Updated LayoutHeader to use i18next for navigation toggle label. - Integrated i18next into useLogout for error messages. - Localized alert dialog actions in useRemoveAlertDialog. - Added new translations in en.json and es.json for various UI components. - Updated breadcrumb and carousel components to use localized strings. - Enhanced pagination component with i18next for navigation labels. - Localized sheet component close button text.
162 lines
4.8 KiB
TypeScript
162 lines
4.8 KiB
TypeScript
import {
|
|
BackHistoryButton,
|
|
FormDatePickerField,
|
|
FormGroup,
|
|
FormTextAreaField,
|
|
FormTextField,
|
|
LoadingOverlay,
|
|
} from "@/components";
|
|
import { t } from "i18next";
|
|
|
|
import { SubmitButton } from "@/components";
|
|
import { useUnsavedChangesNotifier } from "@/lib/hooks";
|
|
import { Button, Form, Separator } from "@/ui";
|
|
import { useToast } from "@/ui/use-toast";
|
|
import { joiResolver } from "@hookform/resolvers/joi";
|
|
import { ICreateQuote_Request_DTO } from "@shared/contexts";
|
|
import Joi from "joi";
|
|
import { useMemo } from "react";
|
|
import { SubmitHandler, useForm } from "react-hook-form";
|
|
import { useNavigate } from "react-router-dom";
|
|
import SpanishJoiMessages from "../../spanish-joi-messages.json";
|
|
import { useQuotes } from "./hooks";
|
|
|
|
interface QuoteDataForm extends ICreateQuote_Request_DTO {}
|
|
|
|
export const QuoteCreate = () => {
|
|
const navigate = useNavigate();
|
|
const { toast } = useToast();
|
|
const { useCreate } = useQuotes();
|
|
const { mutate, isPending } = useCreate();
|
|
|
|
const defaultValues = useMemo(
|
|
() => ({
|
|
date: new Date(Date.now()).toUTCString(),
|
|
customer_reference: "",
|
|
customer_information: "",
|
|
//reference: "",
|
|
}),
|
|
[]
|
|
);
|
|
|
|
const form = useForm<QuoteDataForm>({
|
|
mode: "onBlur",
|
|
defaultValues,
|
|
resolver: joiResolver(
|
|
Joi.object({
|
|
customer_reference: Joi.string(),
|
|
date: Joi.date().required(),
|
|
customer_information: Joi.string().required(),
|
|
}),
|
|
{
|
|
messages: {
|
|
es: SpanishJoiMessages,
|
|
},
|
|
}
|
|
),
|
|
});
|
|
|
|
const { formState, reset, getValues, handleSubmit } = form;
|
|
const { isSubmitting, isDirty } = formState;
|
|
|
|
useUnsavedChangesNotifier({
|
|
isDirty,
|
|
});
|
|
|
|
const onSubmit: SubmitHandler<QuoteDataForm> = async (formData) => {
|
|
try {
|
|
mutate(formData, {
|
|
onError: (error) => {
|
|
console.debug(error);
|
|
toast({
|
|
title: t("common.error"),
|
|
description: error.message,
|
|
variant: "destructive",
|
|
});
|
|
},
|
|
onSuccess: (data) => {
|
|
reset(getValues());
|
|
toast({
|
|
title: t("quotes.notifications.created"),
|
|
variant: "default",
|
|
});
|
|
navigate(`/quotes/edit/${data.id}`, { relative: "path" });
|
|
},
|
|
});
|
|
} finally {
|
|
//setLoading(false);
|
|
}
|
|
};
|
|
|
|
if (isSubmitting) {
|
|
return <LoadingOverlay title={t("quotes.notifications.saving")} />;
|
|
}
|
|
|
|
/*if (isError) {
|
|
return <ErrorOverlay errorMessage={mutateError?.message} />;
|
|
}*/
|
|
|
|
if (isPending) {
|
|
return <LoadingOverlay />;
|
|
}
|
|
|
|
return (
|
|
<Form {...form}>
|
|
<form onSubmit={handleSubmit(onSubmit)}>
|
|
<div className='mx-auto grid max-w-[90rem] flex-1 auto-rows-max gap-6'>
|
|
<div className='flex items-center gap-4'>
|
|
<BackHistoryButton />
|
|
<h1 className='flex-1 text-xl font-semibold tracking-tight shrink-0 whitespace-nowrap sm:grow-0'>
|
|
{t("quotes.create.title")}
|
|
</h1>
|
|
</div>
|
|
|
|
<div className='grid w-6/12 gap-6 mx-auto'>
|
|
<FormGroup
|
|
className='md:col-span-4'
|
|
title={t("quotes.create.form_groups.general.title")}
|
|
description={t("quotes.create.form_groups.general.desc")}
|
|
footerActions={
|
|
<div className='flex items-stretch justify-between flex-1'>
|
|
<Button size='sm' variant={"outline"} onClick={() => navigate("/quotes")}>
|
|
{t("common.discard")}
|
|
</Button>
|
|
<SubmitButton size='sm' label={t("common.continue")}></SubmitButton>
|
|
</div>
|
|
}
|
|
>
|
|
<FormTextField
|
|
required
|
|
name='customer_reference'
|
|
label={t("quotes.form_fields.customer_reference.label")}
|
|
description={t("quotes.form_fields.customer_reference.desc")}
|
|
placeholder={t("quotes.form_fields.customer_reference.placeholder")}
|
|
/>
|
|
|
|
<FormDatePickerField
|
|
required
|
|
label={t("quotes.form_fields.date.label")}
|
|
description={t("quotes.form_fields.date.desc")}
|
|
placeholder={t("quotes.form_fields.date.placeholder")}
|
|
name='date'
|
|
/>
|
|
|
|
<Separator />
|
|
|
|
<FormTextAreaField
|
|
rows={4}
|
|
className='row-span-2'
|
|
name='customer_information'
|
|
required
|
|
label={t("quotes.form_fields.customer_information.label")}
|
|
description={t("quotes.form_fields.customer_information.desc")}
|
|
placeholder={t("quotes.form_fields.customer_information.placeholder")}
|
|
/>
|
|
</FormGroup>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</Form>
|
|
);
|
|
};
|