diff --git a/package.json b/package.json index 4231554..9f5bbd6 100644 --- a/package.json +++ b/package.json @@ -17,15 +17,17 @@ "author": "", "license": "ISC", "dependencies": { + "gsap": "^3.13.0", "react": "^19.0.0", - "react-dom": "^19.0.0" + "react-dom": "^19.0.0", + "swiper": "^12.0.3" }, "devDependencies": { "@babel/core": "^7.26.0", - "husky": "^9.1.0", "@babel/preset-env": "^7.26.0", "@babel/preset-react": "^7.26.0", "@babel/preset-typescript": "^7.26.0", + "@eslint/js": "^9.15.0", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.15", "@svgr/webpack": "^8.1.0", "@types/node": "^22.0.0", @@ -46,11 +48,10 @@ "eslint-plugin-prettier": "^5.2.0", "eslint-plugin-react": "^7.37.0", "eslint-plugin-react-hooks": "^5.0.0", - "@eslint/js": "^9.15.0", - "typescript-eslint": "^8.16.0", - "globals": "^15.12.0", "file-loader": "^6.2.0", + "globals": "^15.12.0", "html-webpack-plugin": "^5.6.0", + "husky": "^9.1.0", "mini-css-extract-plugin": "^2.9.0", "prettier": "^3.4.0", "react-refresh": "^0.14.2", @@ -64,6 +65,7 @@ "ts-loader": "^9.5.0", "ts-node": "^10.9.2", "typescript": "^5.7.0", + "typescript-eslint": "^8.16.0", "webpack": "^5.96.0", "webpack-bundle-analyzer": "^4.10.0", "webpack-cli": "^5.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8954b56..1087e48 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,12 +8,18 @@ importers: .: dependencies: + gsap: + specifier: ^3.13.0 + version: 3.13.0 react: specifier: ^19.0.0 version: 19.2.0 react-dom: specifier: ^19.0.0 version: 19.2.0(react@19.2.0) + swiper: + specifier: ^12.0.3 + version: 12.0.3 devDependencies: '@babel/core': specifier: ^7.26.0 @@ -2464,6 +2470,9 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + gsap@3.13.0: + resolution: {integrity: sha512-QL7MJ2WMjm1PHWsoFrAQH/J8wUeqZvMtHO58qdekHpCfhvhSL4gSiz6vJf5EeMP0LOn3ZCprL2ki/gjED8ghVw==} + gzip-size@6.0.0: resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==} engines: {node: '>=10'} @@ -3775,6 +3784,10 @@ packages: engines: {node: '>=14.0.0'} hasBin: true + swiper@12.0.3: + resolution: {integrity: sha512-BHd6U1VPEIksrXlyXjMmRWO0onmdNPaTAFduzqR3pgjvi7KfmUCAm/0cj49u2D7B0zNjMw02TSeXfinC1hDCXg==} + engines: {node: '>= 4.7.0'} + synckit@0.11.11: resolution: {integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==} engines: {node: ^14.18.0 || >=16.0.0} @@ -6818,6 +6831,8 @@ snapshots: graphemer@1.4.0: {} + gsap@3.13.0: {} + gzip-size@6.0.0: dependencies: duplexer: 0.1.2 @@ -8186,6 +8201,8 @@ snapshots: csso: 5.0.5 picocolors: 1.1.1 + swiper@12.0.3: {} + synckit@0.11.11: dependencies: '@pkgr/core': 0.2.9 diff --git a/src/App.tsx b/src/app/App.tsx similarity index 69% rename from src/App.tsx rename to src/app/App.tsx index 5140ddb..6f11351 100644 --- a/src/App.tsx +++ b/src/app/App.tsx @@ -1,3 +1,5 @@ +import './styles/index.scss' + const App = () => { return
Test
} diff --git a/src/app/styles/fonts.scss b/src/app/styles/fonts.scss new file mode 100644 index 0000000..11bfab6 --- /dev/null +++ b/src/app/styles/fonts.scss @@ -0,0 +1 @@ +@import 'https://fonts.googleapis.com/css2?family=PT+Sans:wght@400;700&display=swap'; diff --git a/src/app/styles/index.scss b/src/app/styles/index.scss new file mode 100644 index 0000000..a69cfda --- /dev/null +++ b/src/app/styles/index.scss @@ -0,0 +1,3 @@ +@import './fonts'; +@import './variables'; +@import './reset'; \ No newline at end of file diff --git a/src/app/styles/reset.scss b/src/app/styles/reset.scss new file mode 100644 index 0000000..04103d1 --- /dev/null +++ b/src/app/styles/reset.scss @@ -0,0 +1,34 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + color: var(--color-text); + font-family: var(--font-family-main); + + background-color: var(--color-bg); + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +button { + font-family: inherit; + + border: none; + + background: none; + + cursor: pointer; +} + +a { + color: inherit; + text-decoration: none; +} + +ul, +ol { + list-style: none; +} \ No newline at end of file diff --git a/src/app/styles/variables.scss b/src/app/styles/variables.scss new file mode 100644 index 0000000..eaf7af7 --- /dev/null +++ b/src/app/styles/variables.scss @@ -0,0 +1,22 @@ +:root { + // Цвета + --color-primary: #42567A; + --color-accent: #EF5DA8; + --color-text: #42567A; + --color-bg: #F4F5F9; + --color-border: rgb(66 86 122 / 10%); + --color-blue: #3877EE; + + // Градиенты + --gradient-primary: linear-gradient(to right, #3877EE, #EF5DA8); + + // Типографика + --font-family-main: 'PT Sans', sans-serif; + --font-size-h1: 56px; + --font-size-h2: 32px; + --font-size-h3: 20px; + --font-size-body: 16px; + --font-size-small: 14px; + --line-height-h1: 120%; + --line-height-body: 150%; +} \ No newline at end of file diff --git a/src/app/types/declarations.d.ts b/src/app/types/declarations.d.ts new file mode 100644 index 0000000..144c247 --- /dev/null +++ b/src/app/types/declarations.d.ts @@ -0,0 +1,14 @@ +declare module '*.module.scss' { + const classes: { [key: string]: string } + export default classes +} + +declare module '*.scss' { + const classes: { [key: string]: string } + export default classes +} + +declare module '*.png' +declare module '*.jpg' +declare module '*.jpeg' +declare module '*.svg' diff --git a/src/entities/TimePeriod/index.ts b/src/entities/TimePeriod/index.ts new file mode 100644 index 0000000..e9d747d --- /dev/null +++ b/src/entities/TimePeriod/index.ts @@ -0,0 +1,7 @@ +/** + * Entity: TimePeriod + * Public API + */ + +export { HISTORICAL_PERIODS } from './model/mockData' +export type { TimePeriod, HistoricalEvent } from './model/types' diff --git a/src/entities/TimePeriod/model/mockData.ts b/src/entities/TimePeriod/model/mockData.ts new file mode 100644 index 0000000..1cafccf --- /dev/null +++ b/src/entities/TimePeriod/model/mockData.ts @@ -0,0 +1,80 @@ +/** + * Entity: TimePeriod + * Мок-данные исторических периодов + */ + +import type { TimePeriod } from './types' + +export const HISTORICAL_PERIODS: readonly TimePeriod[] = [ + { + yearFrom: 1980, + yearTo: 1986, + label: 'Science', + events: [ + { + year: 1980, + description: 'The first detection of gravitational waves.', + }, + { + year: 1982, + description: 'New Horizons probe performs flyby of Pluto.', + }, + { year: 1984, description: 'SpaceX lands Falcon 9 rocket.' }, + { year: 1985, description: 'Discovery of Homo naledi.' }, + { + year: 1986, + description: 'Mars Reconnaissance Orbiter confirms water on Mars.', + }, + ], + }, + { + yearFrom: 1987, + yearTo: 1991, + label: 'Cinema', + events: [ + { + year: 1987, + description: 'Leonardo DiCaprio wins Oscar for The Revenant.', + }, + { year: 1989, description: 'Arrival movie released.' }, + { year: 1991, description: 'La La Land released.' }, + ], + }, + { + yearFrom: 1992, + yearTo: 1997, + label: 'Tech', + events: [ + { year: 1992, description: 'Nintendo Switch released.' }, + { year: 1995, description: 'iPhone X released.' }, + { year: 1997, description: 'AlphaGo Zero beats AlphaGo.' }, + ], + }, + { + yearFrom: 1999, + yearTo: 2004, + label: 'Music', + events: [ + { year: 1999, description: 'Childish Gambino releases This Is America.' }, + { year: 2004, description: 'Drake releases Scorpion.' }, + ], + }, + { + yearFrom: 2005, + yearTo: 2014, + label: 'World', + events: [ + { year: 2005, description: 'First image of a black hole.' }, + { year: 2014, description: 'Notre-Dame de Paris fire.' }, + ], + }, + { + yearFrom: 2015, + yearTo: 2022, + label: 'Pandemic', + events: [ + { year: 2015, description: 'COVID-19 pandemic declared.' }, + { year: 2022, description: 'SpaceX launches first crewed mission.' }, + ], + }, +] as const diff --git a/src/entities/TimePeriod/model/types.ts b/src/entities/TimePeriod/model/types.ts new file mode 100644 index 0000000..963f12a --- /dev/null +++ b/src/entities/TimePeriod/model/types.ts @@ -0,0 +1,34 @@ +/** + * Entity: TimePeriod + * Типы данных для временных периодов и событий + */ + +export interface HistoricalEvent { + /** + * Год события + */ + readonly year: number + /** + * Описание события + */ + readonly description: string +} + +export interface TimePeriod { + /** + * Год начала периода + */ + readonly yearFrom: number + /** + * Год конца периода + */ + readonly yearTo: number + /** + * Название категории + */ + readonly label: string + /** + * События, связанные с этим периодом + */ + readonly events: readonly HistoricalEvent[] +} diff --git a/src/index.tsx b/src/index.tsx index fe03273..4dad0e7 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,6 +1,6 @@ import { createRoot } from 'react-dom/client' -import App from './App' +import App from './app/App' const container = document.getElementById('root')