.
This commit is contained in:
parent
54dc0a8442
commit
b2a8073007
@ -21,5 +21,5 @@ export const StartPage = () => {
|
||||
);
|
||||
}
|
||||
|
||||
return <Navigate to={"/quotes"} replace />;
|
||||
return <Navigate to={"/home"} replace />;
|
||||
};
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import { Container, FormTextField } from "@/components";
|
||||
import { FormSubmitButton } from "@/components/Forms/FormSubmitButton";
|
||||
import { UeckoLogo } from "@/components/UeckoLogo/UeckoLogo";
|
||||
import { useLogin } from "@/lib/hooks";
|
||||
import {
|
||||
Alert,
|
||||
AlertDescription,
|
||||
AlertTitle,
|
||||
Button,
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
@ -18,7 +18,6 @@ import { ILogin_DTO } from "@shared/contexts";
|
||||
import { t } from "i18next";
|
||||
import Joi from "joi";
|
||||
import { AlertCircleIcon } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { SubmitHandler, useForm } from "react-hook-form";
|
||||
import { Trans } from "react-i18next";
|
||||
import { Link } from "react-router-dom";
|
||||
@ -27,7 +26,6 @@ import SpanishJoiMessages from "../../spanish-joi-messages.json";
|
||||
type LoginDataForm = ILogin_DTO;
|
||||
|
||||
export const LoginPage = () => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const { mutate: login } = useLogin({
|
||||
onSuccess: (data) => {
|
||||
const { success, error } = data;
|
||||
@ -57,12 +55,7 @@ export const LoginPage = () => {
|
||||
});
|
||||
|
||||
const onSubmit: SubmitHandler<LoginDataForm> = async (data) => {
|
||||
try {
|
||||
setLoading(true);
|
||||
login({ email: data.email, password: data.password });
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
login({ email: data.email, password: data.password }, {});
|
||||
};
|
||||
|
||||
return (
|
||||
@ -121,9 +114,7 @@ export const LoginPage = () => {
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
<Button disabled={loading} type='submit' className='w-full'>
|
||||
<Trans i18nKey='login_page.login' />
|
||||
</Button>
|
||||
<FormSubmitButton className='w-full' label={t("login_page.login")} />
|
||||
|
||||
<div className='mt-4 text-sm text-center'>
|
||||
<Trans i18nKey='login_page.become_dealer' />
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
import { Card, CardContent } from "@/ui";
|
||||
import { Badge, Card, CardContent } from "@/ui";
|
||||
|
||||
import { DataTableSkeleton, ErrorOverlay, SimpleEmptyState } from "@/components";
|
||||
|
||||
import { DataTable } from "@/components";
|
||||
import { DataTableToolbar } from "@/components/DataTable/DataTableToolbar";
|
||||
import { useDataTable, useDataTableContext } from "@/lib/hooks";
|
||||
import { IListQuotes_Response_DTO, MoneyValue } from "@shared/contexts";
|
||||
import { ColumnDef, Row } from "@tanstack/react-table";
|
||||
import { IListQuotes_Response_DTO, MoneyValue, UTCDateValue } from "@shared/contexts";
|
||||
import { ColumnDef } from "@tanstack/react-table";
|
||||
import { t } from "i18next";
|
||||
import { useMemo } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
@ -27,47 +27,51 @@ export const QuotesDataTable = () => {
|
||||
const columns = useMemo<ColumnDef<IListQuotes_Response_DTO, any>[]>(
|
||||
() => [
|
||||
{
|
||||
id: "id" as const,
|
||||
accessorKey: "id",
|
||||
id: "date" as const,
|
||||
accessor: "date",
|
||||
header: () => <>{t("quotes.list.columns.date")}</>,
|
||||
cell: ({ table, row: { index, original }, column, getValue }) => {
|
||||
console.log(original.date);
|
||||
const quoteDate = UTCDateValue.create(original.date);
|
||||
return quoteDate.isSuccess ? quoteDate.object.toLocaleDateString("es-ES") : "-";
|
||||
},
|
||||
enableResizing: false,
|
||||
size: 10,
|
||||
},
|
||||
{
|
||||
id: "article_id" as const,
|
||||
accessorKey: "id_article",
|
||||
enableResizing: false,
|
||||
size: 10,
|
||||
},
|
||||
{
|
||||
id: "catalog_name" as const,
|
||||
accessorKey: "catalog_name",
|
||||
enableResizing: false,
|
||||
size: 10,
|
||||
},
|
||||
{
|
||||
id: "description" as const,
|
||||
accessorKey: "description",
|
||||
header: () => <>{t("catalog.list.columns.description")}</>,
|
||||
enableResizing: false,
|
||||
size: 100,
|
||||
},
|
||||
{
|
||||
id: "points" as const,
|
||||
accessorKey: "points",
|
||||
header: () => <div className='text-right'>{t("catalog.list.columns.points")}</div>,
|
||||
id: "customer_information" as const,
|
||||
accessorKey: "customer_information",
|
||||
header: () => <>{t("quotes.list.columns.customer_information")}</>,
|
||||
cell: ({ renderValue }: { renderValue: () => any }) => (
|
||||
<div className='text-right'>{renderValue()}</div>
|
||||
<div className='font-semibold'>{renderValue()}</div>
|
||||
),
|
||||
enableResizing: false,
|
||||
size: 20,
|
||||
size: 10,
|
||||
},
|
||||
{
|
||||
id: "retail_price" as const,
|
||||
accessorKey: "retail_price",
|
||||
header: () => <div className='text-right'>{t("catalog.list.columns.retail_price")}</div>,
|
||||
cell: ({ row }: { row: Row<any> }) => {
|
||||
const price = MoneyValue.create(row.original.retail_price).object;
|
||||
return <div className='text-right'>{price.toFormat()}</div>;
|
||||
id: "reference" as const,
|
||||
accessorKey: "reference",
|
||||
header: () => <>{t("quotes.list.columns.reference")}</>,
|
||||
enableResizing: false,
|
||||
size: 10,
|
||||
},
|
||||
{
|
||||
id: "status" as const,
|
||||
accessorKey: "status",
|
||||
header: () => <>{t("quotes.list.columns.status")}</>,
|
||||
cell: ({ renderValue }: { renderValue: () => any }) => <Badge>{renderValue()}</Badge>,
|
||||
enableResizing: false,
|
||||
size: 10,
|
||||
},
|
||||
{
|
||||
id: "total_price" as const,
|
||||
accessor: "total_price",
|
||||
header: () => <div className='text-right'>{t("quotes.list.columns.total_price")}</div>,
|
||||
cell: ({ table, row: { index, original }, column, getValue }) => {
|
||||
const price = MoneyValue.create(original.total_price);
|
||||
return (
|
||||
<div className='text-right'>{price.isSuccess ? price.object.toFormat() : "-"}</div>
|
||||
);
|
||||
},
|
||||
enableResizing: false,
|
||||
size: 20,
|
||||
|
||||
@ -19,17 +19,21 @@ const customButtonVariants = cva("", {
|
||||
});
|
||||
|
||||
export interface CustomButtonProps extends ButtonProps, VariantProps<typeof customButtonVariants> {
|
||||
icon: LucideIcon; // Propiedad para proporcionar el icono personalizado
|
||||
icon?: LucideIcon; // Propiedad para proporcionar el icono personalizado
|
||||
label?: string;
|
||||
}
|
||||
|
||||
const CustomButton = React.forwardRef<HTMLButtonElement, CustomButtonProps>(
|
||||
({ className, label, size, icon: Icon, children, ...props }, ref) => (
|
||||
<Button ref={ref} size={size} className={cn("gap-1", className)} {...props}>
|
||||
<Icon className={cn(customButtonVariants({ size }))} />
|
||||
<>{label ? label : children}</>
|
||||
</Button>
|
||||
)
|
||||
({ className, label, size, icon: Icon, children, ...props }, ref) => {
|
||||
const hasIcon = !!Icon;
|
||||
|
||||
return (
|
||||
<Button ref={ref} size={size} className={cn(hasIcon ? "gap-1" : "", className)} {...props}>
|
||||
{hasIcon && <Icon className={cn(customButtonVariants({ size }))} />}
|
||||
<>{label ? label : children}</>
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
CustomButton.displayName = "CustomButton";
|
||||
|
||||
@ -1,13 +1,12 @@
|
||||
import { ButtonProps } from "@/ui";
|
||||
import { SaveIcon } from "lucide-react";
|
||||
import { CustomButton } from "./CustomButton";
|
||||
|
||||
export interface SubmitButtonProps extends ButtonProps {
|
||||
label?: string;
|
||||
}
|
||||
|
||||
export const SubmitButton = ({ label = "Guardar", ...props }: SubmitButtonProps) => (
|
||||
<CustomButton type='submit' label={label} icon={SaveIcon} variant='default' {...props} />
|
||||
export const SubmitButton = ({ label = "Enviar", ...props }: SubmitButtonProps) => (
|
||||
<CustomButton type='submit' label={label} variant='default' {...props} />
|
||||
);
|
||||
|
||||
SubmitButton.displayName = "SubmitButton";
|
||||
|
||||
11
client/src/components/Forms/FormSubmitButton.tsx
Normal file
11
client/src/components/Forms/FormSubmitButton.tsx
Normal file
@ -0,0 +1,11 @@
|
||||
import { useFormState } from "react-hook-form";
|
||||
import { SubmitButton, SubmitButtonProps } from "../Buttons";
|
||||
|
||||
export interface FromSubmitButtonProps extends SubmitButtonProps {}
|
||||
|
||||
export const FormSubmitButton = (props: FromSubmitButtonProps) => {
|
||||
const { isSubmitting, isLoading, isValidating } = useFormState();
|
||||
return <SubmitButton disabled={isSubmitting || isLoading || isValidating} {...props} />;
|
||||
};
|
||||
|
||||
FormSubmitButton.displayName = "FormSubmitButton";
|
||||
@ -10,13 +10,6 @@ type ProctectRouteProps = {
|
||||
export const ProtectedRoute = ({ children }: ProctectRouteProps) => {
|
||||
const { isPending, isSuccess, data: { authenticated, redirectTo } = {} } = useIsLoggedIn();
|
||||
|
||||
console.debug("ProtectedRouter", {
|
||||
isPending,
|
||||
isSuccess,
|
||||
authenticated,
|
||||
redirectTo,
|
||||
});
|
||||
|
||||
if (isPending) {
|
||||
return <LoadingOverlay />;
|
||||
}
|
||||
|
||||
@ -76,7 +76,14 @@
|
||||
},
|
||||
"quotes": {
|
||||
"list": {
|
||||
"title": "Cotizaciones"
|
||||
"title": "Cotizaciones",
|
||||
"columns": {
|
||||
"date": "Fecha",
|
||||
"reference": "Referencia",
|
||||
"status": "Estado",
|
||||
"customer_information": "Cliente",
|
||||
"total_price": "Imp. total"
|
||||
}
|
||||
},
|
||||
"status": {
|
||||
"draft": "Borrador"
|
||||
|
||||
@ -11,12 +11,12 @@ export const CreateQuotePresenter: ICreateQuotePresenter = {
|
||||
map: (quote: Quote, context: ISalesContext): ICreateQuote_Response_DTO => {
|
||||
return {
|
||||
id: quote.id.toString(),
|
||||
//reference: quote.refe
|
||||
reference: quote.reference.toString(),
|
||||
status: quote.status.toString(),
|
||||
date: quote.date.toString(),
|
||||
date: quote.date.toISO8601(),
|
||||
lang_code: quote.language.toString(),
|
||||
currency_code: quote.currency.toString(),
|
||||
customer_information: quote.customer,
|
||||
customer_information: quote.customer.toString(),
|
||||
subtotal: {
|
||||
amount: 0,
|
||||
precision: 2,
|
||||
|
||||
@ -16,10 +16,10 @@ export const GetQuotePresenter: IGetQuotePresenter = {
|
||||
return {
|
||||
id: quote.id.toString(),
|
||||
status: quote.status.toString(),
|
||||
date: quote.date.toString(),
|
||||
date: quote.date.toISO8601(),
|
||||
reference: quote.reference.toString(),
|
||||
customer_information: quote.customer.toString(),
|
||||
lang_code: quote.language.code,
|
||||
lang_code: quote.language.toString(),
|
||||
currency_code: quote.currency.toString(),
|
||||
|
||||
payment_method: quote.paymentMethod.toString(),
|
||||
|
||||
@ -20,10 +20,10 @@ export const ListQuotesPresenter: IListQuotesPresenter = {
|
||||
return {
|
||||
id: quote.id.toString(),
|
||||
status: quote.status.toString(),
|
||||
date: quote.date.toString(),
|
||||
date: quote.date.toISO8601(),
|
||||
reference: quote.reference.toString(),
|
||||
customer_information: quote.customer.toString(),
|
||||
lang_code: quote.date.toISO8601(),
|
||||
lang_code: quote.language.toString(),
|
||||
currency_code: quote.currency.toString(),
|
||||
|
||||
subtotal: {
|
||||
|
||||
@ -12,20 +12,22 @@ export const UpdateQuotePresenter: IUpdateQuotePresenter = {
|
||||
return {
|
||||
id: quote.id.toString(),
|
||||
status: quote.status.toString(),
|
||||
date: quote.date.toString(),
|
||||
language_code: quote.date.toString(),
|
||||
date: quote.date.toISO8601(),
|
||||
reference: quote.reference.toString(),
|
||||
customer_information: quote.customer.toString(),
|
||||
lang_code: quote.language.toString(),
|
||||
currency_code: quote.currency.toString(),
|
||||
subtotal: {
|
||||
amount: 0,
|
||||
precision: 2,
|
||||
currency: "EUR",
|
||||
},
|
||||
total: {
|
||||
amount: 0,
|
||||
precision: 2,
|
||||
currency: "EUR",
|
||||
},
|
||||
|
||||
payment_method: quote.paymentMethod.toString(),
|
||||
validity: quote.validity.toString(),
|
||||
notes: quote.notes.toString(),
|
||||
|
||||
subtotal_price: quote.subtotalPrice.toObject(),
|
||||
discount: quote.discount.toObject(),
|
||||
total_price: quote.totalPrice.toObject(),
|
||||
|
||||
items: quoteItemPresenter(quote.items, context),
|
||||
dealer_id: quote.dealerId.toString(),
|
||||
};
|
||||
},
|
||||
};
|
||||
@ -34,23 +36,12 @@ export const UpdateQuotePresenter: IUpdateQuotePresenter = {
|
||||
const quoteItemPresenter = (items: ICollection<QuoteItem>, context: ISalesContext) =>
|
||||
items.totalCount > 0
|
||||
? items.items.map((item: QuoteItem) => ({
|
||||
article_id: item.articleId,
|
||||
description: item.description.toString(),
|
||||
quantity: item.quantity.toString(),
|
||||
unit_measure: "",
|
||||
unit_price: {
|
||||
amount: 0,
|
||||
precision: 2,
|
||||
currency: "EUR",
|
||||
},
|
||||
subtotal: {
|
||||
amount: 0,
|
||||
precision: 2,
|
||||
currency: "EUR",
|
||||
},
|
||||
total: {
|
||||
amount: 0,
|
||||
precision: 2,
|
||||
currency: "EUR",
|
||||
},
|
||||
quantity: item.quantity.toObject(),
|
||||
unit_price: item.unitPrice.toObject(),
|
||||
subtotal_price: item.subtotalPrice.toObject(),
|
||||
discount: item.discount.toObject(),
|
||||
total_price: item.totalPrice.toObject(),
|
||||
}))
|
||||
: [];
|
||||
|
||||
@ -55,7 +55,25 @@ export class UTCDateValue extends ValueObject<Date> {
|
||||
return this.isValid() ? this.props.toISOString() : "";
|
||||
};
|
||||
|
||||
public toDateString = (): string => {
|
||||
// Tue Jul 09 2024
|
||||
return this.isValid() ? this.props.toDateString() : "";
|
||||
};
|
||||
|
||||
public toLocaleDateString = (
|
||||
locales?: Intl.LocalesArgument,
|
||||
options?: Intl.DateTimeFormatOptions
|
||||
): string => {
|
||||
// DD/MM/YYYY
|
||||
return this.isValid() ? this.props.toLocaleDateString(locales, options) : "";
|
||||
};
|
||||
|
||||
public toLocaleTimeString = (): string => {
|
||||
return this.isValid() ? this.props.toLocaleTimeString() : "";
|
||||
};
|
||||
|
||||
public toString(): string {
|
||||
// YYYY-MM-DD
|
||||
if (!this.isEmpty()) {
|
||||
const year = this.props.getFullYear();
|
||||
const month = String(this.props.getMonth() + 1).padStart(2, "0");
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { IQuantuty_Response_DTO } from "../../../../../common";
|
||||
import { IMoney_Response_DTO } from "../../../../../common";
|
||||
|
||||
export interface IListQuotes_Response_DTO {
|
||||
id: string;
|
||||
@ -9,6 +9,6 @@ export interface IListQuotes_Response_DTO {
|
||||
lang_code: string;
|
||||
currency_code: string;
|
||||
|
||||
subtotal: IQuantuty_Response_DTO;
|
||||
total: IQuantuty_Response_DTO;
|
||||
subtotal_price: IMoney_Response_DTO;
|
||||
total_price: IMoney_Response_DTO;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user