Skip to content

Commit

Permalink
add backend endpoint and move the logic to endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
pinocchio-life-like committed Jul 26, 2024
1 parent 7f73e5b commit d4298d5
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 105 deletions.
93 changes: 5 additions & 88 deletions packages/app/components/item/ImportForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ import { View, Platform } from 'react-native';
import { DropdownComponent, RButton, RText } from '@packrat/ui';
import useTheme from '../../hooks/useTheme';
import * as DocumentPicker from 'expo-document-picker';
import Papa from 'papaparse';
import { InformUser } from 'app/utils/ToastUtils';
import { useAddPackItem } from 'app/hooks/packs/useAddPackItem';
import { useAddItem } from 'app/hooks/items';
import { useImportPackItem } from 'app/hooks/packs/useImportPackItem';
import { useImportItem } from 'app/hooks/items/useImportItem';

interface ImportFormProps {
showSubmitButton?: boolean;
Expand Down Expand Up @@ -43,6 +42,7 @@ export const ImportForm: FC<ImportFormProps> = ({
const { currentTheme } = useTheme();
const { addPackItem } = useAddPackItem();
const { handleAddNewItem } = useAddItem();
const { handleImportNewItems } = useImportItem();
const { importPackItem } = useImportPackItem();

const [selectedType, setSelectedType] = useState<SelectedType>({
Expand Down Expand Up @@ -83,98 +83,15 @@ export const ImportForm: FC<ImportFormProps> = ({
}

if (currentpage === 'items') {
// data.forEach((item, index) => {
// if (index < data.length - 1) {
// handleAddNewItem(item, () => {
// InformUser({
// title: 'Items imported successfully',
// placement: 'bottom',
// duration: 3000,
// style: { backgroundColor: 'green' },
// });
// });
// }
// });
handleImportNewItems({ content: fileContent, ownerId });
} else {
importPackItem({ content: fileContent, packId, ownerId });
}

console.log('fileContent:', typeof fileContent);

// Papa.parse(fileContent, {
// header: true,
// complete: (result) => {
// const expectedHeaders = [
// 'Name',
// 'Weight',
// 'Unit',
// 'Quantity',
// 'Category',
// ];
// // Get headers from the parsed result
// const parsedHeaders = result.meta.fields;
// try {
// // Check if all expected headers are present
// const allHeadersPresent = expectedHeaders.every((header) =>
// parsedHeaders.includes(header),
// );
// if (!allHeadersPresent) {
// throw new Error(
// 'CSV does not contain all the expected Item headers',
// );
// }
// const data = result.data.map((item, index) => {
// return {
// id: `${Date.now().toString()}${index}`,
// name: item.Name,
// weight: Number(item.Weight),
// unit: item.Unit,
// quantity: Number(item.Quantity),
// type: item.Category,
// packId: packId,
// ownerId: ownerId,
// };
// });

// if (currentpage === 'items') {
// data.forEach((item, index) => {
// if (index < data.length - 1) {
// handleAddNewItem(item, () => {
// InformUser({
// title: 'Items imported successfully',
// placement: 'bottom',
// duration: 3000,
// style: { backgroundColor: 'green' },
// });
// });
// }
// });
// } else {
// data.forEach((item, index) => {
// if (index < data.length - 1) {
// addPackItem(item);
// }
// });
// }
// } catch (error) {
// InformUser({
// title:
// 'CSV does not contain the expected Item headers or data must be corrupt',
// placement: 'bottom',
// duration: 3000,
// style: { backgroundColor: 'red' },
// });
// } finally {
// closeModalHandler();
// }
// },
// error: (error) => {
// console.error('Error parsing CSV:', error);
// },
// });
}
} catch (err) {
console.error('Error importing file:', err);
} finally {
closeModalHandler();
}
};

Expand Down
41 changes: 41 additions & 0 deletions packages/app/hooks/items/useImportItem.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { queryTrpc } from 'app/trpc';
import { useCallback } from 'react';
import { useOfflineQueue } from 'app/hooks/offline';
import { useItemsUpdater } from './useItemsUpdater';

interface State {
items?: Array<{ id: string }>;
}

export const useImportItem = () => {
const utils = queryTrpc.useContext();
const { mutate } = queryTrpc.importItemsGlobal.useMutation();
const { isConnected, addOfflineRequest } = useOfflineQueue();
const updateItems = useItemsUpdater();

const handleImportNewItems = useCallback(
(newItem) => {
if (isConnected) {
return mutate(newItem, {
onSuccess: () => {
utils.getItemsGlobally.invalidate();
},
});
}

addOfflineRequest('addItemGlobal', newItem);

updateItems((prevState: State = {}) => {
const prevItems = Array.isArray(prevState.items) ? prevState.items : [];

return {
...prevState,
items: [newItem, ...prevItems],
};
});
},
[updateItems],
);

return { handleImportNewItems };
};
6 changes: 1 addition & 5 deletions packages/app/hooks/packs/useImportPackItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,7 @@ export const useImportPackItem = () => {
global: false,
packs: [newItem.id],
id: Date.now().toString(),
category: newItem.type
? {
name: newItem.type,
}
: null,
category: newItem.type ? { name: newItem.type } : null,
},
],
};
Expand Down
5 changes: 5 additions & 0 deletions packages/validations/src/validations/itemRoutesValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ export const addItemGlobal = z.object({
ownerId: z.string(),
});

export const importItemsGlobal = z.object({
content: z.string(),
ownerId: z.string(),
});

export const getItemsGlobally = z.object({
limit: z.number(),
page: z.number(),
Expand Down
69 changes: 57 additions & 12 deletions server/src/controllers/item/importItems.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { protectedProcedure } from '../../trpc';
import { addItemService } from '../../services/item/item.service';
import * as validator from '@packrat/validations';
import Papa from 'papaparse';

export const importItems = async (c) => {
try {
Expand All @@ -26,17 +27,61 @@ export function importItemsRoute() {
return protectedProcedure
.input(validator.importItem)
.mutation(async (opts) => {
console.log('opsssssssssssssssssssssssts', opts.input);
// const result = await addItemService(
// name,
// weight,
// quantity,
// unit,
// packId,
// type,
// ownerId,
// opts.ctx.executionCtx,
// );
return 'result';
const { content, packId, ownerId } = opts.input;
return new Promise((resolve, reject) => {
Papa.parse(content, {
header: true,
complete: async function (results) {
const expectedHeaders = [
'Name',
'Weight',
'Unit',
'Quantity',
'Category',
];
const parsedHeaders = results.meta.fields;
try {
const allHeadersPresent = expectedHeaders.every((header) =>
parsedHeaders.includes(header),
);
if (!allHeadersPresent) {
return reject(
new Error(
'CSV does not contain all the expected Item headers',
),
);
}

for (const [index, item] of results.data.entries()) {
if (
index === results.data.length - 1 &&
Object.values(item).every((value) => value === '')
) {
continue;
}

await addItemService(
item.Name,
item.Weight,
item.Quantity,
item.Unit,
packId,
item.Category,
ownerId,
opts.ctx.executionCtx,
);
}
resolve('result');
} catch (err) {
console.error('Error parsing CSV file:', err);
reject(err);
}
},
error: function (error) {
console.error('Error parsing CSV file:', error);
reject(error);
},
});
});
});
}
80 changes: 80 additions & 0 deletions server/src/controllers/item/importItemsGlobal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { type Context } from 'hono';
import { addItemGlobalService } from '../../services/item/item.service';
import { protectedProcedure } from '../../trpc';
import * as validator from '@packrat/validations';
import Papa from 'papaparse';

export const importItemsGlobal = async (c: Context) => {
try {
const { name, weight, quantity, unit, type, ownerId } = await c.req.json();

const item = await addItemGlobalService(
name,
weight,
quantity,
unit,
type,
ownerId,
);
return c.json({ item }, 200);
} catch (error) {
return c.json({ error: `Failed to add item: ${error.message}` }, 500);
}
};

export function importItemsGlobalRoute() {
return protectedProcedure
.input(validator.importItemsGlobal)
.mutation(async (opts) => {
const { content, ownerId } = opts.input;
return new Promise((resolve, reject) => {
Papa.parse(content, {
header: true,
complete: async function (results) {
const expectedHeaders = [
'Name',
'Weight',
'Unit',
'Quantity',
'Category',
];
const parsedHeaders = results.meta.fields;
try {
const allHeadersPresent = expectedHeaders.every((header) =>
parsedHeaders.includes(header),
);
if (!allHeadersPresent) {
return reject(
new Error(
'CSV does not contain all the expected Item headers',
),
);
}

for (const [index, item] of results.data.entries()) {
if (
index === results.data.length - 1 &&
Object.values(item).every((value) => value === '')
) {
continue;
}

await addItemGlobalService(
item.Name,
item.Weight,
item.Quantity,
item.Unit,
item.Category,
ownerId,
opts.ctx.executionCtx,
);
}
return resolve('items');
} catch (error) {
return reject(new Error(`Failed to add items: ${error.message}`));
}
},
});
});
});
}
1 change: 1 addition & 0 deletions server/src/controllers/item/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './addGlobalItemToPack';
export * from './importItemsGlobal';
export * from './addItem';
export * from './importItems';
export * from './addItemGlobal';
Expand Down
2 changes: 2 additions & 0 deletions server/src/routes/trpcRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import {
import {
addGlobalItemToPackRoute,
addItemGlobalRoute,
importItemsGlobalRoute,
addItemRoute,
importItemsRoute,
deleteGlobalItemRoute,
Expand Down Expand Up @@ -154,6 +155,7 @@ export const appRouter = trpcRouter({
editItem: editItemRoute(), // Done
deleteItem: deleteItemRoute(), // Done
addItemGlobal: addItemGlobalRoute(), // Done
importItemsGlobal: importItemsGlobalRoute(), // Done
getItemsGlobally: getItemsGloballyRoute(), // Done
addGlobalItemToPack: addGlobalItemToPackRoute(), // Done
editGlobalItemAsDuplicate: editGlobalItemAsDuplicateRoute(), // Not Implemented
Expand Down

0 comments on commit d4298d5

Please sign in to comment.