"chore: update frontend dev script to include lint checks and add ESLint config file"
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
// src/actions/invoice.ts
|
||||
import { useMemo } from 'react';
|
||||
import axiosInstance, { endpoints, fetcher } from 'src/lib/axios';
|
||||
import type { IInvoiceItem } from 'src/types/invoice';
|
||||
import type { IInvoiceItem, SaveInvoiceData } from 'src/types/invoice';
|
||||
import type { SWRConfiguration } from 'swr';
|
||||
import useSWR from 'swr';
|
||||
|
||||
@@ -97,7 +97,7 @@ export function useSearchInvoices(query: string) {
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
type SaveInvoiceData = IInvoiceItem;
|
||||
// type SaveInvoiceData = IInvoiceItem;
|
||||
|
||||
export async function saveInvoice(invoiceId: string, saveInvoiceData: SaveInvoiceData) {
|
||||
const url = endpoints.invoice.saveInvoice(invoiceId);
|
||||
|
@@ -99,6 +99,7 @@ export function useSearchProducts(query: string) {
|
||||
|
||||
type SaveProductData = {
|
||||
// id: string;
|
||||
|
||||
sku: string;
|
||||
name: string;
|
||||
code: string;
|
||||
|
@@ -17,6 +17,8 @@ export type SignUpParams = {
|
||||
lastName: string;
|
||||
};
|
||||
|
||||
const ERR_ACCESS_TOKEN_NOT_FOUND = `Access token not found in response`;
|
||||
|
||||
/** **************************************
|
||||
* Sign in
|
||||
*************************************** */
|
||||
@@ -29,7 +31,7 @@ export const signInWithPassword = async ({ email, password }: SignInParams): Pro
|
||||
const { accessToken } = res.data;
|
||||
|
||||
if (!accessToken) {
|
||||
throw new Error('Access token not found in response');
|
||||
throw new Error(ERR_ACCESS_TOKEN_NOT_FOUND);
|
||||
}
|
||||
|
||||
setSession(accessToken);
|
||||
|
@@ -69,6 +69,8 @@ export function tokenExpired(exp: number) {
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const INVALID_ACCESS_TOKEN = 'Invalid access token!';
|
||||
|
||||
export async function setSession(accessToken: string | null) {
|
||||
try {
|
||||
if (accessToken) {
|
||||
@@ -81,7 +83,7 @@ export async function setSession(accessToken: string | null) {
|
||||
if (decodedToken && 'exp' in decodedToken) {
|
||||
tokenExpired(decodedToken.exp);
|
||||
} else {
|
||||
throw new Error('Invalid access token!');
|
||||
throw new Error(INVALID_ACCESS_TOKEN);
|
||||
}
|
||||
} else {
|
||||
sessionStorage.removeItem(JWT_STORAGE_KEY);
|
||||
|
@@ -11,7 +11,7 @@ const metadata = { title: `User edit | Dashboard - ${CONFIG.appName}` };
|
||||
export default function Page() {
|
||||
const { id = '' } = useParams();
|
||||
|
||||
// TODO: remove me
|
||||
// TODO: remove unused code
|
||||
// const currentUser = _userList.find((user) => user.id === id);
|
||||
const { user } = useGetUser(id);
|
||||
|
||||
|
@@ -106,7 +106,8 @@ export function CalendarToolbar({
|
||||
<Iconify icon="eva:arrow-ios-back-fill" />
|
||||
</IconButton>
|
||||
|
||||
<Typography variant="h6">{date}</Typography>
|
||||
{/* FIXME: no raw json output in html */}
|
||||
<Typography variant="h6">{JSON.stringify({ date })}</Typography>
|
||||
|
||||
<IconButton onClick={onNextDate}>
|
||||
<Iconify icon="eva:arrow-ios-forward-fill" />
|
||||
|
@@ -37,19 +37,22 @@ export function InvoiceDetails({ invoice }: Props) {
|
||||
const { t } = useTranslation();
|
||||
const [currentStatus, setCurrentStatus] = useState(invoice?.status);
|
||||
|
||||
const handleChangeStatus = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
// setCurrentStatus(event.target.value);
|
||||
const handleChangeStatus = useCallback(
|
||||
(event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
||||
// setCurrentStatus(event.target.value);
|
||||
|
||||
try {
|
||||
changeStatus(invoice.id, event.target.value);
|
||||
setCurrentStatus(event.target.value);
|
||||
try {
|
||||
changeStatus(invoice.id, event.target.value);
|
||||
setCurrentStatus(event.target.value);
|
||||
|
||||
toast.success('status changed!');
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
toast.warning('error during changing status');
|
||||
}
|
||||
}, []);
|
||||
toast.success('status changed!');
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
toast.warning('error during changing status');
|
||||
}
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
const renderFooter = () => (
|
||||
<Box
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import type { IInvoiceItem } from 'src/types/invoice';
|
||||
import type { IInvoiceItem, IInvoiceItemItem } from 'src/types/invoice';
|
||||
|
||||
import { sumBy } from 'es-toolkit';
|
||||
import { useEffect, useCallback } from 'react';
|
||||
@@ -22,7 +22,7 @@ import { InvoiceTotalSummary } from './invoice-total-summary';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export const defaultItem: Omit<IInvoiceItem, 'id'> = {
|
||||
export const defaultItem: Omit<IInvoiceItemItem, 'id'> = {
|
||||
title: '',
|
||||
description: '',
|
||||
service: INVOICE_SERVICE_OPTIONS[0].name,
|
||||
@@ -50,7 +50,7 @@ export function InvoiceNewEditDetails() {
|
||||
const discount = getValues('discount');
|
||||
const shipping = getValues('shipping');
|
||||
|
||||
const subtotal = sumBy(items, (item: IInvoiceItem) => item.quantity * item.price);
|
||||
const subtotal = sumBy(items, (item: IInvoiceItemItem) => item.quantity * item.price);
|
||||
const subtotalWithTax = subtotal + subtotal * (taxes / 100);
|
||||
const totalAmount = subtotalWithTax - discount - shipping;
|
||||
|
||||
|
@@ -81,6 +81,8 @@ export function InvoiceNewEditForm({ currentInvoice }: Props) {
|
||||
const loadingSend = useBoolean();
|
||||
|
||||
const defaultValues: NewInvoiceSchemaType = {
|
||||
id: '',
|
||||
sent: 0,
|
||||
invoiceNumber: 'INV-1990',
|
||||
createDate: today(),
|
||||
dueDate: null,
|
||||
@@ -129,6 +131,8 @@ export function InvoiceNewEditForm({ currentInvoice }: Props) {
|
||||
|
||||
try {
|
||||
if (currentInvoice) {
|
||||
data.dueDate = '2029-01-01';
|
||||
|
||||
await saveInvoice(currentInvoice.id, data);
|
||||
}
|
||||
|
||||
|
@@ -27,7 +27,7 @@ type Props = {
|
||||
invoice?: IInvoiceItem;
|
||||
currentStatus: string;
|
||||
statusOptions: { value: string; label: string }[];
|
||||
onChangeStatus: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
||||
onChangeStatus: (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
|
||||
};
|
||||
|
||||
export function InvoiceToolbar({ invoice, currentStatus, statusOptions, onChangeStatus }: Props) {
|
||||
|
@@ -19,7 +19,7 @@ export type IAddressItem = {
|
||||
addressType?: string;
|
||||
};
|
||||
|
||||
export type IDateValue = string | number | null;
|
||||
export type IDateValue = string | number | Date | null;
|
||||
|
||||
export type IDatePickerControl = Dayjs | null;
|
||||
|
||||
|
@@ -13,15 +13,16 @@ export type IInvoiceTableFilters = {
|
||||
export type IInvoiceItemItem = {
|
||||
id: string;
|
||||
title: string;
|
||||
service: string;
|
||||
price: number;
|
||||
total: number;
|
||||
service: string;
|
||||
quantity: number;
|
||||
description: string;
|
||||
};
|
||||
|
||||
export type IInvoiceItem = {
|
||||
id: string;
|
||||
|
||||
sent: number;
|
||||
taxes: number;
|
||||
status: string;
|
||||
@@ -36,3 +37,26 @@ export type IInvoiceItem = {
|
||||
invoiceTo: IAddressItem;
|
||||
invoiceFrom: IAddressItem;
|
||||
};
|
||||
|
||||
export type SaveInvoiceData = {
|
||||
sent: number;
|
||||
taxes: number;
|
||||
status: string;
|
||||
subtotal: number;
|
||||
discount: number;
|
||||
shipping: number;
|
||||
totalAmount: number;
|
||||
dueDate: IDateValue;
|
||||
invoiceNumber: string;
|
||||
items: {
|
||||
title: string;
|
||||
service: string;
|
||||
price: number;
|
||||
total: number;
|
||||
quantity: number;
|
||||
description: string;
|
||||
}[];
|
||||
createDate: IDateValue;
|
||||
invoiceTo: IAddressItem | null;
|
||||
invoiceFrom: IAddressItem | null;
|
||||
};
|
||||
|
Reference in New Issue
Block a user