Merge branch 'style/footer' into 'main'
Refactor layout and styling across components for improved responsiveness See merge request fjmimbre/deck-of-cards!4
This commit is contained in:
@@ -1,11 +1,11 @@
|
|||||||
export default function CriterionInput({ criterionName, setCriterionName, error }) {
|
export default function CriterionInput({ criterionName, setCriterionName, error }) {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-row items-center justify-center gap-3 w-full z-30 relative mt-4">
|
<div className="flex flex-col sm:flex-row items-stretch sm:items-center justify-center gap-2 sm:gap-3 w-full max-w-full z-30 relative mt-4 px-1">
|
||||||
<label className="text-sm font-bold text-slate-600 uppercase tracking-wide whitespace-nowrap">
|
<label className="text-sm font-bold text-slate-600 uppercase tracking-wide text-center sm:text-left sm:whitespace-nowrap shrink-0">
|
||||||
Nombre del Criterio:
|
Nombre del Criterio:
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<div className="relative w-72">
|
<div className="relative w-full max-w-xs sm:max-w-none sm:w-72 mx-auto sm:mx-0">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Ej: Calidad del código"
|
placeholder="Ej: Calidad del código"
|
||||||
@@ -19,7 +19,7 @@ export default function CriterionInput({ criterionName, setCriterionName, error
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
{error && (
|
{error && (
|
||||||
<span className="absolute top-1/2 -right-18 -translate-y-1/2 text-red-500 text-xs font-semibold">
|
<span className="mt-1 block text-center sm:absolute sm:mt-0 sm:top-1/2 sm:-right-20 sm:-translate-y-1/2 text-red-500 text-xs font-semibold whitespace-nowrap">
|
||||||
Obligatorio
|
Obligatorio
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -14,14 +14,15 @@ export default function Step1BaseScale({
|
|||||||
const [isZoomActive, setIsZoomActive] = useState(true);
|
const [isZoomActive, setIsZoomActive] = useState(true);
|
||||||
const containerRef = useRef(null);
|
const containerRef = useRef(null);
|
||||||
const tableRef = useRef(null);
|
const tableRef = useRef(null);
|
||||||
const [dimensions, setDimensions] = useState({ container: 1000, table: 0 });
|
const [dimensions, setDimensions] = useState({ container: 1000, table: 0, tableHeight: 0 });
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const updateMeasurements = () => {
|
const updateMeasurements = () => {
|
||||||
if (containerRef.current && tableRef.current) {
|
if (containerRef.current && tableRef.current) {
|
||||||
setDimensions({
|
setDimensions({
|
||||||
container: containerRef.current.offsetWidth,
|
container: containerRef.current.offsetWidth,
|
||||||
table: tableRef.current.scrollWidth
|
table: tableRef.current.scrollWidth,
|
||||||
|
tableHeight: tableRef.current.offsetHeight,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -37,8 +38,13 @@ export default function Step1BaseScale({
|
|||||||
const dynamicScale = needsZoom ? (dimensions.container / dimensions.table) * 0.95 : 1;
|
const dynamicScale = needsZoom ? (dimensions.container / dimensions.table) * 0.95 : 1;
|
||||||
const currentScale = isZoomActive && needsZoom ? dynamicScale : 1;
|
const currentScale = isZoomActive && needsZoom ? dynamicScale : 1;
|
||||||
|
|
||||||
|
const isScaledLayout = isZoomActive && needsZoom && currentScale < 1 && dimensions.tableHeight > 0;
|
||||||
|
const scaledViewportHeight = isScaledLayout
|
||||||
|
? dimensions.tableHeight * currentScale + 12
|
||||||
|
: undefined;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full bg-white p-6 rounded-2xl shadow-sm border border-slate-200 flex flex-col items-center animate-fade-in relative overflow-visible">
|
<div className="w-full bg-white p-6 rounded-2xl shadow-sm border border-slate-200 flex flex-col items-center animate-fade-in relative overflow-x-clip">
|
||||||
|
|
||||||
<div className="flex justify-between items-center w-full mb-4 border-b pb-3 relative z-30">
|
<div className="flex justify-between items-center w-full mb-4 border-b pb-3 relative z-30">
|
||||||
<h2 className="text-xl font-bold text-slate-800">
|
<h2 className="text-xl font-bold text-slate-800">
|
||||||
@@ -60,10 +66,16 @@ export default function Step1BaseScale({
|
|||||||
|
|
||||||
<CriterionInput criterionName={criterionName} setCriterionName={handleCriterionChange} error={errors.criterion} />
|
<CriterionInput criterionName={criterionName} setCriterionName={handleCriterionChange} error={errors.criterion} />
|
||||||
|
|
||||||
<div ref={containerRef} className={`w-full mt-2 transition-all relative ${!isZoomActive && needsZoom ? 'overflow-x-auto flex justify-start pt-4 px-4 custom-scrollbar' : 'overflow-visible flex justify-center pt-4'}`}>
|
<div ref={containerRef} className={`w-full mt-2 transition-all relative ${!isZoomActive && needsZoom ? 'overflow-x-auto flex justify-start pt-4 px-4 pb-4 custom-scrollbar' : 'overflow-x-clip flex justify-center pt-4'}`}>
|
||||||
<div className={`flex flex-row items-start min-w-max transition-transform duration-500 ease-out px-4 origin-top`} style={{ transform: `scale(${currentScale})`, marginBottom: isZoomActive && currentScale < 1 ? `-${(1 - currentScale) * 300}px` : '0px' }}>
|
<div
|
||||||
|
className="flex w-full justify-center transition-[height] duration-500 ease-out"
|
||||||
<div ref={tableRef} className="flex flex-row items-start relative px-10 overflow-visible">
|
style={isScaledLayout ? { height: scaledViewportHeight } : undefined}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex flex-row items-start min-w-max px-4 origin-top transition-transform duration-500 ease-out"
|
||||||
|
style={{ transform: `scale(${currentScale})` }}
|
||||||
|
>
|
||||||
|
<div ref={tableRef} className="flex flex-row items-start relative px-10 overflow-x-clip">
|
||||||
{levels.map((level, index) => (
|
{levels.map((level, index) => (
|
||||||
<React.Fragment key={index}>
|
<React.Fragment key={index}>
|
||||||
|
|
||||||
@@ -96,7 +108,7 @@ export default function Step1BaseScale({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -2,86 +2,89 @@ export default function Footer() {
|
|||||||
return (
|
return (
|
||||||
<footer className="bg-white border-t border-slate-200 mt-auto shrink-0 w-full pt-8 pb-8">
|
<footer className="bg-white border-t border-slate-200 mt-auto shrink-0 w-full pt-8 pb-8">
|
||||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
|
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-12 gap-8 lg:gap-6">
|
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-12 gap-8 lg:gap-6">
|
||||||
|
|
||||||
{/* Proyecto */}
|
{/* Proyecto */}
|
||||||
<div className="lg:col-span-4 flex flex-col">
|
<div className="lg:col-span-4 flex flex-col items-center text-center sm:items-start sm:text-left">
|
||||||
<div className="flex items-center gap-3 mb-3">
|
<div className="flex flex-wrap items-center justify-center gap-3 mb-3 sm:justify-start">
|
||||||
<span className="text-xl font-black text-slate-800 tracking-tight">Deck of Cards</span>
|
<span className="text-xl font-black text-slate-800 tracking-tight">Deck of Cards</span>
|
||||||
<span className="px-2 py-1 bg-blue-50 text-blue-700 text-[10px] font-black uppercase tracking-widest rounded-md">
|
<span className="px-2 py-1 bg-blue-50 text-blue-700 text-[10px] font-black uppercase tracking-widest rounded-md">
|
||||||
Software Científico
|
Software Científico
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-sm text-slate-500 leading-relaxed max-w-sm">
|
<p className="text-sm text-slate-500 leading-relaxed max-w-sm">
|
||||||
Plataforma web para la elicitación de escalas de valor y construcción de conjuntos difusos interpretables (DoC-MF).
|
Elicitación de escalas de valor y construcción de conjuntos difusos interpretables (DoC-MF).
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Desarrollo */}
|
{/* Desarrollo */}
|
||||||
<div className="lg:col-span-3 flex flex-col">
|
<div className="lg:col-span-3 flex flex-col items-center text-center sm:items-start sm:text-left">
|
||||||
<h4 className="text-[10px] font-black uppercase tracking-[0.2em] text-slate-400 mb-3">Ingeniería y Desarrollo</h4>
|
<h4 className="text-[10px] font-black uppercase tracking-[0.2em] text-slate-400 mb-3">Ingeniería y Desarrollo</h4>
|
||||||
<ul className="text-sm font-bold text-slate-700 space-y-2">
|
<ul className="text-sm font-bold text-slate-700 space-y-2">
|
||||||
<li className="flex flex-wrap items-center gap-2">
|
<li className="flex flex-wrap items-center justify-center gap-2 sm:justify-start">
|
||||||
Alexis López Moral
|
Alexis López Moral
|
||||||
<span className="text-slate-400 font-medium text-[10px] font-mono bg-slate-50 border border-slate-100 px-1.5 py-0.5 rounded">Frontend</span>
|
<span className="text-slate-400 font-medium text-[10px] font-mono bg-slate-50 border border-slate-100 px-1.5 py-0.5 rounded">Frontend</span>
|
||||||
</li>
|
</li>
|
||||||
<li className="flex flex-wrap items-center gap-2">
|
<li className="flex flex-wrap items-center justify-center gap-2 sm:justify-start">
|
||||||
Mireya Cueto Garrido
|
Mireya Cueto Garrido
|
||||||
<span className="text-slate-400 font-medium text-[10px] font-mono bg-slate-50 border border-slate-100 px-1.5 py-0.5 rounded">Backend</span>
|
<span className="text-slate-400 font-medium text-[10px] font-mono bg-slate-50 border border-slate-100 px-1.5 py-0.5 rounded">Backend</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Dirección Científica */}
|
{/* Dirección Científica */}
|
||||||
<div className="lg:col-span-2 flex flex-col">
|
<div className="lg:col-span-2 flex flex-col items-center text-center sm:items-start sm:text-left">
|
||||||
<h4 className="text-[10px] font-black uppercase tracking-[0.2em] text-slate-400 mb-3">Dirección Científica</h4>
|
<h4 className="text-[10px] font-black uppercase tracking-[0.2em] text-slate-400 mb-3">Dirección Científica</h4>
|
||||||
<p className="text-sm font-bold text-slate-700">Luis Martínez López</p>
|
<p className="text-sm font-bold text-slate-700">Luis Martínez López</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Enlaces Institucionales y Código */}
|
{/* Enlaces Institucionales y Código */}
|
||||||
<div className="lg:col-span-3 flex flex-col gap-5 sm:items-start lg:items-end">
|
<div className="lg:col-span-3 flex flex-col items-center w-full sm:items-start lg:items-end">
|
||||||
|
|
||||||
{/* Universidad de Jaén */}
|
|
||||||
<a
|
|
||||||
href="https://www.ujaen.es/"
|
|
||||||
target="_blank" rel="noopener noreferrer"
|
|
||||||
className="group flex items-center gap-3 w-fit"
|
|
||||||
title="Ir a la web oficial de la Universidad de Jaén"
|
|
||||||
>
|
|
||||||
<div className="text-right border-r-2 border-slate-300 group-hover:border-blue-600 pr-3 flex flex-col justify-center h-9 transition-colors">
|
|
||||||
<span className="text-xs font-black text-slate-800 uppercase tracking-widest leading-none mb-1">Universidad</span>
|
|
||||||
<span className="text-[10px] font-bold text-slate-500 uppercase tracking-[0.3em] leading-none">de Jaén</span>
|
|
||||||
</div>
|
|
||||||
<img
|
|
||||||
src="/uja-logo.png"
|
|
||||||
alt="Logo UJA"
|
|
||||||
className="w-9 h-9 object-contain grayscale group-hover:grayscale-0 transition-all opacity-80 group-hover:opacity-100"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
{/* Repositorio GitHub */}
|
<div className="grid grid-cols-2 gap-2.5 sm:gap-3 w-full max-w-sm sm:max-w-none lg:flex lg:flex-col lg:w-auto lg:gap-5">
|
||||||
<a
|
|
||||||
href="https://github.com/alexislopez-dev/deck-of-cards"
|
|
||||||
target="_blank" rel="noopener noreferrer"
|
|
||||||
className="group flex items-center gap-3 w-fit"
|
|
||||||
title="Ver código fuente en GitHub"
|
|
||||||
>
|
|
||||||
<div className="text-right border-r-2 border-slate-300 group-hover:border-slate-800 pr-3 flex flex-col justify-center h-9 transition-colors">
|
|
||||||
<span className="text-xs font-black text-slate-800 uppercase tracking-widest leading-none mb-1">Repositorio</span>
|
|
||||||
<span className="text-[10px] font-bold text-slate-500 uppercase tracking-[0.3em] leading-none">Oficial</span>
|
|
||||||
</div>
|
|
||||||
<svg className="w-9 h-9 text-slate-400 group-hover:text-slate-800 transition-colors" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
|
||||||
<path fillRule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clipRule="evenodd" />
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
|
{/* Universidad de Jaén */}
|
||||||
|
<a
|
||||||
|
href="https://www.ujaen.es/"
|
||||||
|
target="_blank" rel="noopener noreferrer"
|
||||||
|
className="group flex items-center justify-center gap-2.5 rounded-lg border border-slate-200 bg-slate-50/50 px-3 py-2 transition-colors hover:bg-slate-100"
|
||||||
|
title="Ir a la web oficial de la Universidad de Jaén"
|
||||||
|
>
|
||||||
|
<div className="flex h-8 flex-col justify-center border-r-2 border-slate-300 pr-2.5 text-right transition-colors group-hover:border-blue-600">
|
||||||
|
<span className="mb-0.5 text-[11px] font-bold uppercase leading-none tracking-wide text-slate-800">Universidad</span>
|
||||||
|
<span className="text-[10px] font-medium uppercase leading-none tracking-[0.22em] text-slate-500">de Jaén</span>
|
||||||
|
</div>
|
||||||
|
<img
|
||||||
|
src={`${import.meta.env.BASE_URL}uja-logo.png`}
|
||||||
|
alt="Logo UJA"
|
||||||
|
className="h-7 w-7 object-contain grayscale opacity-80 transition-all group-hover:grayscale-0 group-hover:opacity-100"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
{/* Repositorio GitHub */}
|
||||||
|
<a
|
||||||
|
href="https://github.com/alexislopez-dev/deck-of-cards"
|
||||||
|
target="_blank" rel="noopener noreferrer"
|
||||||
|
className="group flex items-center justify-center gap-2.5 rounded-lg border border-slate-200 bg-slate-50/50 px-3 py-2 transition-colors hover:bg-slate-100"
|
||||||
|
title="Ver código fuente en GitHub"
|
||||||
|
>
|
||||||
|
<div className="flex h-8 flex-col justify-center border-r-2 border-slate-300 pr-2.5 text-right transition-colors group-hover:border-slate-800">
|
||||||
|
<span className="mb-0.5 text-[11px] font-bold uppercase leading-none tracking-wide text-slate-800">Repositorio</span>
|
||||||
|
<span className="text-[10px] font-medium uppercase leading-none tracking-[0.22em] text-slate-500">Oficial</span>
|
||||||
|
</div>
|
||||||
|
<svg className="h-7 w-7 text-slate-400 transition-colors group-hover:text-slate-800" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||||
|
<path fillRule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clipRule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Sub-Footer: Copyright y Referencia Científica */}
|
{/* Sub-Footer: Copyright y Referencia Científica */}
|
||||||
<div className="mt-6 pt-6 border-t border-slate-100 flex flex-col md:flex-row justify-between items-center gap-4">
|
<div className="mt-6 pt-6 border-t border-slate-100 flex flex-col md:flex-row justify-between items-center gap-4">
|
||||||
<p className="text-[10px] font-bold text-slate-400 uppercase tracking-widest whitespace-nowrap">
|
<p className="text-[10px] font-bold text-slate-400 uppercase tracking-widest text-center">
|
||||||
© {new Date().getFullYear()} Deck of Cards App.
|
© {new Date().getFullYear()} Deck of Cards App.
|
||||||
</p>
|
</p>
|
||||||
<p className="text-[10px] font-medium text-slate-400 text-center md:text-right">
|
<p className="text-[10px] font-medium text-slate-400 text-center md:text-right">
|
||||||
@@ -92,4 +95,4 @@ export default function Footer() {
|
|||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import Footer from './Footer';
|
|||||||
|
|
||||||
export default function MainLayout({ children }) {
|
export default function MainLayout({ children }) {
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen flex flex-col bg-slate-50 font-sans">
|
<div className="min-h-screen flex flex-col overflow-x-clip bg-slate-50 font-sans">
|
||||||
|
|
||||||
<Header />
|
<Header />
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,11 @@
|
|||||||
/* Solo escanear código fuente; evita que Tailwind/Vite procesen Dockerfile u otros archivos en /app */
|
/* Solo escanear código fuente; evita que Tailwind/Vite procesen Dockerfile u otros archivos en /app */
|
||||||
@source "./src/**/*.{js,jsx}";
|
@source "./src/**/*.{js,jsx}";
|
||||||
|
|
||||||
|
html {
|
||||||
|
overflow-x: clip;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
overflow-x: clip;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user