From 339ce85e4682b35a48652a1dd554065116dfacf2 Mon Sep 17 00:00:00 2001 From: Sergio Ramirez Date: Wed, 30 Jul 2025 13:47:13 -0400 Subject: [PATCH] recibir la imagen en la api corectamente --- .../inventory/inventory.controller.ts | 2 +- .../features/pictures/pictures.controller.ts | 10 +- .../src/features/pictures/pictures.service.ts | 24 +- apps/api/uploads/.gitkeep | 0 .../feactures/inventory/actions/actions.ts | 31 +++ .../inventory/update-product-form copy.tsx | 231 ++++++++++++++++++ .../inventory/update-product-form.tsx | 76 +++++- .../feactures/inventory/hooks/use-mutation.ts | 6 +- .../feactures/inventory/schemas/inventory.ts | 5 + .../feactures/inventory/utils/sizeFormate.ts | 13 + apps/web/lib/fetch.api.ts | 25 +- apps/web/lib/fetch.api2.ts | 99 ++++++++ apps/web/next.config.js | 8 +- 13 files changed, 493 insertions(+), 37 deletions(-) delete mode 100644 apps/api/uploads/.gitkeep create mode 100644 apps/web/feactures/inventory/components/inventory/update-product-form copy.tsx create mode 100644 apps/web/feactures/inventory/utils/sizeFormate.ts create mode 100644 apps/web/lib/fetch.api2.ts diff --git a/apps/api/src/features/inventory/inventory.controller.ts b/apps/api/src/features/inventory/inventory.controller.ts index 9761c37..119b13d 100644 --- a/apps/api/src/features/inventory/inventory.controller.ts +++ b/apps/api/src/features/inventory/inventory.controller.ts @@ -29,7 +29,7 @@ export class UsersController { @ApiOperation({ summary: 'Get all products with pagination and filters' }) @ApiResponse({ status: 200, description: 'Return paginated products.' }) async findAllByUserId(@Req() req: Request, @Query() paginationDto: PaginationDto) { - console.log(req['user'].id) + // console.log(req['user'].id) // const id = 1 const id = Number(req['user'].id); const result = await this.inventoryService.findAllByUserId(id,paginationDto); diff --git a/apps/api/src/features/pictures/pictures.controller.ts b/apps/api/src/features/pictures/pictures.controller.ts index 7e68276..1ae4024 100644 --- a/apps/api/src/features/pictures/pictures.controller.ts +++ b/apps/api/src/features/pictures/pictures.controller.ts @@ -8,8 +8,14 @@ export class PicturesController { constructor(private readonly picturesService: PicturesService) {} @Post('upload') - @UseInterceptors(FilesInterceptor('files')) + @UseInterceptors(FilesInterceptor('urlImg')) async uploadFile(@UploadedFiles() files: Express.Multer.File[]) { - return this.picturesService.saveImages(files); + console.log(files); + + + // const result = await this.picturesService.saveImages(files); + // console.log(result); + + return {data: ["result"]} } } diff --git a/apps/api/src/features/pictures/pictures.service.ts b/apps/api/src/features/pictures/pictures.service.ts index ade96fc..6e83fb9 100644 --- a/apps/api/src/features/pictures/pictures.service.ts +++ b/apps/api/src/features/pictures/pictures.service.ts @@ -12,18 +12,24 @@ export class PicturesService { */ async saveImages(file: Express.Multer.File[]): Promise { - const picturesPath = join(__dirname, '..', '..', 'pictures'); - + const picturesPath = join(__dirname, '..', '..', '..', '..', 'uploads','pict'); + let images : string[] = []; + + console.log(file); + + let count = 0; - file.forEach(async (pic) => { - const fileName = `${Date.now()}-${pic.originalname}`; - const filePath = join(picturesPath, fileName); - await writeFile(filePath, pic.buffer); - images.push(`/pictures/${fileName}`); - }); - + // file.forEach(async (file) => { + // // count++ + // // const fileName = `${Date.now()}-${count++}-${file.originalname}`; + // // console.log(fileName); + // // const filePath = join(picturesPath, fileName); + // // await writeFile(filePath, file.buffer); + // // images.push(fileName); + // }); + // return [file[0].originalname] return images; diff --git a/apps/api/uploads/.gitkeep b/apps/api/uploads/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/apps/web/feactures/inventory/actions/actions.ts b/apps/web/feactures/inventory/actions/actions.ts index 4ced31c..16402e3 100644 --- a/apps/web/feactures/inventory/actions/actions.ts +++ b/apps/web/feactures/inventory/actions/actions.ts @@ -4,6 +4,7 @@ import { ApiResponseSchema, InventoryTable, productMutate, + test, // editInventory, productApiResponseSchema, getProduct @@ -138,6 +139,36 @@ export const createProductAction = async (payload: InventoryTable) => { return payloadWithoutId; }; +export const updateUserAction2 = async (payload: InventoryTable) => { + try { + // const { id, urlImg, ...payloadWithoutId } = payload; + + // const formData = new FormData(); + // formData.append('file', urlImg); + + + // console.log(formData); + + + const [error, data] = await safeFetchApi( + test, + `/pictures/upload`, + 'POST', + payload, + ); + + if (error) { + console.error(error); + throw new Error(error?.message || 'Error al actualizar el producto'); + } + // console.log(data); + return data; + + } catch (error) { + console.error(error); + } +} + export const updateUserAction = async (payload: InventoryTable) => { try { const { id, ...payloadWithoutId } = payload; diff --git a/apps/web/feactures/inventory/components/inventory/update-product-form copy.tsx b/apps/web/feactures/inventory/components/inventory/update-product-form copy.tsx new file mode 100644 index 0000000..33c33c2 --- /dev/null +++ b/apps/web/feactures/inventory/components/inventory/update-product-form copy.tsx @@ -0,0 +1,231 @@ +'use client'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { Button } from '@repo/shadcn/button'; +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from '@repo/shadcn/form'; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@repo/shadcn/select'; +import { Input } from '@repo/shadcn/input'; +import { useForm } from 'react-hook-form'; +import { useUpdateUser } from "@/feactures/inventory/hooks/use-mutation"; +import { editInventory, EditInventory } from '@/feactures/inventory/schemas/inventory'; // Renombrado EditInventory para claridad +import { Textarea } from '@repo/shadcn/components/ui/textarea'; +import {STATUS} from '@/constants/status' +import { useState } from 'react'; +import {sizeFormate} from "@/feactures/inventory/utils/sizeFormate" + +interface UpdateFormProps { + onSuccess?: () => void; + onCancel?: () => void; + defaultValues?: Partial; +} + +export function UpdateForm({ + onSuccess, + onCancel, + defaultValues, +}: UpdateFormProps) { + const { + mutate: saveAccountingAccounts, + isPending: isSaving, + isError, // isError no se usa en el template, podrías usarlo para mostrar un mensaje global + } = useUpdateUser(); + + const [sizeFile, setSizeFile] = useState('0 bytes'); + + const defaultformValues: EditInventory = { + id: defaultValues?.id, + title: defaultValues?.title || '', + description: defaultValues?.description || '', + price: defaultValues?.price || '', + address: defaultValues?.address || '', + status: defaultValues?.status || 'BORRADOR', + stock: defaultValues?.stock ?? 0, + urlImg: [], + userId: defaultValues?.userId + }; + + const form = useForm({ + resolver: zodResolver(editInventory), + defaultValues: defaultformValues, + mode: 'onChange', // Enable real-time validation + }); + + const onSubmit = async (data: EditInventory) => { + // console.log(data); + + saveAccountingAccounts(data, { + onSuccess: () => { + form.reset(); + onSuccess?.(); + }, + onError: (error) => { // Captura el error para mostrar un mensaje más específico si es posible + console.error("Error al guardar el producto:", error); + form.setError('root', { + type: 'manual', + message: error.message || 'Error al guardar el producto', // Mejor mensaje de error + }); + }, + }); + }; + + return ( +
+ + {form.formState.errors.root && ( +
+ {form.formState.errors.root.message} +
+ )} +
+ ( + + Nombre/Título + + + + + + )} + /> + + ( + + Precio + + + + + + )} + /> + + ( + + Dirección + + + + + + )} + /> + + ( + + Descripción + +