diff --git a/next.config.mjs b/next.config.mjs
index 3182a51..0058348 100644
--- a/next.config.mjs
+++ b/next.config.mjs
@@ -1,6 +1,6 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
- output: "export",
+ // output: "export",
trailingSlash: true,
distDir: "dist",
};
diff --git a/src/Projects/DesktopProjects.tsx b/src/Projects/DesktopProjects.tsx
new file mode 100644
index 0000000..1cb324d
--- /dev/null
+++ b/src/Projects/DesktopProjects.tsx
@@ -0,0 +1,36 @@
+import { Fragment } from "react";
+import ProjectsSection from "@components/ProjectsSection";
+import { IProject } from "../types/IProject";
+import { SortedProject } from "../types/SortedProject";
+
+interface IProjectsProps {
+ projects: IProject[];
+ projectLabels: (string | number)[];
+ sortedProjects: SortedProject | undefined;
+}
+
+const DesktopProjects = ({
+ projects,
+ projectLabels,
+ sortedProjects,
+}: IProjectsProps) => {
+ return (
+
+ {projectLabels.map((year) => {
+ const projects = (sortedProjects && sortedProjects.get(year)) ?? [];
+
+ return (
+
+ {projects.length !== 0 && (
+
+ )}
+
+ );
+ })}
+
+ );
+};
+
+export default DesktopProjects;
diff --git a/src/Projects/MobileProjects.tsx b/src/Projects/MobileProjects.tsx
new file mode 100644
index 0000000..296f9ba
--- /dev/null
+++ b/src/Projects/MobileProjects.tsx
@@ -0,0 +1,70 @@
+import { Fragment, useEffect, useLayoutEffect, useState } from "react";
+import MoreProjectButton from "@components/MoreProjectButton";
+import ProjectCard from "@components/ProjectCard";
+import { IProject } from "../types/IProject";
+import { SortedProject } from "../types/SortedProject";
+import LabelCard from "@components/LabelCart";
+import { getTime, getYear } from "date-fns";
+
+interface IProjectsProps {
+ projects: IProject[];
+ projectLabels: (string | number)[];
+ sortedProjects: SortedProject | undefined;
+}
+
+const MobileProjects = ({ sortedProjects }: IProjectsProps) => {
+ const [currentCount, setCurrentCount] = useState(5);
+ const [projects, setProjects] = useState([]);
+ let previosLabel: string | number = "";
+
+ useLayoutEffect(() => {
+ if (!sortedProjects) return;
+
+ const _projects = [];
+ const values = Array.from(sortedProjects.values());
+ for (let i = 0; i < values.length; i++) {
+ const pr = values[i];
+ for (let j = 0; j < pr.length; j++) {
+ _projects.push(pr[j]);
+ }
+ }
+
+ setProjects(_projects);
+ }, [sortedProjects]);
+
+ const handleShowMore = () => {
+ setCurrentCount((prev) => prev + 8);
+ };
+
+ return (
+
+ {projects.slice(0, currentCount).map((project, index) => {
+ const projectYear = getYear(project.releaseDate);
+ const label = project.stage !== 6 ? "В работе" : projectYear;
+ const projects = sortedProjects?.get(projectYear);
+ if (previosLabel === "") {
+ previosLabel = label;
+ }
+
+ if ((index === 0 || previosLabel !== label) && projects?.length !== 0) {
+ previosLabel = label;
+ return (
+ <>
+ {/*
*/}
+
+
+ >
+ );
+ }
+
+ return
;
+ })}
+
+ {projects.length > currentCount && (
+
+ )}
+
+ );
+};
+
+export default MobileProjects;
diff --git a/src/Projects/Projects.tsx b/src/Projects/Projects.tsx
new file mode 100644
index 0000000..631caf6
--- /dev/null
+++ b/src/Projects/Projects.tsx
@@ -0,0 +1,53 @@
+import { useState, useEffect } from "react";
+import Heading2 from "../components/Headings/Heading2";
+import { IProject } from "../types/IProject";
+import { SortedProject } from "../types/SortedProject";
+import DesktopProjects from "./DesktopProjects";
+import MobileProjects from "./MobileProjects";
+import api from "@utils/api";
+import { getProjectLabels } from "../calc/getProjectLabels";
+import { getSortedProjects } from "../calc/getSortedProjects";
+
+const Projects = () => {
+ const [projects, setProjects] = useState([]);
+ const [projectLabels, setProjectLabels] = useState<(string | number)[]>([]);
+ const [sortedProjects, setSortedProjects] = useState();
+
+ async function getProjects() {
+ try {
+ const _projects: IProject[] = await api.get("projects").json();
+ const _projectLabels = getProjectLabels(_projects);
+ const _sortedProjects = getSortedProjects(_projects);
+
+ setProjectLabels(_projectLabels);
+ setSortedProjects(_sortedProjects);
+ setProjects(_projects);
+ } catch (error) {
+ if (error instanceof Error) {
+ alert(`Error: ${error.message}`);
+ }
+ }
+ }
+
+ useEffect(() => {
+ getProjects();
+ }, []);
+
+ return (
+
+ Проекты
+
+
+
+ );
+};
+
+export default Projects;
diff --git a/src/app/page.tsx b/src/app/page.tsx
index 081ef97..515c758 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -35,6 +35,7 @@ import { motion } from "framer-motion";
import { Video } from "../types/Video";
import Reviews from "@components/Reviews";
import Histories from "@components/Histories";
+import Projects from "../Projects/Projects";
const VIDEOS_FEATURES: Video[] = [
{
@@ -99,56 +100,13 @@ const VIDEOS_FEATURES: Video[] = [
},
];
-function getSortedProjects(projects: IProject[]) {
- const sorted = [...projects].sort(
- (da, db) => getTime(db.releaseDate) - getTime(da.releaseDate)
- );
-
- const sortedProject: SortedProject = new Map();
-
- for (let i = 0; i < sorted.length; i++) {
- const project = sorted[i];
- const projectYear = getYear(project.releaseDate);
- const key = project.stage !== 6 ? "В работе" : projectYear;
-
- if (sortedProject.has(key)) {
- const prevProjects = sortedProject.get(key) as IProject[];
- const updatedProjects = [...prevProjects, project];
- sortedProject.set(key, updatedProjects);
- } else {
- const createdProjects = [project];
- sortedProject.set(key, createdProjects);
- }
- }
-
- return sortedProject;
-}
-
-function getProjectLabels(projects: IProject[]) {
- const projectYears: number[] = [];
-
- for (let i = 0; i < projects.length; i++) {
- const project = getYear(projects[i].releaseDate);
- if (projectYears.includes(project)) continue;
- projectYears.push(project);
- }
-
- projectYears.sort((a, b) => b - a);
-
- const projectLabels = ["В работе", ...projectYears];
-
- return projectLabels;
-}
-
export default function App() {
const [selectedVideo, setSelectedVideo] = useState(
"/videos/features/virtual_tour.mp4"
);
- const [projects, setProjects] = useState([]);
- const [projectLabels, setProjectLabels] = useState<(string | number)[]>([]);
- const [sortedProjects, setSortedProjects] = useState();
+
const [setModal] = useModalStore((state) => [state.setModal]);
- const [isShownAllProjects, setIsShownAllProjects] = useState(false);
+
const [isBuffering, setIsBuffering] = useState(true);
const [isViewportEntered, setIsViewportEntered] = useState(false);
@@ -158,26 +116,6 @@ export default function App() {
setIsViewportEntered(true);
};
- async function getProjects() {
- try {
- const _projects: IProject[] = await api.get("projects").json();
- const _projectLabels = getProjectLabels(_projects);
- const _sortedProjects = getSortedProjects(_projects);
-
- setProjectLabels(_projectLabels);
- setSortedProjects(_sortedProjects);
- setProjects(_projects);
- } catch (error) {
- if (error instanceof Error) {
- alert(`Error: ${error.message}`);
- }
- }
- }
-
- useEffect(() => {
- getProjects();
- }, []);
-
return (
@@ -674,45 +612,7 @@ export default function App() {
-
-
-
Проекты
-
- {projectLabels.map((year) => {
- const projects =
- (sortedProjects && sortedProjects.get(year)) ?? [];
-
- return (
-
- {projects.length !== 0 && (
-
- )}
-
- );
- })}
-
-
- {[...Array.from({ length: 5 })].map((_, index) => (
-
- ))}
- {!isShownAllProjects ? (
-
setIsShownAllProjects(true)}
- />
- ) : (
- <>
- {projects.map(
- (_, index) =>
- projects[index + 5] && (
-
- )
- )}
- >
- )}
-
-
+
diff --git a/src/calc/getProjectLabels.ts b/src/calc/getProjectLabels.ts
new file mode 100644
index 0000000..9df5515
--- /dev/null
+++ b/src/calc/getProjectLabels.ts
@@ -0,0 +1,20 @@
+import { getYear } from "date-fns";
+import { IProject } from "../types/IProject";
+
+function getProjectLabels(projects: IProject[]) {
+ const projectYears: number[] = [];
+
+ for (let i = 0; i < projects.length; i++) {
+ const year = getYear(projects[i].releaseDate);
+ if (projectYears.includes(year)) continue;
+ projectYears.push(year);
+ }
+
+ projectYears.sort((a, b) => b - a);
+
+ const projectLabels = ["В работе", ...projectYears];
+
+ return projectLabels;
+}
+
+export { getProjectLabels };
diff --git a/src/calc/getSortedProjects.ts b/src/calc/getSortedProjects.ts
new file mode 100644
index 0000000..1b32e60
--- /dev/null
+++ b/src/calc/getSortedProjects.ts
@@ -0,0 +1,30 @@
+import { getTime, getYear } from "date-fns";
+import { IProject } from "../types/IProject";
+import { SortedProject } from "../types/SortedProject";
+
+function getSortedProjects(projects: IProject[]) {
+ const sorted = [...projects].sort(
+ (da, db) => getTime(db.releaseDate) - getTime(da.releaseDate)
+ );
+
+ const sortedProject: SortedProject = new Map();
+
+ for (let i = 0; i < sorted.length; i++) {
+ const project = sorted[i];
+ const projectYear = getYear(project.releaseDate);
+ const key = project.stage !== 6 ? "В работе" : projectYear;
+
+ if (sortedProject.has(key)) {
+ const prevProjects = sortedProject.get(key) as IProject[];
+ const updatedProjects = [...prevProjects, project];
+ sortedProject.set(key, updatedProjects);
+ } else {
+ const createdProjects = [project];
+ sortedProject.set(key, createdProjects);
+ }
+ }
+
+ return sortedProject;
+}
+
+export { getSortedProjects };
diff --git a/src/components/CardYear.tsx b/src/components/LabelCart.tsx
similarity index 66%
rename from src/components/CardYear.tsx
rename to src/components/LabelCart.tsx
index e974e76..19f6bcd 100644
--- a/src/components/CardYear.tsx
+++ b/src/components/LabelCart.tsx
@@ -3,7 +3,7 @@ interface LabelCardProps {
}
const LabelCard = ({ label }: LabelCardProps): JSX.Element => {
- return {label}
;
+ return {label}
;
};
export default LabelCard;
diff --git a/src/components/MoreProjectButton.tsx b/src/components/MoreProjectButton.tsx
index 8188dee..d99a92c 100644
--- a/src/components/MoreProjectButton.tsx
+++ b/src/components/MoreProjectButton.tsx
@@ -13,7 +13,7 @@ function MoreProjectButton({ onClick }: IMoreProjectButtonProps) {
whileInView={{ opacity: 1 }}
viewport={{ once: true, margin: "-100px" }}
transition={{ duration: 1, ease: [0.58, 0.12, 0.27, 0.98], delay: 0.2 }}
- className="border border-[#3D425C] p-4 flex sm:flex-col sm:justify-end items-end gap-2 sm:rounded-none rounded-full"
+ className="border border-[#3D425C] p-4 flex sm:flex-col sm:justify-end items-end gap-2 sm:rounded-none rounded-full aspect-square"
onClick={onClick}
>
diff --git a/src/components/ProjectsSection.tsx b/src/components/ProjectsSection.tsx
index cc2de75..4419f56 100644
--- a/src/components/ProjectsSection.tsx
+++ b/src/components/ProjectsSection.tsx
@@ -1,5 +1,5 @@
import { IProject } from "../types/IProject";
-import LabelCard from "./CardYear";
+import LabelCard from "./LabelCart";
import ProjectCard from "./ProjectCard";
type ProjectYearSectionProps = {
diff --git a/src/types/IProject.ts b/src/types/IProject.ts
index df4f3ee..a6dfa79 100644
--- a/src/types/IProject.ts
+++ b/src/types/IProject.ts
@@ -1,7 +1,7 @@
import Device from "./Device";
interface IProject {
- id?: string;
+ id: string;
name: string;
company: string;
city: string;
@@ -11,4 +11,4 @@ interface IProject {
devices: Device[];
}
-export type {IProject};
+export type { IProject };