Se hizo página de carga y descarga
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import FuenteCard from "@/components/fuenteCard";
|
||||
import CargaArchivo from "@/components/cargaArchivo";
|
||||
import Button from "@/components/button";
|
||||
|
||||
const fuentes = [
|
||||
{ nombre: "Fuente 1", fecha: "Martes 3 de mayo 2025", activa: true },
|
||||
{ nombre: "Fuente 2", fecha: "Martes 3 de mayo 2025", activa: true },
|
||||
{ nombre: "Fuente 3", fecha: "Martes 3 de mayo 2025", activa: true },
|
||||
{ nombre: "Fuente 4", fecha: "Martes 3 de mayo 2025", activa: false },
|
||||
];
|
||||
|
||||
export default function Dashboard() {
|
||||
return (
|
||||
<main className="p-6" style={{
|
||||
minHeight: "100vh",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
background: "#063970"}}>
|
||||
|
||||
|
||||
|
||||
|
||||
<div className="flex gap-4 flex-wrap mb-6" style={{
|
||||
background: "#f3f4f6",
|
||||
padding: "2rem",
|
||||
borderRadius: "8px",
|
||||
boxShadow: "0 4px 6px rgba(253, 253, 253, 0.1)",
|
||||
width: "100%",
|
||||
|
||||
}}>
|
||||
<Button onClick={() => alert('¡Hola mundo!')} className='mb-3'>
|
||||
descarga Base de datos
|
||||
</Button>
|
||||
<h2 className="text-xl font-semibold mb-4">Fuentes</h2>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
justifyContent: "center",
|
||||
gap: "16px", // espacio entre las cajas
|
||||
}}>
|
||||
{fuentes.map((f, idx) => (
|
||||
<FuenteCard
|
||||
key={idx}
|
||||
nombre={f.nombre}
|
||||
fecha={f.fecha}
|
||||
activa={f.activa}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<h2 className="text-xl font-semibold mb-4">Carga</h2>
|
||||
<div>
|
||||
<CargaArchivo />
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
+3
-3
@@ -20,9 +20,9 @@ export default function Login() {
|
||||
}}>
|
||||
<div style={{
|
||||
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
background: "#f3f4f6",
|
||||
padding: "2rem",
|
||||
borderRadius: "8px",
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
import React from 'react';
|
||||
|
||||
/**
|
||||
* Botón reutilizable con soporte para variantes de Bootstrap y personalización de íconos.
|
||||
*
|
||||
* @component
|
||||
*/
|
||||
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
/**
|
||||
* Variante Bootstrap o personalizada. Ej: `primary`, `danger`, `mi-clase-custom`.
|
||||
* @default "primary"
|
||||
*/
|
||||
variant?: string;
|
||||
|
||||
/**
|
||||
* Si se usa variante `outline` (por ejemplo, `btn-outline-primary`).
|
||||
* @default false
|
||||
*/
|
||||
outline?: boolean;
|
||||
|
||||
/**
|
||||
* Ícono Bootstrap (`string`, como `check-circle`) o componente React.
|
||||
*/
|
||||
icon?: string | React.ReactNode;
|
||||
|
||||
/**
|
||||
* Tamaño del botón: `sm` o `lg` para tamaños Bootstrap.
|
||||
*/
|
||||
size?: 'sm' | 'lg';
|
||||
|
||||
/**
|
||||
* Clases adicionales personalizadas para el botón.
|
||||
*/
|
||||
className?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Componente `Button` con estilos de Bootstrap y soporte para íconos.
|
||||
*/
|
||||
const Button: React.FC<ButtonProps> = ({
|
||||
children,
|
||||
type = 'button',
|
||||
icon,
|
||||
className = '',
|
||||
variant = 'primary',
|
||||
outline = false,
|
||||
disabled = false,
|
||||
size,
|
||||
...rest
|
||||
}) => {
|
||||
const btnVariant = outline ? `btn-outline-${variant}` : `btn-${variant}`;
|
||||
const sizeClass = size ? `btn-${size}` : '';
|
||||
const combinedClasses = `btn ${btnVariant} ${sizeClass} ${className}`.trim();
|
||||
|
||||
return (
|
||||
<button
|
||||
type={type}
|
||||
disabled={disabled}
|
||||
className={combinedClasses}
|
||||
{...rest}
|
||||
>
|
||||
{typeof icon === 'string' ? (
|
||||
<i className={`me-2 bi bi-${icon}`}></i>
|
||||
) : (
|
||||
icon && <span className="me-2">{icon}</span>
|
||||
)}
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
export default Button;
|
||||
@@ -0,0 +1,50 @@
|
||||
"use client";
|
||||
import React, { useState } from "react";
|
||||
|
||||
const CargaArchivo: React.FC = () => {
|
||||
const [archivo, setArchivo] = useState<File | null>(null);
|
||||
|
||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const file = e.target.files?.[0];
|
||||
if (file) setArchivo(file);
|
||||
};
|
||||
|
||||
const handleUpload = async () => {
|
||||
if (!archivo) return;
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append("archivo", archivo);
|
||||
|
||||
const res = await fetch("/api/cargar-archivo", {
|
||||
method: "POST",
|
||||
body: formData,
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
alert("Archivo subido correctamente");
|
||||
setArchivo(null);
|
||||
} else {
|
||||
alert("Error al subir archivo");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-full">
|
||||
<input
|
||||
type="file"
|
||||
accept=".xls,.xlsx"
|
||||
onChange={handleChange}
|
||||
className="mb-4 block text-sm"
|
||||
/>
|
||||
<button
|
||||
onClick={handleUpload}
|
||||
disabled={!archivo}
|
||||
className="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700"
|
||||
>
|
||||
Subir archivo
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CargaArchivo;
|
||||
@@ -0,0 +1,26 @@
|
||||
type FuenteCardProps = {
|
||||
nombre: string;
|
||||
fecha: string;
|
||||
activa: boolean;
|
||||
};
|
||||
|
||||
const FuenteCard: React.FC<FuenteCardProps> = ({ nombre, fecha, activa }) => {
|
||||
return (
|
||||
<div className="border rounded shadow-sm p-4 bg-white w-44">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<span className="font-semibold text-sm">{nombre}</span>
|
||||
<span
|
||||
className={`w-3 h-3 rounded-full ${
|
||||
activa ? "bg-green-500" : "bg-red-500"
|
||||
}`}
|
||||
/>
|
||||
</div>
|
||||
<p className="text-xs text-gray-700 leading-tight">
|
||||
Fecha de carga:<br />
|
||||
{fecha}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default FuenteCard;
|
||||
Reference in New Issue
Block a user