mirror of
https://github.com/PeterMaquiran/tvone.git
synced 2026-04-18 15:27:52 +00:00
@@ -1,5 +1,8 @@
|
||||
"use client"; // Necessário para animações no Next.js App Router
|
||||
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
const recentes = [
|
||||
{
|
||||
@@ -401,79 +404,76 @@ export function TvoneNegocios() {
|
||||
|
||||
export function TvoneEscolhaEditor() {
|
||||
return (
|
||||
<section className="mx-auto w-full max-w-[1200px] px-4 pb-20">
|
||||
<section className="mx-auto w-full max-w-[1200px] px-4 pb-20 overflow-hidden">
|
||||
{/* HEADER */}
|
||||
<div className="mb-10 flex items-end justify-between border-b border-neutral-100 pb-6">
|
||||
<div className="max-w-[600px]">
|
||||
<h2 className="text-3xl font-bold tracking-tight text-neutral-900 md:text-4xl">
|
||||
Escolha do Editor
|
||||
</h2>
|
||||
<p className="mt-2 text-sm md:text-base text-neutral-500 leading-relaxed">
|
||||
Curadoria exclusiva das histórias mais impactantes do dia, selecionadas pela nossa redação.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<Link
|
||||
href="/escolhas"
|
||||
className="group flex items-center gap-1 text-sm font-semibold text-[#0066CC] transition-colors hover:text-[#004499] whitespace-nowrap mb-1"
|
||||
>
|
||||
<h2 className="text-3xl font-bold tracking-tight text-neutral-900 md:text-4xl">
|
||||
Escolha do Editor
|
||||
</h2>
|
||||
<Link href="/escolhas" className="group flex items-center gap-1 text-sm font-semibold text-[#0066CC]">
|
||||
Ver tudo
|
||||
<svg className="h-4 w-4 transition-transform group-hover:translate-x-0.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2.5}>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M9 5l7 7-7 7" />
|
||||
<path d="M9 5l7 7-7 7" />
|
||||
</svg>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* CONTAINER DE SCROLL:
|
||||
- flex e overflow-x-auto no mobile
|
||||
- md:grid no desktop
|
||||
- snap-x para efeito de 'imã' ao scrollar
|
||||
*/}
|
||||
<div className="no-scrollbar -mx-4 flex snap-x snap-mandatory overflow-x-auto px-4 gap-6 md:mx-0 md:grid md:grid-cols-3 md:overflow-x-visible md:gap-10">
|
||||
{editorChoice.map((item, index) => (
|
||||
{/* CONTAINER COM ANIMACÃO "WHILE IN VIEW" */}
|
||||
<motion.div
|
||||
initial={{ x: 80, opacity: 0 }}
|
||||
whileInView={{ x: 0, opacity: 1 }} // Dispara quando entra na viewport
|
||||
viewport={{ once: true, margin: "-100px" }} // Executa uma vez, 100px antes de chegar no centro
|
||||
transition={{
|
||||
type: "spring",
|
||||
stiffness: 200, // Aumentado de 50 para 200 (muito mais rápido)
|
||||
damping: 25, // Mantém o controle para não balançar demais
|
||||
mass: 0.5 // Reduzimos a massa para o objeto parecer mais leve
|
||||
}}
|
||||
className="no-scrollbar flex flex-col gap-10 md:flex-row md:overflow-x-auto md:snap-x md:snap-mandatory md:gap-8 md:pb-6"
|
||||
>
|
||||
{editorChoice.slice(0, 6).map((item, index) => (
|
||||
<article
|
||||
key={index}
|
||||
className="min-w-[85vw] snap-start flex flex-col gap-5 sm:min-w-[50vw] md:min-w-full"
|
||||
className={`group flex flex-col gap-5 md:min-w-[31%] md:snap-start
|
||||
${index >= 3 ? 'hidden md:flex' : 'flex'}`}
|
||||
>
|
||||
<div className="relative aspect-video overflow-hidden rounded-[24px] bg-neutral-100 shadow-sm transition-all duration-500 group-hover:shadow-md">
|
||||
<Image
|
||||
src={item.img}
|
||||
alt=""
|
||||
fill
|
||||
className="object-cover transition-transform duration-700 group-hover:scale-105"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="px-1">
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="text-[10px] font-bold uppercase tracking-wider text-blue-600">
|
||||
{item.category}
|
||||
</span>
|
||||
<span className="h-1 w-1 rounded-full bg-neutral-300" />
|
||||
<span className="text-[10px] font-semibold text-neutral-500 uppercase tracking-tight">
|
||||
{item.publishDate}
|
||||
</span>
|
||||
<Link href="#" className="block">
|
||||
<div className="relative aspect-video overflow-hidden rounded-[24px] bg-neutral-100 shadow-sm transition-all duration-500 group-hover:shadow-xl">
|
||||
<Image
|
||||
src={item.img}
|
||||
alt={item.title}
|
||||
fill
|
||||
className="object-cover transition-transform duration-700 group-hover:scale-105"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<h3 className="mt-3 text-xl font-bold leading-snug text-neutral-900 transition-colors group-hover:text-[#0066CC]">
|
||||
{item.title}
|
||||
</h3>
|
||||
<div className="mt-5 px-1">
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="text-[10px] font-bold uppercase tracking-wider text-blue-600">{item.category}</span>
|
||||
<span className="h-1 w-1 rounded-full bg-neutral-300" />
|
||||
<span className="text-[10px] font-semibold text-neutral-500 uppercase tracking-tight">{item.publishDate}</span>
|
||||
</div>
|
||||
|
||||
<p className="mt-3 line-clamp-2 text-sm leading-relaxed text-neutral-500">
|
||||
{item.description}
|
||||
</p>
|
||||
<h3 className="mt-3 text-xl font-bold leading-snug text-neutral-900 group-hover:text-[#0066CC] transition-colors">
|
||||
{item.title}
|
||||
</h3>
|
||||
|
||||
<p className="mt-3 line-clamp-2 text-sm leading-relaxed text-neutral-500">{item.description}</p>
|
||||
|
||||
<div className="mt-5 flex items-center gap-2 border-t border-neutral-50 pt-4">
|
||||
<svg className="h-3.5 w-3.5 text-neutral-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
<span className="text-[10px] font-bold uppercase text-neutral-400">
|
||||
{item.readTime} min de leitura
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="mt-5 flex items-center gap-2 border-t border-neutral-50 pt-4">
|
||||
<svg className="h-3.5 w-3.5 text-neutral-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
<span className="text-[10px] font-bold uppercase text-neutral-400">
|
||||
{item.readTime} min de leitura
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
"lint": "eslint"
|
||||
},
|
||||
"dependencies": {
|
||||
"framer-motion": "^12.38.0",
|
||||
"next": "16.2.1",
|
||||
"react": "19.2.4",
|
||||
"react-dom": "19.2.4"
|
||||
|
||||
Generated
+38
@@ -8,6 +8,9 @@ importers:
|
||||
|
||||
.:
|
||||
dependencies:
|
||||
framer-motion:
|
||||
specifier: ^12.38.0
|
||||
version: 12.38.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||
next:
|
||||
specifier: 16.2.1
|
||||
version: 16.2.1(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||
@@ -1130,6 +1133,20 @@ packages:
|
||||
resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
framer-motion@12.38.0:
|
||||
resolution: {integrity: sha512-rFYkY/pigbcswl1XQSb7q424kSTQ8q6eAC+YUsSKooHQYuLdzdHjrt6uxUC+PRAO++q5IS7+TamgIw1AphxR+g==}
|
||||
peerDependencies:
|
||||
'@emotion/is-prop-valid': '*'
|
||||
react: ^18.0.0 || ^19.0.0
|
||||
react-dom: ^18.0.0 || ^19.0.0
|
||||
peerDependenciesMeta:
|
||||
'@emotion/is-prop-valid':
|
||||
optional: true
|
||||
react:
|
||||
optional: true
|
||||
react-dom:
|
||||
optional: true
|
||||
|
||||
function-bind@1.1.2:
|
||||
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
|
||||
|
||||
@@ -1521,6 +1538,12 @@ packages:
|
||||
minimist@1.2.8:
|
||||
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
|
||||
|
||||
motion-dom@12.38.0:
|
||||
resolution: {integrity: sha512-pdkHLD8QYRp8VfiNLb8xIBJis1byQ9gPT3Jnh2jqfFtAsWUA3dEepDlsWe/xMpO8McV+VdpKVcp+E+TGJEtOoA==}
|
||||
|
||||
motion-utils@12.36.0:
|
||||
resolution: {integrity: sha512-eHWisygbiwVvf6PZ1vhaHCLamvkSbPIeAYxWUuL3a2PD/TROgE7FvfHWTIH4vMl798QLfMw15nRqIaRDXTlYRg==}
|
||||
|
||||
ms@2.1.3:
|
||||
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
||||
|
||||
@@ -3140,6 +3163,15 @@ snapshots:
|
||||
dependencies:
|
||||
is-callable: 1.2.7
|
||||
|
||||
framer-motion@12.38.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
|
||||
dependencies:
|
||||
motion-dom: 12.38.0
|
||||
motion-utils: 12.36.0
|
||||
tslib: 2.8.1
|
||||
optionalDependencies:
|
||||
react: 19.2.4
|
||||
react-dom: 19.2.4(react@19.2.4)
|
||||
|
||||
function-bind@1.1.2: {}
|
||||
|
||||
function.prototype.name@1.1.8:
|
||||
@@ -3506,6 +3538,12 @@ snapshots:
|
||||
|
||||
minimist@1.2.8: {}
|
||||
|
||||
motion-dom@12.38.0:
|
||||
dependencies:
|
||||
motion-utils: 12.36.0
|
||||
|
||||
motion-utils@12.36.0: {}
|
||||
|
||||
ms@2.1.3: {}
|
||||
|
||||
nanoid@3.3.11: {}
|
||||
|
||||
Reference in New Issue
Block a user