diff --git a/apps/api/src/features/inventory/dto/create-product.dto.ts b/apps/api/src/features/inventory/dto/create-product.dto.ts index 7a4728b..6cc64eb 100644 --- a/apps/api/src/features/inventory/dto/create-product.dto.ts +++ b/apps/api/src/features/inventory/dto/create-product.dto.ts @@ -18,12 +18,19 @@ export class CreateProductDto { price: string; @ApiProperty() - @IsString({ + @IsInt({ message: 'stock must be a number', }) @IsOptional() stock: number; + @ApiProperty() + @IsInt({ + message: 'stock must be a number', + }) + @IsOptional() + userId: number; + @ApiProperty() @IsString({ message: 'urlImg must be a string', diff --git a/apps/api/src/features/inventory/entities/inventory.entity.ts b/apps/api/src/features/inventory/entities/inventory.entity.ts index 3556333..3f511e8 100644 --- a/apps/api/src/features/inventory/entities/inventory.entity.ts +++ b/apps/api/src/features/inventory/entities/inventory.entity.ts @@ -5,4 +5,15 @@ export class Product { price: string; stock: number; urlImg: string; + UserId?: number; +} + +export class CreateProduct { + id: number; + title: string; + description: string; + price: string; + stock: string; + urlImg: string; + UserId: number; } \ No newline at end of file diff --git a/apps/api/src/features/inventory/inventory.controller.ts b/apps/api/src/features/inventory/inventory.controller.ts index 4d618b6..6078262 100644 --- a/apps/api/src/features/inventory/inventory.controller.ts +++ b/apps/api/src/features/inventory/inventory.controller.ts @@ -3,7 +3,7 @@ import { InventoryService } from './inventory.service'; import { CreateProductDto } from './dto/create-product.dto'; import { UpdateProductDto } from './dto/update-product.dto'; import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; -import { Roles } from '../../common/decorators/roles.decorator'; +// import { Roles } from '../../common/decorators/roles.decorator'; import { PaginationDto } from '../../common/dto/pagination.dto'; @ApiTags('inventory') @@ -42,22 +42,19 @@ export class UsersController { @Body() createUserDto: CreateProductDto, @Query('roleId') roleId?: string, ) { - const data = await this.inventoryService.create( - createUserDto, - roleId ? parseInt(roleId) : undefined, - ); + const data = await this.inventoryService.create(createUserDto) return { message: 'User created successfully', data }; } - // @Patch(':id') + @Patch(':id') // @Roles('admin') - // @ApiOperation({ summary: 'Update a user' }) - // @ApiResponse({ status: 200, description: 'User updated successfully.' }) - // @ApiResponse({ status: 404, description: 'User not found.' }) - // async update(@Param('id') id: string, @Body() UpdateProductDto: UpdateProductDto) { - // const data = await this.inventoryService.update(id, UpdateProductDto); - // return { message: 'User updated successfully', data }; - // } + @ApiOperation({ summary: 'Update a product' }) + @ApiResponse({ status: 200, description: 'Product updated successfully.' }) + @ApiResponse({ status: 404, description: 'Product not found.' }) + async update(@Param('id') id: string, @Body() UpdateProductDto: UpdateProductDto) { + const data = await this.inventoryService.update(id, UpdateProductDto); + return { message: 'User updated successfully', data }; + } // @Delete(':id') // @Roles('admin') diff --git a/apps/api/src/features/inventory/inventory.service.ts b/apps/api/src/features/inventory/inventory.service.ts index 115fcdc..732d41b 100644 --- a/apps/api/src/features/inventory/inventory.service.ts +++ b/apps/api/src/features/inventory/inventory.service.ts @@ -6,7 +6,7 @@ import { products } from 'src/database/index'; import { eq, like, or, SQL, sql, and, not } from 'drizzle-orm'; import { CreateProductDto } from './dto/create-product.dto'; import { UpdateProductDto } from './dto/update-product.dto'; -import { Product } from './entities/inventory.entity'; +import { Product, CreateProduct } from './entities/inventory.entity'; import { PaginationDto } from '../../common/dto/pagination.dto'; @Injectable() @@ -54,13 +54,8 @@ export class InventoryService { price: products.price, urlImg: products.urlImg, stock: products.stock, - // price: products.price, - // quantity: products.quantity, - // isActive: products.isActive }) .from(products) - // .leftJoin(usersRole, eq(usersRole.userId, users.id)) - // .leftJoin(roles, eq(roles.id, usersRole.roleId)) .where(searchCondition) .orderBy(orderBy) .limit(limit) @@ -77,9 +72,6 @@ export class InventoryService { nextPage: page < totalPages ? page + 1 : null, previousPage: page > 1 ? page - 1 : null, }; - - console.log(data); - return { data, meta }; } @@ -94,16 +86,10 @@ export class InventoryService { stock: products.stock }) .from(products) - // .leftJoin(usersRole, eq(usersRole.userId, users.id)) - // .leftJoin(roles, eq(roles.id, usersRole.roleId)) - // .leftJoin(schema.states, eq(schema.states.id, users.state)) - // .leftJoin(schema.municipalities, eq(schema.municipalities.id, users.municipality)) - // .leftJoin(schema.parishes, eq(schema.parishes.id, users.parish)) - .where(eq(products.id, parseInt(id))); if (find.length === 0) { - throw new HttpException('User does not exist', HttpStatus.BAD_REQUEST); + throw new HttpException('Product does not exist', HttpStatus.BAD_REQUEST); } return find[0]; @@ -111,14 +97,13 @@ export class InventoryService { // Rest of the service remains the same async create( - createProductDto: CreateProductDto, - roleId: number = 2, - ): Promise { + createProductDto: CreateProductDto + ): Promise { // Start a transaction return await this.drizzle.transaction(async (tx) => { - // Create the user + const [newProduct] = await tx .insert(products) .values({ @@ -126,72 +111,33 @@ export class InventoryService { description: createProductDto.description, price: createProductDto.price, urlImg: createProductDto.urlImg, - stock: createProductDto.stock + stock: createProductDto.stock, + userId: createProductDto.userId }) .returning(); - - // Assign role to user - // await tx.insert(usersRole).values({ - // userId: newProduct.id, - // roleId: roleId, - // }); - - // Return the created user with role - // const [userWithRole] = await tx - // .select({ - // id: users.id, - // username: users.username, - // email: users.email, - // fullname: users.fullname, - // phone: users.phone, - // isActive: users.isActive, - // role: roles.name, - // }) - // .from(users) - // .leftJoin(usersRole, eq(usersRole.userId, users.id)) - // .leftJoin(roles, eq(roles.id, usersRole.roleId)) - // .where(eq(users.id, newProduct.id)); - - - - return this.findOne(String(newProduct.id)); + return newProduct }); } - // async update(id: string, updateUserDto: UpdateUserDto): Promise { - // const userId = parseInt(id); + async update(id: string, updateProductDto: UpdateProductDto): Promise { + const productId = parseInt(id); - // // Check if user exists - // await this.findOne(id); + // Check if exists + await this.findOne(id); - // // Prepare update data - // const updateData: any = {}; - // if (updateUserDto.username) updateData.username = updateUserDto.username; - // if (updateUserDto.email) updateData.email = updateUserDto.email; - // if (updateUserDto.fullname) updateData.fullname = updateUserDto.fullname; - // if (updateUserDto.password) { - // updateData.password = await bcrypt.hash(updateUserDto.password, 10); - // } - // if (updateUserDto.phone) updateData.phone = updateUserDto.phone; - // if (updateUserDto.isActive) updateData.isActive = updateUserDto.isActive; + // Prepare update data + const updateData: any = {}; + if (updateProductDto.title) updateData.title = updateProductDto.title; + if (updateProductDto.description) updateData.description = updateProductDto.description; + if (updateProductDto.price) updateData.price = updateProductDto.price; + if (updateProductDto.stock) updateData.stock = updateProductDto.stock; + if (updateProductDto.urlImg) updateData.urlImg = updateProductDto.urlImg; - // const updateDataRole: any = {}; - // if (updateUserDto.role) updateDataRole.roleId = updateUserDto.role; - // // Update user - // await this.drizzle - // .update(users) - // .set(updateData) - // .where(eq(users.id, userId)); - - // await this.drizzle - // .update(usersRole) - // .set(updateDataRole) - // .where(eq(usersRole.userId, userId)); - - - // // Return updated user - // return this.findOne(id); - // } + const [updatedProduct] = await this.drizzle.update(products).set(updateData).where(eq(products.id, productId)).returning(); + return updatedProduct + // Return updated user + // return this.findOne(id); + } // async remove(id: string): Promise<{ message: string, data: User }> { diff --git a/apps/web/feactures/inventory/actions/actions.ts b/apps/web/feactures/inventory/actions/actions.ts index ec0e850..e5220dc 100644 --- a/apps/web/feactures/inventory/actions/actions.ts +++ b/apps/web/feactures/inventory/actions/actions.ts @@ -1,49 +1,14 @@ 'use server'; import { safeFetchApi } from '@/lib/fetch.api'; import { - surveysApiResponseSchema, - CreateUser, + ApiResponseSchema, + InventoryTable, productMutate, - UpdateUser + editInventory } from '../schemas/inventory'; import { auth } from '@/lib/auth'; - -export const getProfileAction = async () => { - const session = await auth() - const id = session?.user?.id - - const [error, response] = await safeFetchApi( - productMutate, - `/users/${id}`, - 'GET' - ); - if (error) throw new Error(error.message); - return response; -}; - -export const updateProfileAction = async (payload: UpdateUser) => { - const { id, ...payloadWithoutId } = payload; - - const [error, data] = await safeFetchApi( - productMutate, - `/users/profile/${id}`, - 'PATCH', - payloadWithoutId, - ); - - console.log(payload); - if (error) { - if (error.message === 'Email already exists') { - throw new Error('Ese correo ya está en uso'); - } - // console.error('Error:', error); - throw new Error('Error al crear el usuario'); - } - return data; -}; - export const getInventoryAction = async (params: { page?: number; limit?: number; @@ -61,7 +26,7 @@ export const getInventoryAction = async (params: { }); const [error, response] = await safeFetchApi( - surveysApiResponseSchema, + ApiResponseSchema, `/inventory?${searchParams}`, 'GET', ); @@ -71,8 +36,6 @@ export const getInventoryAction = async (params: { throw new Error(error.message); } - - // const transformedData = response?.data ? transformSurvey(response?.data) : undefined; return { @@ -90,37 +53,35 @@ export const getInventoryAction = async (params: { }; } -export const createUserAction = async (payload: CreateUser) => { - const { id, confirmPassword, ...payloadWithoutId } = payload; +export const createProductAction = async (payload: InventoryTable) => { + const session = await auth() + const userId = session?.user?.id + const { id, ...payloadWithoutId } = payload; + + payloadWithoutId.userId = userId const [error, data] = await safeFetchApi( productMutate, - '/users', + '/inventory', 'POST', payloadWithoutId, ); if (error) { - if (error.message === 'Username already exists') { - throw new Error('Ese usuario ya existe'); - } - if (error.message === 'Email already exists') { - throw new Error('Ese correo ya está en uso'); - } - // console.error('Error:', error); + console.error(error); throw new Error('Error al crear el usuario'); } return payloadWithoutId; }; -export const updateUserAction = async (payload: UpdateUser) => { +export const updateUserAction = async (payload: InventoryTable) => { try { const { id, ...payloadWithoutId } = payload; const [error, data] = await safeFetchApi( productMutate, - `/users/${id}`, + `/inventory/${id}`, 'PATCH', payloadWithoutId, ); diff --git a/apps/web/feactures/inventory/components/inventory/create-user-form.tsx b/apps/web/feactures/inventory/components/inventory/create-product-form.tsx similarity index 51% rename from apps/web/feactures/inventory/components/inventory/create-user-form.tsx rename to apps/web/feactures/inventory/components/inventory/create-product-form.tsx index 86cbc86..297721e 100644 --- a/apps/web/feactures/inventory/components/inventory/create-user-form.tsx +++ b/apps/web/feactures/inventory/components/inventory/create-product-form.tsx @@ -1,5 +1,4 @@ 'use client'; - import { zodResolver } from '@hookform/resolvers/zod'; import { Button } from '@repo/shadcn/button'; import { @@ -11,38 +10,30 @@ import { FormMessage, } from '@repo/shadcn/form'; import { Input } from '@repo/shadcn/input'; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from '@repo/shadcn/select'; +// import { +// Select, +// SelectContent, +// SelectItem, +// SelectTrigger, +// SelectValue, +// } from '@repo/shadcn/select'; import { useForm } from 'react-hook-form'; -import { useCreateUser } from "../../hooks/use-mutation-users"; -import { CreateUser, createUser } from '../../schemas/inventory'; +import { useCreateUser } from "@/feactures/inventory/hooks/use-mutation"; +import { EditInventory, editInventory } from '@/feactures/inventory/schemas/inventory'; +import { parse } from 'path'; -const ROLES = { - // 1: 'Superadmin', - 2: 'Administrador', - 3: 'autoridad', - 4: 'Gerente', - 5: 'Usuario', - 6: 'Productor', - 7: 'Organización' -} -interface CreateUserFormProps { +interface CreateFormProps { onSuccess?: () => void; onCancel?: () => void; - defaultValues?: Partial; + defaultValues?: Partial; } -export function CreateUserForm({ +export function CreateForm({ onSuccess, onCancel, defaultValues, -}: CreateUserFormProps) { +}: CreateFormProps) { const { mutate: saveAccountingAccounts, isPending: isSaving, @@ -52,23 +43,20 @@ export function CreateUserForm({ // const { data: AccoutingAccounts } = useSurveyMutation(); const defaultformValues = { - username: defaultValues?.username || '', - fullname: defaultValues?.fullname || '', - email: defaultValues?.email || '', - password: '', - confirmPassword: '', - id: defaultValues?.id, - phone: defaultValues?.phone || '', - role: defaultValues?.role, + title: defaultValues?.title || '', + description: defaultValues?.description || '', + price: defaultValues?.price || '', + stock: defaultValues?.stock || 0, + urlImg: defaultValues?.urlImg || '' } - const form = useForm({ - resolver: zodResolver(createUser), + const form = useForm({ + resolver: zodResolver(editInventory), defaultValues: defaultformValues, mode: 'onChange', // Enable real-time validation }); - const onSubmit = async (data: CreateUser) => { + const onSubmit = async (data: EditInventory) => { const formData = data @@ -97,10 +85,10 @@ export function CreateUserForm({
( - Usuario + Nombre/Título @@ -111,10 +99,10 @@ export function CreateUserForm({ ( - Nombre completo + Descripción @@ -125,12 +113,14 @@ export function CreateUserForm({ ( - Correo + Precio - + @@ -139,12 +129,12 @@ export function CreateUserForm({ ( - Teléfono + Cantidad/Stock - + @@ -153,59 +143,17 @@ export function CreateUserForm({ ( - Contraseña + Imagen - + )} /> - - ( - - Confirmar Contraseña - - - - - - )} - /> - - ( - - Rol - - - - )} - />
diff --git a/apps/web/feactures/inventory/components/inventory/user-modal.tsx b/apps/web/feactures/inventory/components/inventory/inventory-modal.tsx similarity index 71% rename from apps/web/feactures/inventory/components/inventory/user-modal.tsx rename to apps/web/feactures/inventory/components/inventory/inventory-modal.tsx index b4230f8..28a4348 100644 --- a/apps/web/feactures/inventory/components/inventory/user-modal.tsx +++ b/apps/web/feactures/inventory/components/inventory/inventory-modal.tsx @@ -7,21 +7,22 @@ import { DialogHeader, DialogTitle, } from '@repo/shadcn/dialog'; -import { AccountPlan } from '@/feactures/users/schemas/account-plan.schema'; -import { CreateUserForm } from './create-user-form'; -import { UpdateUserForm } from './update-user-form'; +// import { AccountPlan } from '@/feactures/users/schemas/account-plan.schema'; +import { EditInventory, editInventory } from '../../schemas/inventory'; +import { CreateForm } from './create-product-form'; +import { UpdateForm } from './update-product-form'; -interface AccountPlanModalProps { +interface ModalProps { open: boolean; onOpenChange: (open: boolean) => void; - defaultValues?: Partial; + defaultValues?: Partial; } export function AccountPlanModal({ open, onOpenChange, defaultValues, -}: AccountPlanModalProps) { +}: ModalProps) { const handleSuccess = () => { onOpenChange(false); }; @@ -43,21 +44,21 @@ export function AccountPlanModal({ {defaultValues?.id - ? 'Actualizar usuario' - : 'Crear usuario'} + ? 'Actualizar producto' + : 'Registrar producto'} - Complete los campos para {defaultValues?.id ? 'actualizar' : 'crear'} un usuario + Complete los campos para {defaultValues?.id ? 'actualizar' : 'registrar'} un producto {defaultValues?.id ? ( - ): ( - ; diff --git a/apps/web/feactures/inventory/components/inventory/product-tables/cell-action.tsx b/apps/web/feactures/inventory/components/inventory/product-tables/cell-action.tsx index 53fac03..0e682ec 100644 --- a/apps/web/feactures/inventory/components/inventory/product-tables/cell-action.tsx +++ b/apps/web/feactures/inventory/components/inventory/product-tables/cell-action.tsx @@ -12,7 +12,7 @@ import { import { Edit, Trash, User } from 'lucide-react'; import { InventoryTable } from '@/feactures/inventory/schemas/inventory'; import { useDeleteUser } from '@/feactures/users/hooks/use-mutation-users'; -import { AccountPlanModal } from '../user-modal'; +import { AccountPlanModal } from '../inventory-modal'; interface CellActionProps { data: InventoryTable; diff --git a/apps/web/feactures/inventory/components/inventory/update-product-form.tsx b/apps/web/feactures/inventory/components/inventory/update-product-form.tsx new file mode 100644 index 0000000..c4ee45d --- /dev/null +++ b/apps/web/feactures/inventory/components/inventory/update-product-form.tsx @@ -0,0 +1,168 @@ +'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 { Input } from '@repo/shadcn/input'; +// import { +// Select, +// SelectContent, +// SelectItem, +// SelectTrigger, +// SelectValue, +// } from '@repo/shadcn/select'; +import { useForm } from 'react-hook-form'; +import { useUpdateUser } from "@/feactures/inventory/hooks/use-mutation"; +import { EditInventory, editInventory } from '@/feactures/inventory/schemas/inventory'; + + +interface UpdateFormProps { + onSuccess?: () => void; + onCancel?: () => void; + defaultValues?: Partial; +} + +export function UpdateForm({ + onSuccess, + onCancel, + defaultValues, +}: UpdateFormProps) { + const { + mutate: saveAccountingAccounts, + isPending: isSaving, + isError, + } = useUpdateUser(); + + const defaultformValues = { + id: defaultValues?.id, + title: defaultValues?.title || '', + description: defaultValues?.description || '', + price: defaultValues?.price || '', + stock: defaultValues?.stock || 0, + urlImg: defaultValues?.urlImg || '', + } + + // console.log(defaultValues); + + const form = useForm({ + resolver: zodResolver(editInventory), + defaultValues: defaultformValues, + mode: 'onChange', // Enable real-time validation + }); + + const onSubmit = async (data: EditInventory) => { + + const formData = data + + saveAccountingAccounts(formData, { + onSuccess: () => { + form.reset(); + onSuccess?.(); + }, + onError: () => { + form.setError('root', { + type: 'manual', + message: 'Error al guardar la cuenta contable', + }); + }, + }); + }; + + return ( +
+ + {form.formState.errors.root && ( +
+ {form.formState.errors.root.message} +
+ )} +
+ ( + + Nombre/Título + + + + + + )} + /> + + ( + + Descripción + + + + + + )} + /> + + ( + + Precio + + + + + + )} + /> + + ( + + Cantidad/Stock + + + + + + )} + /> + + ( + + Imagen + + + + + + )} + /> +
+ +
+ + +
+
+ + ); +} diff --git a/apps/web/feactures/inventory/components/inventory/update-user-form.tsx b/apps/web/feactures/inventory/components/inventory/update-user-form.tsx deleted file mode 100644 index b96d14f..0000000 --- a/apps/web/feactures/inventory/components/inventory/update-user-form.tsx +++ /dev/null @@ -1,227 +0,0 @@ -'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 { Input } from '@repo/shadcn/input'; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from '@repo/shadcn/select'; -import { useForm } from 'react-hook-form'; -import { useUpdateUser } from "@/feactures/users/hooks/use-mutation-users"; -import { UpdateUser, updateUser } from '@/feactures/users/schemas/users'; - -const ROLES = { - // 1: 'Superadmin', - 2: 'Administrador', - 3: 'autoridad', - 4: 'Gerente', - 5: 'Usuario', - 6: 'Productor', - 7: 'Organización' -} - -interface UserFormProps { - onSuccess?: () => void; - onCancel?: () => void; - defaultValues?: Partial; -} - -export function UpdateUserForm({ - onSuccess, - onCancel, - defaultValues, -}: UserFormProps) { - const { - mutate: saveAccountingAccounts, - isPending: isSaving, - isError, - } = useUpdateUser(); - - const defaultformValues = { - username: defaultValues?.username || '', - fullname: defaultValues?.fullname || '', - email: defaultValues?.email || '', - password: '', - id: defaultValues?.id, - phone: defaultValues?.phone || '', - role: undefined, - isActive: defaultValues?.isActive - } - - // console.log(defaultValues); - - const form = useForm({ - resolver: zodResolver(updateUser), - defaultValues: defaultformValues, - mode: 'onChange', // Enable real-time validation - }); - - const onSubmit = async (data: UpdateUser) => { - - const formData = data - - saveAccountingAccounts(formData, { - onSuccess: () => { - form.reset(); - onSuccess?.(); - }, - onError: () => { - form.setError('root', { - type: 'manual', - message: 'Error al guardar la cuenta contable', - }); - }, - }); - }; - - return ( -
- - {form.formState.errors.root && ( -
- {form.formState.errors.root.message} -
- )} -
- ( - - Usuario - - - - - - )} - /> - - ( - - Nombre completo - - - - - - )} - /> - - ( - - Correo - - - - - - )} - /> - - ( - - Teléfono - - - - - - )} - /> - - ( - - Nueva Contraseña - - - - - - )} - /> - - ( - - Rol - - - - )} - /> - - ( - - Estatus - - - - )} - /> -
- -
- - -
-
- - ); -} diff --git a/apps/web/feactures/inventory/components/inventory/users-header.tsx b/apps/web/feactures/inventory/components/inventory/users-header.tsx index 891c9dc..ee32e27 100644 --- a/apps/web/feactures/inventory/components/inventory/users-header.tsx +++ b/apps/web/feactures/inventory/components/inventory/users-header.tsx @@ -1,10 +1,10 @@ 'use client'; -import { useRouter } from 'next/navigation'; +// import { useRouter } from 'next/navigation'; import { Button } from '@repo/shadcn/button'; import { Heading } from '@repo/shadcn/heading'; import { Plus } from 'lucide-react'; import { useState } from 'react'; -import { AccountPlanModal } from './user-modal'; +import { AccountPlanModal } from './inventory-modal'; export function UsersHeader() { const [open, setOpen] = useState(false); @@ -17,7 +17,7 @@ export function UsersHeader() { description="Gestione aquí los productos que usted registre en la plataforma" />
diff --git a/apps/web/feactures/inventory/components/modal-profile.tsx b/apps/web/feactures/inventory/components/modal-profile.tsx deleted file mode 100644 index 4f1853a..0000000 --- a/apps/web/feactures/inventory/components/modal-profile.tsx +++ /dev/null @@ -1,57 +0,0 @@ -'use client'; - -import { - Dialog, - DialogContent, - DialogDescription, - DialogHeader, - DialogTitle, -} from '@repo/shadcn/dialog'; -import { AccountPlan } from '@/feactures/users/schemas/account-plan.schema'; -import { ModalForm } from './update-user-form'; - -interface AccountPlanModalProps { - open: boolean; - onOpenChange: (open: boolean) => void; - defaultValues?: Partial; -} - -export function AccountPlanModal({ - open, - onOpenChange, - defaultValues, -}: AccountPlanModalProps) { - const handleSuccess = () => { - onOpenChange(false); - }; - - const handleCancel = () => { - onOpenChange(false); - }; - - return ( - { - if (!open) { - onOpenChange(false); - } - }} - > - - - Actualizar Perfil - - Complete los campos para actualizar sus datos.
Los campos vacios no seran actualizados. -
-
- - -
-
- ); -} diff --git a/apps/web/feactures/inventory/components/selectList.tsx b/apps/web/feactures/inventory/components/selectList.tsx deleted file mode 100644 index 4150cd5..0000000 --- a/apps/web/feactures/inventory/components/selectList.tsx +++ /dev/null @@ -1,85 +0,0 @@ -// 'use client'; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from '@repo/shadcn/select'; -import { - Form, - FormControl, - FormField, - FormItem, - FormLabel, - FormMessage, -} from '@repo/shadcn/form'; -import { UpdateUser, updateUser } from '@/feactures/users/schemas/users'; -import { useForm } from 'react-hook-form'; -import { zodResolver } from '@hookform/resolvers/zod'; - -interface SelectListProps { - label: string - // values: - values: Array - form: any - name: string - handleChange: any -} - -export function SelectList({ label, values, form, name, handleChange }: SelectListProps) { - // const { label, values, form, name } = props; - // handleChange - - // const defaultformValues = { - // username: '', - // fullname: '', - // email: '', - // password: '', - // id: 0, - // phone: '', - // role: undefined, - // isActive: false - // } - - // const form = useForm({ - // resolver: zodResolver(updateUser), - // defaultValues: defaultformValues, - // mode: 'onChange', // Enable real-time validation - // }); - - - return ( - - {label} - - - - )} - /> -} \ No newline at end of file diff --git a/apps/web/feactures/inventory/components/survey.tsx b/apps/web/feactures/inventory/components/survey.tsx deleted file mode 100644 index b4b5eb9..0000000 --- a/apps/web/feactures/inventory/components/survey.tsx +++ /dev/null @@ -1,28 +0,0 @@ -'use client' - -import { SurveyResponse } from '@/feactures/surveys/components/survey-response'; -import { useSurveysByIdQuery } from '@/feactures/surveys/hooks/use-query-surveys'; - -import { notFound, useParams } from 'next/navigation'; - - -export default function SurveyPage() { - const params = useParams(); - const surveyId = params?.id as string | undefined; - - - if (!surveyId || surveyId === '') { - notFound(); - } - - const { data: survey, isLoading } = useSurveysByIdQuery(Number(surveyId)); - console.log('🎯 useSurveysByIdQuery ejecutado, data:', survey, 'isLoading:', isLoading); - - if (!survey?.data || !survey?.data.published) { - notFound(); - } - - return ( - - ); -} \ No newline at end of file diff --git a/apps/web/feactures/inventory/components/update-user-form.tsx b/apps/web/feactures/inventory/components/update-user-form.tsx deleted file mode 100644 index 6398864..0000000 --- a/apps/web/feactures/inventory/components/update-user-form.tsx +++ /dev/null @@ -1,268 +0,0 @@ -'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 { Input } from '@repo/shadcn/input'; -// import { -// Select, -// SelectContent, -// SelectItem, -// SelectTrigger, -// SelectValue, -// } from '@repo/shadcn/select'; -import { SelectSearchable } from '@repo/shadcn/select-searchable' -import { useForm } from 'react-hook-form'; -import { useUpdateProfile } from "@/feactures/users/hooks/use-mutation-users"; -import { UpdateUser, updateUser } from '@/feactures/users/schemas/users'; -import { toast } from 'sonner'; - -import React from 'react'; -import { useStateQuery, useMunicipalityQuery, useParishQuery } from '@/feactures/location/hooks/use-query-location'; - -interface UserFormProps { - onSuccess?: () => void; - onCancel?: () => void; - defaultValues?: Partial; -} - -export function ModalForm({ - onSuccess, - onCancel, - defaultValues, -}: UserFormProps) { - const { - mutate: saveAccountingAccounts, - isPending: isSaving, - isError, - } = useUpdateProfile(); - - const [state, setState] = React.useState(0); - const [municipality, setMunicipality] = React.useState(0); - const [parish, setParish] = React.useState(0); - - const [disabledMunicipality, setDisabledMunicipality] = React.useState(true); - const [disabledParish, setDisabledParish] = React.useState(true); - - const { data : dataState } = useStateQuery() - const { data : dataMunicipality } = useMunicipalityQuery(state) - const { data : dataParish } = useParishQuery(municipality) - - const stateOptions = dataState?.data || [{id:0,name:'Sin estados'}] - - const municipalityOptions = Array.isArray(dataMunicipality?.data) && dataMunicipality.data.length > 0 - ? dataMunicipality.data - : [{id:0,stateId:0,name:'Sin Municipios'}] - // const parishOptions = dataParish?.data || [{id:0,municipalityId:0,name:'Sin Parroquias'}] - const parishOptions = Array.isArray(dataParish?.data) && dataParish.data.length > 0 - ? dataParish.data - : [{id:0,stateId:0,name:'Sin Parroquias'}] - - - const defaultformValues = { - username: defaultValues?.username || '', - fullname: defaultValues?.fullname || '', - email: defaultValues?.email || '', - password: '', - id: defaultValues?.id, - phone: defaultValues?.phone || '', - role: undefined, - isActive: defaultValues?.isActive, - state: defaultValues?.state, - municipality: defaultValues?.municipality, - parish: defaultValues?.parish - } - - - - // console.log(defaultValues); - - const form = useForm({ - resolver: zodResolver(updateUser), - defaultValues: defaultformValues, - mode: 'onChange', // Enable real-time validation - }); - - const onSubmit = async (data: UpdateUser) => { - - const formData = data - - saveAccountingAccounts(formData, { - onSuccess: () => { - form.reset(); - onSuccess?.(); - toast.success('Actualizado exitosamente!'); - }, - onError: (e) => { - form.setError('root', { - type: 'manual', - message: e.message, - }); - // toast.error(e.message); - }, - }); - }; - - return ( -
- - {form.formState.errors.root && ( -
- {form.formState.errors.root.message} -
- )} -
- ( - - Nombre completo - - - - - - )} - /> - - ( - - Correo - - - - - - )} - /> - - ( - - Teléfono - - - - - - )} - /> - - ( - - Estado - - ({ - value: item.id.toString(), - label: item.name, - })) || [] - } - onValueChange={(value : any) => - {field.onChange(Number(value)); setState(value); setDisabledMunicipality(false); setDisabledParish(true)} - } - placeholder="Selecciona un estado" - defaultValue={field.value?.toString()} - // disabled={readOnly} - /> - - - )} - /> - - ( - - Municipio - - ({ - value: item.id.toString(), - label: item.name, - })) || [] - } - onValueChange={(value : any) => - {field.onChange(Number(value)); setMunicipality(value); setDisabledParish(false)} - } - placeholder="Selecciona un Municipio" - defaultValue={field.value?.toString()} - disabled={disabledMunicipality} - /> - - - )} - /> - - ( - - Parroquia - - ({ - value: item.id.toString(), - label: item.name, - })) || [] - } - onValueChange={(value : any) => - field.onChange(Number(value)) - } - placeholder="Selecciona una Parroquia" - defaultValue={field.value?.toString()} - disabled={disabledParish} - /> - - - )} - /> - - ( - - Nueva Contraseña - - - - - - )} - /> -
- -
- - -
-
- - ); -} diff --git a/apps/web/feactures/inventory/components/user-profile.tsx b/apps/web/feactures/inventory/components/user-profile.tsx deleted file mode 100644 index 72c621c..0000000 --- a/apps/web/feactures/inventory/components/user-profile.tsx +++ /dev/null @@ -1,75 +0,0 @@ -'use client'; -import { useUserByProfile } from '@/feactures/users/hooks/use-query-users'; -import { Button } from '@repo/shadcn/button'; -import { Edit, Edit2 } from 'lucide-react'; -import { useState } from 'react'; -import { AccountPlanModal } from './modal-profile'; - -export function Profile() { - const [open, setOpen] = useState(false); - - const { data } = useUserByProfile(); - - // console.log("🎯 data:", data); - - return ( -
- - - - -

Datos del usuario

-
-
-

Usuario:

-

{data?.data.username || 'Sin Nombre de Usuario'}

-
- -
-

Rol:

-

{data?.data.role || 'Sin Rol'}

-
-
- -

Información personal

-
-
-

Nombre completo:

-

{data?.data.fullname || 'Sin nombre y apellido'}

-
- -
-

Correo:

-

{data?.data.email || 'Sin correo'}

-
- -
-

Teléfono:

-

{data?.data.phone || 'Sin teléfono'}

-
-
- -

Información de ubicación

-
-
-

Estado:

-

{data?.data.state || 'Sin Estado'}

-
- -
-

Municipio:

-

{data?.data.municipality || 'Sin Municipio'}

-
- -
-

Parroquia:

-

{data?.data.parish || 'Sin Parroquia'}

-
-
- -
- ); -} - diff --git a/apps/web/feactures/inventory/hooks/use-mutation-users.ts b/apps/web/feactures/inventory/hooks/use-mutation-users.ts deleted file mode 100644 index dbbf733..0000000 --- a/apps/web/feactures/inventory/hooks/use-mutation-users.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { useMutation, useQueryClient } from "@tanstack/react-query"; -import { CreateUser, UpdateUser } from "../schemas/inventory"; -import { updateUserAction, createUserAction, deleteUserAction, updateProfileAction } from "../actions/actions"; - -// Create mutation -export function useCreateUser() { - const queryClient = useQueryClient(); - const mutation = useMutation({ - mutationFn: (data: CreateUser) => createUserAction(data), - onSuccess: () => queryClient.invalidateQueries({ queryKey: ['users'] }), - // onError: (e) => console.error('Error:', e), - }) - return mutation -} - -// Update mutation -export function useUpdateUser() { - const queryClient = useQueryClient(); - const mutation = useMutation({ - mutationFn: (data: UpdateUser) => updateUserAction(data), - onSuccess: () => queryClient.invalidateQueries({ queryKey: ['users'] }), - onError: (e) => console.error('Error:', e) - }) - return mutation; -} - -export function useUpdateProfile() { - const queryClient = useQueryClient(); - const mutation = useMutation({ - mutationFn: (data: UpdateUser) => updateProfileAction(data), - onSuccess: () => queryClient.invalidateQueries({ queryKey: ['users'] }), - // onError: (e) => console.error('Error:', e) - }) - return mutation; -} - -// Delete mutation -export function useDeleteUser() { - const queryClient = useQueryClient(); - return useMutation({ - mutationFn: (id: number) => deleteUserAction(id), - onSuccess: () => queryClient.invalidateQueries({ queryKey: ['users'] }), - onError: (e) => console.error('Error:', e) - }) -} \ No newline at end of file diff --git a/apps/web/feactures/inventory/hooks/use-mutation.ts b/apps/web/feactures/inventory/hooks/use-mutation.ts new file mode 100644 index 0000000..fbe334c --- /dev/null +++ b/apps/web/feactures/inventory/hooks/use-mutation.ts @@ -0,0 +1,35 @@ +import { useMutation, useQueryClient } from "@tanstack/react-query"; +import { EditInventory } from "../schemas/inventory"; +import { updateUserAction, createProductAction } from "../actions/actions"; + +// Create mutation +export function useCreateUser() { + const queryClient = useQueryClient(); + const mutation = useMutation({ + mutationFn: (data: EditInventory) => createProductAction(data), + onSuccess: () => queryClient.invalidateQueries({ queryKey: ['product'] }), + // onError: (e) => console.error('Error:', e), + }) + return mutation +} + +// Update mutation +export function useUpdateUser() { + const queryClient = useQueryClient(); + const mutation = useMutation({ + mutationFn: (data: EditInventory) => updateUserAction(data), + onSuccess: () => queryClient.invalidateQueries({ queryKey: ['product'] }), + onError: (e) => console.error('Error:', e) + }) + return mutation; +} + +// Delete mutation +// export function useDeleteUser() { +// const queryClient = useQueryClient(); +// return useMutation({ +// mutationFn: (id: number) => deleteUserAction(id), +// onSuccess: () => queryClient.invalidateQueries({ queryKey: ['users'] }), +// onError: (e) => console.error('Error:', e) +// }) +// } \ No newline at end of file diff --git a/apps/web/feactures/inventory/hooks/use-query-surveys.ts b/apps/web/feactures/inventory/hooks/use-query-surveys.ts deleted file mode 100644 index 6610191..0000000 --- a/apps/web/feactures/inventory/hooks/use-query-surveys.ts +++ /dev/null @@ -1,12 +0,0 @@ -'use client' -import { useSafeQuery } from "@/hooks/use-safe-query"; -import { getUsersAction,getProfileAction} from "../actions/actions"; - -// Hook for users -export function useUsersQuery(params = {}) { - return useSafeQuery(['users',params], () => getUsersAction(params)) -} - -export function useUserByProfile() { - return useSafeQuery(['users'], () => getProfileAction()) -} diff --git a/apps/web/feactures/inventory/schemas/inventory.ts b/apps/web/feactures/inventory/schemas/inventory.ts index 640dd85..a20ee35 100644 --- a/apps/web/feactures/inventory/schemas/inventory.ts +++ b/apps/web/feactures/inventory/schemas/inventory.ts @@ -1,54 +1,31 @@ -import { title } from 'process'; import { z } from 'zod'; export type InventoryTable = z.infer; -export type CreateUser = z.infer; -export type UpdateUser = z.infer; +export type EditInventory = z.infer; export const product = z.object({ id: z.number().optional(), title: z.string(), description: z.string(), - // price: z.number(), - // quantity: z.number(), // category: z.string(), - // image: z.string().optional(), stock: z.number(), price: z.string(), urlImg: z.string(), userId: z.number().optional(), }); -export const createUser = z.object({ +export const editInventory = z.object({ id: z.number().optional(), - username: z.string().min(5, { message: "Debe de tener 5 o más caracteres" }), - password: z.string().min(8, { message: "Debe de tener 8 o más caracteres" }), - email: z.string().email({ message: "Correo no válido" }), - fullname: z.string(), - phone: z.string(), - confirmPassword: z.string(), - role: z.number() -}) -.refine((data) => data.password === data.confirmPassword, { - message: 'La contraseña no coincide', - path: ['confirmPassword'], + title: z.string().min(5, { message: "Debe de tener 5 o más caracteres" }), + description: z.string().min(10, { message: "Debe de tener 10 o más caracteres" }), + stock: z.string().transform(val => Number(val)), + price: z.string(), + urlImg: z.string(), + userId: z.number().optional(), }) -export const updateUser = z.object({ - id: z.number(), - username: z.string().min(5, { message: "Debe de tener 5 o más caracteres" }).or(z.literal('')), - password: z.string().min(6, { message: "Debe de tener 6 o más caracteres" }).or(z.literal('')), - email: z.string().email({ message: "Correo no válido" }).or(z.literal('')), - fullname: z.string().optional(), - phone: z.string().optional(), - role: z.number().optional(), - isActive: z.boolean().optional(), - state: z.number().optional().nullable(), - municipality: z.number().optional().nullable(), - parish: z.number().optional().nullable(), -}) -export const surveysApiResponseSchema = z.object({ +export const ApiResponseSchema = z.object({ message: z.string(), data: z.array(product), meta: z.object({ diff --git a/apps/web/feactures/users/components/selectList.tsx b/apps/web/feactures/users/components/selectList.tsx deleted file mode 100644 index eec6688..0000000 --- a/apps/web/feactures/users/components/selectList.tsx +++ /dev/null @@ -1,83 +0,0 @@ -// 'use client'; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from '@repo/shadcn/select'; -import { - Form, - FormControl, - FormField, - FormItem, - FormLabel, - FormMessage, -} from '@repo/shadcn/form'; - - -interface SelectListProps { - label: string - // values: - values: Array - form: any - name: string - handleChange: any -} - -export function SelectList({ label, values, form, name, handleChange }: SelectListProps) { - // const { label, values, form, name } = props; - // handleChange - - // const defaultformValues = { - // username: '', - // fullname: '', - // email: '', - // password: '', - // id: 0, - // phone: '', - // role: undefined, - // isActive: false - // } - - // const form = useForm({ - // resolver: zodResolver(updateUser), - // defaultValues: defaultformValues, - // mode: 'onChange', // Enable real-time validation - // }); - - - return ( - - {label} - - - - )} - /> -} \ No newline at end of file diff --git a/apps/web/feactures/users/components/survey.tsx b/apps/web/feactures/users/components/survey.tsx deleted file mode 100644 index b4b5eb9..0000000 --- a/apps/web/feactures/users/components/survey.tsx +++ /dev/null @@ -1,28 +0,0 @@ -'use client' - -import { SurveyResponse } from '@/feactures/surveys/components/survey-response'; -import { useSurveysByIdQuery } from '@/feactures/surveys/hooks/use-query-surveys'; - -import { notFound, useParams } from 'next/navigation'; - - -export default function SurveyPage() { - const params = useParams(); - const surveyId = params?.id as string | undefined; - - - if (!surveyId || surveyId === '') { - notFound(); - } - - const { data: survey, isLoading } = useSurveysByIdQuery(Number(surveyId)); - console.log('🎯 useSurveysByIdQuery ejecutado, data:', survey, 'isLoading:', isLoading); - - if (!survey?.data || !survey?.data.published) { - notFound(); - } - - return ( - - ); -} \ No newline at end of file