prod-site/src/views/projects/ui/ProjectsPage.tsx

73 lines
No EOL
2.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import { useState } from "react";
import { Header } from "@/widgets/header";
import { Footer } from "@/widgets/footer";
import { useInView } from "@/shared/hooks/useInView";
import { projects } from "@/shared/config/projects/projects";
import type { Project } from "@/shared/config/projects/types";
import { ProjectModal } from "@/widgets/project-modal";
import ProjectCard from "@/components/projects/ProjectCard";
import styles from "@/static/projects/projects-page.module.css";
const ProjectsPage = () => {
const [selected, setSelected] = useState<Project | null>(null);
const [headRef, headInView] = useInView<HTMLDivElement>(0.4);
const [gridRef, gridInView] = useInView<HTMLDivElement>(0.08);
const reveal = (visible: boolean) =>
`transition-all duration-700 ease-out will-change-transform ${
visible ? "opacity-100 translate-y-0" : "opacity-0 translate-y-8"
}`;
return (
<>
<Header />
<main className="relative flex flex-col">
<section className={styles.projectsPage} data-scroll-section>
<span className={styles.glow} aria-hidden="true" />
<span className={styles.ghost} aria-hidden="true">
{String(projects.length).padStart(2, "0")}
</span>
<div className="page-container relative z-10">
<div ref={headRef} className={styles.head}>
<p className={`${styles.eyebrow} ${reveal(headInView)}`}>
<span className={styles.rule} aria-hidden="true" />
проекты
</p>
<h1 className={`${styles.title} ${reveal(headInView)}`}>
Все <span className={styles.titleAccent}>работы</span>
</h1>
<p className={`${styles.count} ${reveal(headInView)}`}>
{String(projects.length).padStart(2, "0")} проектов под ключ
</p>
</div>
<div ref={gridRef} className={styles.grid}>
{projects.map((project, index) => (
<div
key={project.id}
className={reveal(gridInView)}
style={{ transitionDelay: `${index * 60}ms` }}
>
<ProjectCard project={project} onOpen={setSelected} />
</div>
))}
</div>
</div>
<ProjectModal project={selected} onClose={() => setSelected(null)} />
</section>
</main>
<Footer />
</>
);
};
export default ProjectsPage;