198 lines
9.0 KiB
TypeScript
198 lines
9.0 KiB
TypeScript
// Imported from investidor/resources/js/modules/news/sections/about/AboutStory.tsx; original content preserved.
|
|
import { useState, useEffect, useRef } from 'react';
|
|
import { Trans } from './source-text';
|
|
|
|
const aboutimgstory = '/assets/imgs/aboutimgstory.png';
|
|
|
|
interface CounterProps {
|
|
end: number;
|
|
suffix?: string;
|
|
}
|
|
|
|
const Counter = ({ end, suffix = '' }: CounterProps) => {
|
|
const [count, setCount] = useState<number>(0);
|
|
const countRef = useRef<number>(0);
|
|
|
|
useEffect(() => {
|
|
const duration = 2000;
|
|
const increment = end / (duration / 16);
|
|
|
|
const timer = setInterval(() => {
|
|
countRef.current += increment;
|
|
if (countRef.current >= end) {
|
|
clearInterval(timer);
|
|
countRef.current = end;
|
|
}
|
|
setCount(Math.floor(countRef.current));
|
|
}, 16);
|
|
|
|
return () => clearInterval(timer);
|
|
}, [end]);
|
|
|
|
return (
|
|
<span>
|
|
{count}
|
|
{suffix}
|
|
</span>
|
|
);
|
|
};
|
|
|
|
export const AboutStory = () => {
|
|
const [isVisible, setIsVisible] = useState<boolean>(false);
|
|
const [counted, setCounted] = useState<boolean>(false);
|
|
const sectionRef = useRef<HTMLDivElement>(null);
|
|
|
|
useEffect(() => {
|
|
const observer = new IntersectionObserver(
|
|
([entry]) => {
|
|
if (entry.isIntersecting) {
|
|
setIsVisible(true);
|
|
setCounted(true);
|
|
}
|
|
},
|
|
{ threshold: 0.2 },
|
|
);
|
|
|
|
if (sectionRef.current) {
|
|
observer.observe(sectionRef.current);
|
|
}
|
|
|
|
return () => {
|
|
if (sectionRef.current) {
|
|
observer.unobserve(sectionRef.current);
|
|
}
|
|
};
|
|
}, []);
|
|
|
|
return (
|
|
<section
|
|
ref={sectionRef}
|
|
className={`bg-primary px-6 transition-all duration-1000 md:px-12 lg:px-20 ${
|
|
isVisible
|
|
? 'translate-y-0 opacity-100'
|
|
: 'translate-y-10 opacity-0'
|
|
}`}
|
|
>
|
|
<div className="mx-auto max-w-6xl">
|
|
<div className="grid grid-cols-1 items-stretch gap-x-12 gap-y-2 lg:grid-cols-2">
|
|
{/* Imagem */}
|
|
<div
|
|
className={`relative transition-all delay-200 duration-1000 ${
|
|
isVisible
|
|
? 'translate-x-0 opacity-100'
|
|
: '-translate-x-12 opacity-0'
|
|
}`}
|
|
>
|
|
<div className="group relative h-64 overflow-hidden rounded-2xl md:h-72">
|
|
<img
|
|
src={aboutimgstory}
|
|
alt="Equipe Tempo"
|
|
className="h-full w-full object-cover transition-transform duration-1000 group-hover:scale-110"
|
|
onError={(e) => {
|
|
e.currentTarget.src =
|
|
'/assets/images/info.png';
|
|
}}
|
|
/>
|
|
<div className="pointer-events-none absolute inset-0 bg-black/12" />
|
|
|
|
<div className="absolute right-4 bottom-4 left-4">
|
|
<div className="flex flex-col gap-4 sm:flex-row sm:items-end sm:gap-8">
|
|
<div className="rounded-xl bg-black/20 p-3 backdrop-blur-sm transition-all sm:bg-transparent sm:p-0 sm:backdrop-blur-none">
|
|
<div
|
|
className="text-4xl font-black tracking-tighter text-white md:text-6xl"
|
|
style={{
|
|
textShadow:
|
|
'0 4px 12px rgba(0,0,0,0.95), 0 2px 6px rgba(0,0,0,0.9)',
|
|
}}
|
|
>
|
|
{counted ? (
|
|
<Counter end={50} suffix="+" />
|
|
) : (
|
|
'50+'
|
|
)}
|
|
</div>
|
|
<div
|
|
className="mt-1 text-xs font-bold tracking-widest text-white uppercase opacity-90 md:text-lg"
|
|
style={{
|
|
textShadow:
|
|
'0 3px 10px rgba(0,0,0,0.9), 0 1px 4px black',
|
|
}}
|
|
>
|
|
<Trans>Anos de Experiência</Trans>
|
|
</div>
|
|
</div>
|
|
<div className="rounded-xl bg-black/20 p-3 backdrop-blur-sm transition-all sm:bg-transparent sm:p-0 sm:backdrop-blur-none">
|
|
<div
|
|
className="text-4xl font-black tracking-tighter text-[#ED1C24] md:text-6xl"
|
|
style={{
|
|
textShadow:
|
|
'0 4px 12px rgba(0,0,0,0.95), 0 2px 6px rgba(0,0,0,0.9)',
|
|
}}
|
|
>
|
|
{counted ? (
|
|
<Counter end={200} suffix="+" />
|
|
) : (
|
|
'200+'
|
|
)}
|
|
</div>
|
|
<div
|
|
className="mt-1 text-xs font-bold tracking-widest text-white uppercase opacity-90 md:text-lg"
|
|
style={{
|
|
textShadow:
|
|
'0 3px 10px rgba(0,0,0,0.9), 0 1px 4px black',
|
|
}}
|
|
>
|
|
<Trans>Projetos Realizados</Trans>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div
|
|
className={`absolute -right-6 -bottom-6 -z-10 h-32 w-32 rounded-2xl border-2 border-red-600/30 transition-all delay-500 duration-1000 ${
|
|
isVisible
|
|
? 'scale-100 opacity-100'
|
|
: 'scale-0 opacity-0'
|
|
}`}
|
|
/>
|
|
</div>
|
|
|
|
{/* Texto */}
|
|
<div
|
|
className={`flex flex-col justify-center space-y-4 transition-all delay-500 duration-1000 ${
|
|
isVisible
|
|
? 'translate-x-0 opacity-100'
|
|
: '-translate-x-12 opacity-0'
|
|
}`}
|
|
>
|
|
<p className="text-base leading-relaxed font-light text-white md:text-lg">
|
|
<Trans>
|
|
Somos detentores de um vasto património cultural
|
|
e tecnológico, resultado da integração e da
|
|
cooperação entre diversas empresas com ampla
|
|
experiência nas áreas de Tecnologias de
|
|
Informação e Comunicação, produção e
|
|
disseminação de conteúdos informativos, educação
|
|
vocacional e gestão empresarial.
|
|
</Trans>
|
|
</p>
|
|
<p className="text-base leading-relaxed font-light text-white md:text-lg">
|
|
<Trans>
|
|
Dispomos de uma equipa qualificada, com sólida
|
|
experiência na concepção e implementação de
|
|
soluções de TI, de cibersegurança, de
|
|
desenvolvimento institucional, de reengenharia
|
|
de processos organizacionais e de formação
|
|
profissional.
|
|
</Trans>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|
|
|
|
export default AboutStory;
|