crud cliente ok

main
Freddy Heredia 2 years ago
parent 2a2dd4f4e3
commit 7ee82313d5

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

@ -16,7 +16,7 @@ export default function RootLayout({
children: React.ReactNode
}) {
return (
<html lang="en">
<html lang="en" data-theme="cmyk">
<body className={inter.className}>
<div>

@ -1,3 +1,87 @@
export default function Page({ params }: { params: { id: string } }) {
return <div>My Post: {params.id}</div>
}
'use client'
import { Input } from '@/components/Input';
import { useForm } from 'react-hook-form';
import Button from '@/components/Button';
import { useRouter } from 'next/navigation';
import { useEffect, useState } from 'react';
import { Toolbar } from '@/components/Toolbar';
import useFetchWithAuth from '@/hooks/useFetchWithAuth';
import saveWithAuth from '@/hooks/saveWithAuth';
const ClientePage = ({ params }: { params: { id: string } }) => {
const router = useRouter();
const entityId =params.id;
const [cliente, setCliente] = useState({
id: 0,
cedula: '',
nombreCompleto: '',
});
const { register, setValue,getValues,handleSubmit, formState: { errors } } = useForm(
{
defaultValues: {
...cliente
}
}
);
const getInitData = async () => {
if (!entityId || entityId=="0")
return;
const { data, error } = await useFetchWithAuth("cliente/" + entityId);
if (!error) {
if (data.id!=0){
setValue("id", data['id'])
setValue("cedula", data['cedula'])
setValue("nombreCompleto", data['nombreCompleto'])
setCliente(data)
}
} else {
console.log(error)
}
}
const onSubmit = async (entity: any) => {
try {
let endpoint = "cliente";
const { data, error } = await saveWithAuth(endpoint, entityId, entity);
if (error) {
console.log(error);
} else {
router.push("pedidos/"+endpoint+"/"+ data.id)
}
} catch (e) {
console.log("Post error:");
console.table(e);
}
}
useEffect(() => {
getInitData();
}, [])
return (
<>
<div className='grow '>
<Toolbar pathForm='pedidos/cliente/0' pathList='pedidos/cliente/' currentEntity={getValues("nombreCompleto")} entityName='cliente'/>
<div className='h-96 w-4/6 mx-auto p-4 border-solid border-gray-300 border-2 rounded-xl '>
<form onSubmit={handleSubmit(onSubmit)}>
<Input id='id' label='' register={register} type='hidden'/>
<Input id='cedula' label='Cédula' register={register} />
<Input id='nombreCompleto' label='Nombre completo' register={register} />
<Button className="btn-sm my-2" type='submit' label='Guardar' />
{errors?.root?.server && <p>Form submit failed.</p>}
</form>
</div>
</div>
</>
)
}
export default ClientePage;

@ -1,24 +1,20 @@
import { Toolbar } from '@/components/Toolbar';
import Head from '@/components/table/Head'
import TBody from '@/components/table/TBody';
import { FC } from 'react'
interface Props {
}
const ListadoCliente:FC <Props> = () => {
const ListadoCliente = () => {
return (
<>
<div className='flex-col mx-auto'>
<p className='text-center text-primary'>Listado <span className='text-secondary'>de cliente</span></p>
<div className='overflow-x-auto'>
<table className='table table-xs table-pin-rows table-pin-cols'>
<div className='grow '>
<Toolbar pathForm='pedidos/cliente/0' pathList='pedidos/cliente/' currentEntity={""} entityName='cliente'/>
<p className='text-center text-black'>Listado <span className='text-primary'>de clientes</span></p>
<div className='overflow-x-auto'>
<table className='table table-xs table-pin-rows table-pin-cols w-5/6 mx-auto'>
<Head columnas={["","Cédula","Nombre completo"]}/>
<TBody columnas={["cedula","nombreCompleto"]} endpoint='cliente'/>
</table>
</div>
</div>
</div>
</div>
</>
)
}

@ -2,6 +2,7 @@ import Navbar from '@/components/Navbar'
import './../globals.css'
import { Inter } from 'next/font/google'
import Sidebar from '@/components/Sidebar'
import { Toolbar } from '@/components/Toolbar'
const inter = Inter({ subsets: ['latin'] })
@ -20,7 +21,6 @@ export default function RootLayout({
<>
<Navbar />
<div className='flex'>
<Sidebar />
{children}
</div>

@ -1,26 +1,22 @@
import Navbar from '@/components/Navbar'
import { Toolbar } from '@/components/Toolbar'
import Head from '@/components/table/Head'
import TBody from '@/components/table/TBody'
import { FC } from 'react'
interface Props {
}
const ListadoProducto:FC <Props> = () => {
return (
<>
<div className='flex-col mx-auto'>
<p className='text-center text-primary'>Listado <span className='text-secondary'>de producto</span></p>
<div className='overflow-x-auto'>
<table className='table table-xs table-pin-rows table-pin-cols'>
<Head columnas={["","Nombre","Precio"]}/>
<TBody columnas={["nombre","precio"]} endpoint='api/producto'/>
const Listadoproducto = () => {
return (
<>
<div className='grow '>
<Toolbar pathForm='pedidos/producto/0' pathList='pedidos/producto/' currentEntity={""} entityName='producto'/>
<p className='text-center text-black'>Listado <span className='text-primary'>de productos</span></p>
<div className='overflow-x-auto'>
<table className='table table-xs table-pin-rows table-pin-cols w-5/6 mx-auto'>
<Head columnas={["","Nombre","Precio"]}/>
<TBody columnas={["nombre","precio"]} endpoint='producto'/>
</table>
</div>
</div>
</>
)
</div>
</div>
</>
)
}
export default ListadoProducto
export default Listadoproducto

@ -5,15 +5,17 @@ import { FC } from 'react'
interface Props {
label: string,
onClick: () => void
onClick?: () => void
type?:"button" | "submit" | "reset" | undefined
className?: string
}
const Button:FC <Props> = ({label, onClick}) => {
const Button:FC <Props> = ({label, onClick=()=>{},type='button', className}) => {
return (
<>
<button
<button className={'btn btn-primary '+ className}
onClick={onClick}
type={type}
>{label}
</button>
</>

@ -0,0 +1,26 @@
import React from 'react';
import { FC } from 'react'
import { UseFormRegister,FieldValues } from 'react-hook-form';
interface Props {
id: string,
label: string,
type?:"text"|"password"|"checkbox"|"hidden"|"number"|"date"|"datetime-local",
register: UseFormRegister<any>
}
export const Input:FC <Props> = ({id,label,type="text", register}) => {
return (
<>
<div className='flex flex-col'>
<label htmlFor={id}>{label}</label>
<input
type={type}
className='input input-primary'
id={id}
{...register(id)}/>
</div>
</>
)
}

@ -0,0 +1,55 @@
import React, { FC, useEffect, useState } from 'react'
import { Controller, Control } from 'react-hook-form';
import useFetchWithAuth from '@/hooks/useFetchWithAuth';
interface Props {
entity: string,
control: Control<any, any>
}
export const Manytoone: FC<Props> = ({entity, control }) => {
const [data, setData] = useState([{id:0,nombre:'Select one'}]);
useEffect(() => {
async function fetchData() {
try {
const { data, error } = await useFetchWithAuth(entity.toLowerCase());
setData(data);
} catch (trace) {
console.error(trace);
}
}
fetchData();
}, [entity]);
return (
<>
<label htmlFor={entity}>{entity}</label>
<Controller key={entity}
render={({ field }) => (
<select key={entity+"select"} {...field} className={' p-2 border-2 border-sky-300 outline-sky-300 bg-white rounded-xl w-full'}>
<option key={entity+0} value={0}>
Seleccione un valor
</option>
{data.map((item) => (
<option key={entity+item.id} value={item.id}>
{item['nombre']}
</option>
))}
</select>
)}
name={entity}
control={control}
/>
</>
)
}

@ -0,0 +1,58 @@
'use client'
import { FC } from 'react'
import Link from 'next/link'
interface Props {
pathForm: string
pathList: string
entityName: string
currentEntity: string
}
export const Toolbar: FC<Props> = ({
pathForm,
pathList,
entityName,
currentEntity,
}) => {
return (
<>
<div className="flex flex-row items-start sm:items-center">
<Link href={pathForm} >
<button className="my-2 mr-3 font-bold rounded btn btn-outline btn-sm group">
<svg className="w-3 h-3 mr-1 group-hover:animate-bounce group-hover:fill-white"
xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" version="1.1"
viewBox="0 0 512 512" xmlSpace="preserve">
<g>
<path
d="M480,224H288V32c0-17.673-14.327-32-32-32s-32,14.327-32,32v192H32c-17.673,0-32,14.327-32,32s14.327,32,32,32h192v192 c0,17.673,14.327,32,32,32s32-14.327,32-32V288h192c17.673,0,32-14.327,32-32S497.673,224,480,224z" />
</g>
</svg>
<span className="hidden md:inline">
Nuevo
</span>
</button>
</Link>
<h1 className="flex-1 my-2 text-lg text-left">
<div className="flex-1 text-sm font-bold text-gray-600 breadcrumbs breadflex-1">
<ul>
<li>
<Link href={pathList}>{entityName}</Link>
</li>
<li>
<a>{currentEntity}</a>
</li>
</ul>
</div>
</h1>
</div>
</>
)
}

@ -31,12 +31,12 @@ const TBody:FC <Props> = ({columnas, endpoint}) => {
{entidades && entidades.map((entidad) => (
<tr key={entidad['id']}>
<td>
<td className='w-6'>
<Link href={{
pathname: "/pedidos/"+endpoint+"/"+entidad['id'],
}}>
Editar
<img className='w-4 h-4' src="/lapiz.png" />
</Link>
</td>
{columnas.map((columna)=> (

@ -0,0 +1,43 @@
import Cookies from 'js-cookie';
const fecher = async (url: string, id:string, token: string, data:any) => {
return await fetch(url, {
method: id==="0" ? 'POST': 'PATCH',
mode: 'cors',
headers: {
'Authorization' :token,
'Content-Type': 'application/json',
'Accept':'application/json'
},
body: data,
});
}
const saveWithAuth = async (url: string, id:string, body:any) => {
url= process.env.API_URL+"/api/"+url+"/";
if ( Number(id)>0){
url = url + id +"/"
}
const token = Cookies.get('token') || "";
let data;
let error;
try{
data = JSON.stringify(body);
console.log(url)
const response = await fecher(url, id, token, data)
if (response.ok){
data = await response.json();
}else {
error = "Servidor: "+ ((await response.json()).trace).substring(1,300);
}
}catch (e){
error = "Cliente: "+e;
}
return {
data,
error
}
}
export default saveWithAuth;

@ -11,13 +11,13 @@ const fecher = async (url:string, token: string) => {
const useBasicAuth = async (username: string, password: string) => {
let bearerToken = "";
try {
console.log("ingreso en el useBasicAuth")
const token = 'Basic '+ Buffer.from(username+":"+password).toString('base64');
console.log(token)
const baseUrl = process.env.API_URL;
console.log(baseUrl)
const response = await fecher(baseUrl+'/login', token);
console.log(response)
if (response.ok){
bearerToken = response.headers.get("Authorization") || "";

@ -11,6 +11,7 @@ const fecher = async (url:string, token: string) => {
const useBasicAuth = async (endpoint:string) => {
let data = null;
let error;
try {
const token = Cookies.get("token")|| "";
@ -21,14 +22,16 @@ const useBasicAuth = async (endpoint:string) => {
if (response.ok){
data = await response.json();
}
} catch (error) {
console.log(error)
}else {
error = "Servidor: "+ ((await response.json()).trace);
}
} catch (err) {
error = "Cliente: "+err;
}
return{
data
data,
error
}
}

@ -15,4 +15,7 @@ module.exports = {
},
},
plugins: [require("daisyui")],
daisyui: {
themes: ["light", "dark", "cmyk"],
},
}

Loading…
Cancel
Save