Se hizo página de carga y descarga

This commit is contained in:
evenegas
2025-06-13 10:52:27 -06:00
parent 56e2b4b8d6
commit 877fcfe81e
5 changed files with 214 additions and 3 deletions
+63
View File
@@ -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
View File
@@ -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",
+72
View File
@@ -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;
+50
View File
@@ -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;
+26
View File
@@ -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;