├── .eslintrc.cjs ├── .gitignore ├── .npmrc ├── .prettierignore ├── .prettierrc ├── .stylelintrc.json ├── LICENSE ├── README.md ├── index.html ├── package.json ├── public └── vite.svg ├── src ├── App.tsx ├── Navigator.tsx ├── __tests__ │ ├── App.test.tsx │ └── setup.ts ├── api │ ├── client.ts │ ├── clientProxy.ts │ └── queue.ts ├── assets │ └── fonts │ │ ├── Axiforma │ │ ├── Axiforma-Black.eot │ │ ├── Axiforma-Black.ttf │ │ ├── Axiforma-Black.woff │ │ ├── Axiforma-Black.woff2 │ │ ├── Axiforma-BlackItalic.eot │ │ ├── Axiforma-BlackItalic.ttf │ │ ├── Axiforma-BlackItalic.woff │ │ ├── Axiforma-BlackItalic.woff2 │ │ ├── Axiforma-Bold.eot │ │ ├── Axiforma-Bold.ttf │ │ ├── Axiforma-Bold.woff │ │ ├── Axiforma-Bold.woff2 │ │ ├── Axiforma-BoldItalic.eot │ │ ├── Axiforma-BoldItalic.ttf │ │ ├── Axiforma-BoldItalic.woff │ │ ├── Axiforma-BoldItalic.woff2 │ │ ├── Axiforma-Book.eot │ │ ├── Axiforma-Book.ttf │ │ ├── Axiforma-Book.woff │ │ ├── Axiforma-Book.woff2 │ │ ├── Axiforma-BookItalic.eot │ │ ├── Axiforma-BookItalic.ttf │ │ ├── Axiforma-BookItalic.woff │ │ ├── Axiforma-BookItalic.woff2 │ │ ├── Axiforma-ExtraBold.eot │ │ ├── Axiforma-ExtraBold.ttf │ │ ├── Axiforma-ExtraBold.woff │ │ ├── Axiforma-ExtraBold.woff2 │ │ ├── Axiforma-ExtraBoldItalic.eot │ │ ├── Axiforma-ExtraBoldItalic.ttf │ │ ├── Axiforma-ExtraBoldItalic.woff │ │ ├── Axiforma-ExtraBoldItalic.woff2 │ │ ├── Axiforma-Heavy.eot │ │ ├── Axiforma-Heavy.ttf │ │ ├── Axiforma-Heavy.woff │ │ ├── Axiforma-Heavy.woff2 │ │ ├── Axiforma-HeavyItalic.eot │ │ ├── Axiforma-HeavyItalic.ttf │ │ ├── Axiforma-HeavyItalic.woff │ │ ├── Axiforma-HeavyItalic.woff2 │ │ ├── Axiforma-Italic.eot │ │ ├── Axiforma-Italic.ttf │ │ ├── Axiforma-Italic.woff │ │ ├── Axiforma-Italic.woff2 │ │ ├── Axiforma-Light.eot │ │ ├── Axiforma-Light.ttf │ │ ├── Axiforma-Light.woff │ │ ├── Axiforma-Light.woff2 │ │ ├── Axiforma-LightItalic.eot │ │ ├── Axiforma-LightItalic.ttf │ │ ├── Axiforma-LightItalic.woff │ │ ├── Axiforma-LightItalic.woff2 │ │ ├── Axiforma-Medium.eot │ │ ├── Axiforma-Medium.ttf │ │ ├── Axiforma-Medium.woff │ │ ├── Axiforma-Medium.woff2 │ │ ├── Axiforma-MediumItalic.eot │ │ ├── Axiforma-MediumItalic.ttf │ │ ├── Axiforma-MediumItalic.woff │ │ ├── Axiforma-MediumItalic.woff2 │ │ ├── Axiforma-Regular.eot │ │ ├── Axiforma-Regular.ttf │ │ ├── Axiforma-Regular.woff │ │ ├── Axiforma-Regular.woff2 │ │ ├── Axiforma-SemiBold.eot │ │ ├── Axiforma-SemiBold.ttf │ │ ├── Axiforma-SemiBold.woff │ │ ├── Axiforma-SemiBold.woff2 │ │ ├── Axiforma-SemiBoldItalic.eot │ │ ├── Axiforma-SemiBoldItalic.ttf │ │ ├── Axiforma-SemiBoldItalic.woff │ │ ├── Axiforma-SemiBoldItalic.woff2 │ │ ├── Axiforma-Thin.eot │ │ ├── Axiforma-Thin.ttf │ │ ├── Axiforma-Thin.woff │ │ ├── Axiforma-Thin.woff2 │ │ ├── Axiforma-ThinItalic.eot │ │ ├── Axiforma-ThinItalic.ttf │ │ ├── Axiforma-ThinItalic.woff │ │ ├── Axiforma-ThinItalic.woff2 │ │ └── typography.css │ │ └── Poppins │ │ ├── Poppins-Black.eot │ │ ├── Poppins-Black.ttf │ │ ├── Poppins-Black.woff │ │ ├── Poppins-Black.woff2 │ │ ├── Poppins-BlackItalic.eot │ │ ├── Poppins-BlackItalic.ttf │ │ ├── Poppins-BlackItalic.woff │ │ ├── Poppins-BlackItalic.woff2 │ │ ├── Poppins-Bold.eot │ │ ├── Poppins-Bold.ttf │ │ ├── Poppins-Bold.woff │ │ ├── Poppins-Bold.woff2 │ │ ├── Poppins-BoldItalic.eot │ │ ├── Poppins-BoldItalic.ttf │ │ ├── Poppins-BoldItalic.woff │ │ ├── Poppins-BoldItalic.woff2 │ │ ├── Poppins-ExtraBold.eot │ │ ├── Poppins-ExtraBold.ttf │ │ ├── Poppins-ExtraBold.woff │ │ ├── Poppins-ExtraBold.woff2 │ │ ├── Poppins-ExtraBoldItalic.eot │ │ ├── Poppins-ExtraBoldItalic.ttf │ │ ├── Poppins-ExtraBoldItalic.woff │ │ ├── Poppins-ExtraBoldItalic.woff2 │ │ ├── Poppins-ExtraLight.eot │ │ ├── Poppins-ExtraLight.ttf │ │ ├── Poppins-ExtraLight.woff │ │ ├── Poppins-ExtraLight.woff2 │ │ ├── Poppins-ExtraLightItalic.eot │ │ ├── Poppins-ExtraLightItalic.ttf │ │ ├── Poppins-ExtraLightItalic.woff │ │ ├── Poppins-ExtraLightItalic.woff2 │ │ ├── Poppins-Italic.eot │ │ ├── Poppins-Italic.ttf │ │ ├── Poppins-Italic.woff │ │ ├── Poppins-Italic.woff2 │ │ ├── Poppins-Light.eot │ │ ├── Poppins-Light.ttf │ │ ├── Poppins-Light.woff │ │ ├── Poppins-Light.woff2 │ │ ├── Poppins-LightItalic.eot │ │ ├── Poppins-LightItalic.ttf │ │ ├── Poppins-LightItalic.woff │ │ ├── Poppins-LightItalic.woff2 │ │ ├── Poppins-Medium.eot │ │ ├── Poppins-Medium.ttf │ │ ├── Poppins-Medium.woff │ │ ├── Poppins-Medium.woff2 │ │ ├── Poppins-MediumItalic.eot │ │ ├── Poppins-MediumItalic.ttf │ │ ├── Poppins-MediumItalic.woff │ │ ├── Poppins-MediumItalic.woff2 │ │ ├── Poppins-Regular.eot │ │ ├── Poppins-Regular.ttf │ │ ├── Poppins-Regular.woff │ │ ├── Poppins-Regular.woff2 │ │ ├── Poppins-SemiBold.eot │ │ ├── Poppins-SemiBold.ttf │ │ ├── Poppins-SemiBold.woff │ │ ├── Poppins-SemiBold.woff2 │ │ ├── Poppins-SemiBoldItalic.eot │ │ ├── Poppins-SemiBoldItalic.ttf │ │ ├── Poppins-SemiBoldItalic.woff │ │ ├── Poppins-SemiBoldItalic.woff2 │ │ ├── Poppins-Thin.eot │ │ ├── Poppins-Thin.ttf │ │ ├── Poppins-Thin.woff │ │ ├── Poppins-Thin.woff2 │ │ ├── Poppins-ThinItalic.eot │ │ ├── Poppins-ThinItalic.ttf │ │ ├── Poppins-ThinItalic.woff │ │ ├── Poppins-ThinItalic.woff2 │ │ └── typography.css ├── components │ ├── Icon.tsx │ ├── layout │ │ └── Header │ │ │ ├── Header.module.pcss │ │ │ └── Header.tsx │ └── screens │ │ └── AppScreen │ │ ├── AppScreen.module.pcss │ │ ├── AppScreen.module.pcss.d.ts │ │ └── AppScreen.tsx ├── constants │ ├── animations.ts │ ├── config.ts │ └── routes.ts ├── hooks │ └── useTracking.tsx ├── i18n │ ├── I18nextProvider.tsx │ ├── languages.ts │ └── translations │ │ └── en.ts ├── main.tsx ├── stylesheets │ ├── App.css │ ├── App.css.d.ts │ ├── index.css │ └── index.css.d.ts ├── types │ └── TrackEventProps.d.ts └── utils │ ├── cookies.ts │ ├── copyToClipboard.ts │ ├── debounceThrottle.ts │ ├── errors.ts │ ├── formatting.ts │ ├── initPosthog.ts │ ├── localStorage.ts │ ├── objectUtils.ts │ ├── retryRequest.ts │ ├── storage.ts │ └── validation.ts ├── tsconfig.json ├── tsconfig.node.json ├── vite.config.ts └── vitest.config.ts /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "env": { 3 | "browser": true, 4 | "es2021": true 5 | }, 6 | "extends": [ 7 | "plugin:react/recommended", 8 | "standard-with-typescript", 9 | "prettier", 10 | ], 11 | "overrides": [ 12 | ], 13 | "parserOptions": { 14 | "ecmaVersion": "latest", 15 | "sourceType": "module" 16 | }, 17 | "plugins": [ 18 | "react", 19 | "prettier" 20 | 21 | ], 22 | "rules": { 23 | "@typescript-eslint/restrict-plus-operands": "off", 24 | "@typescript-eslint/no-unsafe-argument": "off", 25 | "@typescript-eslint/no-misused-promises": "off", 26 | "@typescript-eslint/explicit-function-return-type": "off", 27 | "@typescript-eslint/strict-boolean-expressions": "off", 28 | "@typescript-eslint/naming-convention": [ 29 | "error", 30 | { 31 | "selector": "parameter", 32 | "format": ["camelCase", "PascalCase", "UPPER_CASE", "snake_case"], 33 | "leadingUnderscore": "allow" 34 | } 35 | ], 36 | "@typescript-eslint/no-floating-promises": "off", 37 | "@typescript-eslint/no-unused-vars": ["warn"], 38 | "@typescript-eslint/no-non-null-assertion": "off", 39 | "@typescript-eslint/prefer-nullish-coalescing": "off", 40 | "@typescript-eslint/no-non-null-asserted-optional-chain": "warn", 41 | "@typescript-eslint/no-empty-interface": "warn", 42 | "@typescript-eslint/no-invalid-void-type": "warn", 43 | "@typescript-eslint/ban-types": "warn", 44 | "react/react-in-jsx-scope": "off", 45 | "react/prop-types": "off", 46 | "react/display-name": "warn", 47 | "react/jsx-key": "warn", 48 | "react/no-unescaped-entities": "off", 49 | "no-prototype-builtins": "off", 50 | "n/handle-callback-err" : "off", 51 | "no-case-declarations": "warn", 52 | 53 | }, 54 | "settings": { 55 | "react": { 56 | "version": "detect" 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # dependencies 3 | /node_modules 4 | /.pnp 5 | .pnp.js 6 | 7 | pnpm-lock.yaml 8 | 9 | # testing 10 | /coverage 11 | 12 | # production 13 | /build 14 | /dist 15 | 16 | # misc 17 | .DS_Store 18 | .env.local 19 | .env.development.local 20 | .env.test.local 21 | .env.production.local 22 | 23 | ### macOS.gitignore 24 | # General 25 | .AppleDouble 26 | .LSOverride 27 | 28 | # Icon must end with two \r 29 | Icon 30 | # Thumbnails 31 | ._* 32 | 33 | # Files that might appear in the root of a volume 34 | .DocumentRevisions-V100 35 | .fseventsd 36 | .Spotlight-V100 37 | .TemporaryItems 38 | .Trashes 39 | .VolumeIcon.icns 40 | .com.apple.timemachine.donotpresent 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | 49 | # Logs 50 | logs 51 | *.log 52 | npm-debug.log* 53 | yarn-debug.log* 54 | yarn-error.log* 55 | pnpm-debug.log* 56 | lerna-debug.log* 57 | 58 | node_modules 59 | dist 60 | dist-ssr 61 | *.local 62 | 63 | # Editor directories and files 64 | .idea 65 | .idea/* 66 | .vscode/* 67 | !.vscode/extensions.json 68 | *.suo 69 | *.ntvs* 70 | *.njsproj 71 | *.sln 72 | *.sw? 73 | 74 | .stylelintcache 75 | .env 76 | 77 | *.lockb 78 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | shamefully-hoist=true 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all", 4 | "semi": false, 5 | "bracketSameLine": false, 6 | "printWidth": 180, 7 | "tabWidth": 1, 8 | "useTabs": true, 9 | "arrowParens": "avoid", 10 | "endOfLine": "auto", 11 | "overrides": [ 12 | { 13 | "files": "*.json", 14 | "options": { 15 | "printWidth": 200 16 | } 17 | } 18 | ] 19 | } 20 | 21 | -------------------------------------------------------------------------------- /.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "stylelint-config-prettier", 4 | "stylelint-config-recommended-scss" 5 | ], 6 | "rules": { 7 | "at-rule-no-unknown": null, 8 | "color-named": "never", 9 | "color-hex-length": "long", 10 | "function-disallowed-list": [ 11 | "rgb", 12 | "hsl" 13 | ], 14 | "declaration-block-no-duplicate-properties": [ 15 | true, 16 | { 17 | "ignore": [ 18 | "consecutive-duplicates-with-different-values" 19 | ] 20 | } 21 | ], 22 | "declaration-empty-line-before": null, 23 | "declaration-property-unit-allowed-list": { 24 | "/^border(?!.*-radius$)/": [ 25 | "px", 26 | "%" 27 | ], 28 | "/^border-radius/": [ 29 | "px", 30 | "rem", 31 | "%" 32 | ], 33 | "/^box-shadow": [ 34 | "px" 35 | ], 36 | "/^margin/": [ 37 | "rem", 38 | "px" 39 | ], 40 | "/^padding/": [ 41 | "rem", 42 | "px" 43 | ], 44 | "font-size": [ 45 | "rem", 46 | "em", 47 | "px" 48 | ], 49 | "height": [ 50 | "rem", 51 | "%", 52 | "vh", 53 | "px" 54 | ], 55 | "width": [ 56 | "rem", 57 | "%", 58 | "vw", 59 | "px" 60 | ] 61 | }, 62 | "max-empty-lines": 1, 63 | "no-duplicate-selectors": true, 64 | "selector-class-pattern": [ 65 | "^[a-z0-9-]+(__[a-z0-9-]+)?(--[a-z0-9-]+)?$", 66 | { 67 | "message": "Please follow BEM naming conventions", 68 | "resolveNestedSelectors": true 69 | } 70 | ], 71 | "selector-max-compound-selectors": [ 72 | 1, 73 | { 74 | "message": "Descendent selectors break encapsulation and are bad for performance. Please try using BEM class names instead and nesting/combining them with &", 75 | "severity": "warning" 76 | } 77 | ], 78 | "selector-max-id": [ 79 | 0 80 | ], 81 | "string-quotes": "single", 82 | "value-no-vendor-prefix": true, 83 | "font-family-no-missing-generic-family-keyword": null, 84 | "no-descending-specificity": null, 85 | "selector-pseudo-class-no-unknown": [ 86 | true, 87 | { 88 | "ignorePseudoClasses": [ 89 | "global" 90 | ] 91 | } 92 | ], 93 | "no-invalid-position-at-import-rule": null, 94 | "rule-empty-line-before": null, 95 | "selector-no-vendor-prefix": null, 96 | "alpha-value-notation": null, 97 | "color-function-notation": null, 98 | "value-keyword-case": null, 99 | "shorthand-property-no-redundant-values": null, 100 | "declaration-block-no-redundant-longhand-properties": null, 101 | "keyframes-name-pattern": null, 102 | "number-max-precision": null, 103 | "property-no-vendor-prefix": null 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Oleg Kron 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Vite+React Template 🚀

2 |

Built with PostCSS, EsLint, Prettier, Husky & Vitest

3 |
4 | 5 | [![Stars](https://img.shields.io/github/stars/olegkron/vite-ts-react-template.svg?style=social)](https://github.com/olegkron/vite-ts-react-template/stargazers) [![Forks](https://img.shields.io/github/forks/olegkron/vite-ts-react-template.svg?style=social)](https://github.com/username/repo/network/members) [![Contributors](https://img.shields.io/github/contributors/olegkron/vite-ts-react-template.svg)](https://github.com/olegkron/vite-ts-react-template/graphs/contributors) [![Issues](https://img.shields.io/github/issues/olegkron/vite-ts-react-template.svg)](https://github.com/olegkron/vite-ts-react-template/issues) [![MIT License](https://img.shields.io/github/license/olegkron/vite-ts-react-template.svg)](https://github.com/olegkron/vite-ts-react-template/blob/main/LICENSE) 6 | 7 |
8 | Kickstart your React projects with this feature-packed Vite-powered React TypeScript template. 9 | 10 | ## 🔥 Features 11 | 12 | - 🔷 React with TypeScript 13 | - 🚀 Vite as the build tool and development server 14 | - 🔄 Queue-based API calls with Axios 15 | - 🎨 PostCSS 16 | - 🧪 Jest and React Testing Library 17 | - 📐 ESLint and Prettier 18 | - 🐶 Husky pre-commit hooks 19 | - 📂 Pre-configured folder structure for components, hooks, tests, and more 20 | - 🔧 Built-in utilities for error handling, API calls, data formatting, validation, etc. 21 | - 🚦 Basic routing and navigation setup 22 | 23 | ## 🙌 Contributing 24 | 25 | Your contributions are always welcome and appreciated! 26 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React + TS 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vite-ts-react-template", 3 | "private": true, 4 | "version": "1.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "start": "npx vite", 8 | "dev": "npx vite", 9 | "build": "npx vite build", 10 | "lint": "npx eslint src --ext ts,tsx", 11 | "lint:fix": "npx eslint src --ext ts,tsx --fix ", 12 | "lint:css": "npx stylelint \"src/**/*.{css,pcss}\" --fix", 13 | "format": "npx prettier --write \"src/**/*.{ts,tsx,js,jsx,json,md,css,pcss}\"", 14 | "preview": "npx vite preview", 15 | "test": "npx vitest --run" 16 | }, 17 | "dependencies": { 18 | "@tabler/icons-react": "^2.46.0", 19 | "axios": "^1.6.6", 20 | "dayjs": "^1.11.10", 21 | "posthog-js": "^1.102.0", 22 | "react": "^18.2.0", 23 | "react-dom": "^18.2.0", 24 | "react-router-dom": "^6.21.3" 25 | }, 26 | "devDependencies": { 27 | "@testing-library/jest-dom": "^6.3.0", 28 | "@testing-library/react": "^14.1.2", 29 | "@types/react": "^18.2.48", 30 | "@types/react-dom": "^18.2.18", 31 | "@typescript-eslint/eslint-plugin": "^6.19.1", 32 | "@vitejs/plugin-react": "^4.2.1", 33 | "@vitejs/plugin-react-swc": "^3.5.0", 34 | "eslint": "^8.56.0", 35 | "eslint-config-prettier": "^9.1.0", 36 | "eslint-config-standard-with-typescript": "^43.0.1", 37 | "eslint-plugin-import": "^2.29.1", 38 | "eslint-plugin-n": "^16.6.2", 39 | "eslint-plugin-prettier": "^5.1.3", 40 | "eslint-plugin-promise": "^6.1.1", 41 | "eslint-plugin-react": "^7.33.2", 42 | "jsdom": "^24.0.0", 43 | "postcss": "^8.4.33", 44 | "precss": "^4.0.0", 45 | "prettier": "^3.2.4", 46 | "stylelint": "^16.2.0", 47 | "stylelint-config-prettier": "^9.0.5", 48 | "stylelint-config-recommended-scss": "^14.0.0", 49 | "stylelint-config-standard": "^36.0.0", 50 | "vite": "^5.0.12", 51 | "vite-plugin-environment": "^1.1.3", 52 | "vite-plugin-stylelint": "^5.3.1", 53 | "vitest": "^1.2.1" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/App.tsx: -------------------------------------------------------------------------------- 1 | import './stylesheets/App.css' 2 | import { Navigator } from './Navigator' 3 | 4 | function App() { 5 | return 6 | } 7 | 8 | export default App 9 | -------------------------------------------------------------------------------- /src/Navigator.tsx: -------------------------------------------------------------------------------- 1 | import { type FC } from 'react' 2 | import { BrowserRouter, Routes } from 'react-router-dom' 3 | import { AppScreen } from './components/screens/AppScreen/AppScreen' 4 | import { Header } from './components/layout/Header/Header' 5 | 6 | export interface NavigatorProps {} 7 | 8 | export const Navigator: FC = () => ( 9 | 10 | 11 |
12 |

Vite + React template

13 |
Built with PostCss, Eslint, Prettier, Husky & Vitest
14 | {/* } /> */} 15 | 16 | 17 | ) 18 | -------------------------------------------------------------------------------- /src/__tests__/App.test.tsx: -------------------------------------------------------------------------------- 1 | import { render } from '@testing-library/react' 2 | 3 | describe(' component', () => { 4 | test('renders without crashing', () => { 5 | const { container } = render(

Vite + React template

) 6 | expect(container).toBeTruthy() 7 | }) 8 | 9 | // Add any additional tests specific to your App component here 10 | }) 11 | -------------------------------------------------------------------------------- /src/__tests__/setup.ts: -------------------------------------------------------------------------------- 1 | import '@testing-library/jest-dom' 2 | -------------------------------------------------------------------------------- /src/api/client.ts: -------------------------------------------------------------------------------- 1 | import axios, { type AxiosRequestConfig, type AxiosResponse } from 'axios' 2 | import { config } from '../constants/config' 3 | import queue from './queue' 4 | 5 | type GetParams = Record 6 | 7 | type PostData = Record 8 | 9 | const api = axios.create({ 10 | baseURL: config.baseURL, 11 | headers: config.headers, 12 | }) 13 | 14 | // Axios interceptor for adding authorization token to request headers. 15 | api.interceptors.request.use( 16 | (config: AxiosRequestConfig) => { 17 | const token = localStorage.getItem('token') 18 | if (token) { 19 | config.headers.Authorization = `Bearer ${token}` 20 | } 21 | return config 22 | }, 23 | async error => await Promise.reject(error), 24 | ) 25 | 26 | /** 27 | Performs a GET request to the specified URL with the given parameters. 28 | @param {string} url - The URL to send the GET request to. 29 | @param {GetParams} params - The parameters to send with the GET request. 30 | @returns {Promise} A promise that resolves with the response data if the request succeeds, or rejects with an error if it fails. 31 | */ 32 | export async function get(url: string, params: GetParams = {}): Promise { 33 | try { 34 | const response: AxiosResponse = await queue.add({ 35 | method: 'get', 36 | url: `${config.baseURL}${url}`, 37 | headers: config.headers, 38 | params, 39 | }) 40 | return response.data 41 | } catch (error) { 42 | console.error('GET request failed:', error) 43 | throw error 44 | } 45 | } 46 | 47 | /** 48 | Performs a POST request to the specified URL with the given data. 49 | @param {string} url - The URL to send the POST request to. 50 | @param {PostData} data - The data to send with the POST request. 51 | @returns {Promise} A promise that resolves with the response data if the request succeeds, or rejects with an error if it fails. 52 | */ 53 | export async function post(url: string, data: PostData): Promise { 54 | try { 55 | const response: AxiosResponse = await queue.add({ 56 | method: 'post', 57 | url: `${config.baseURL}${url}`, 58 | headers: config.headers, 59 | data, 60 | }) 61 | 62 | return response.data 63 | } catch (error) { 64 | console.error('POST request failed:', error) 65 | throw error 66 | } 67 | } 68 | 69 | /** 70 | Uploads an image file to the specified URL using a POST request. 71 | @param {string} url - The URL to send the POST request to. 72 | @param {File} imageFile - The image file to upload. 73 | @returns {Promise} A promise that resolves with the response data if the request succeeds, or rejects with an error if it fails. 74 | */ 75 | export async function imageUpload(url: string, imageFile: File): Promise { 76 | try { 77 | const formData = new FormData() 78 | formData.append('image', imageFile) 79 | 80 | const response: AxiosResponse = await api.post(url, formData, { 81 | headers: { 82 | 'Content-Type': 'multipart/form-data', 83 | }, 84 | }) 85 | 86 | return response.data 87 | } catch (error) { 88 | console.error('Image upload failed:', error) 89 | throw error 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/api/clientProxy.ts: -------------------------------------------------------------------------------- 1 | import axios, { type AxiosRequestConfig, type AxiosResponse } from 'axios' 2 | import { config } from '../constants/config' 3 | import queue from './queue.ts' 4 | 5 | type GetParams = Record 6 | 7 | type PostData = Record 8 | 9 | const api = axios.create({ 10 | baseURL: config.baseURL, 11 | headers: config.headers, 12 | }) 13 | 14 | // Axios interceptor for adding authorization token to request headers. 15 | api.interceptors.request.use( 16 | (config: AxiosRequestConfig) => { 17 | const token = localStorage.getItem('token') 18 | if (token) { 19 | config.headers.Authorization = `Bearer ${token}` 20 | } 21 | return config 22 | }, 23 | async error => await Promise.reject(error), 24 | ) 25 | 26 | /** 27 | * Performs a GET request to the specified URL with the given parameters. 28 | * @param {string} url - The URL to send the GET request to. 29 | * @param {GetParams} params - The parameters to send with the GET request. 30 | * @returns {Promise} A promise that resolves with the response data if the request succeeds, or rejects with an error if it fails. 31 | */ 32 | export async function get(url: string, axiosConfig?: any): Promise { 33 | try { 34 | const response: AxiosResponse = await queue.add({ 35 | method: 'post', 36 | url: `${config.baseURL}/proxy`, 37 | headers: config.headers, 38 | data: { 39 | url, 40 | method: 'GET', 41 | ...axiosConfig, 42 | }, 43 | }) 44 | return response 45 | } catch (error) { 46 | console.error('GET request failed:', error) 47 | throw error 48 | } 49 | } 50 | 51 | /** 52 | * Performs a POST request to the specified URL with the given data. 53 | * @param {string} url - The URL to send the POST request to. 54 | * @param {PostData} data - The data to send with the POST request. 55 | * @returns {Promise} A promise that resolves with the response data if the request succeeds, or rejects with an error if it fails. 56 | */ 57 | export async function post(url: string, axiosConfig: any): Promise { 58 | try { 59 | const response: AxiosResponse = await queue.add({ 60 | method: 'post', 61 | url: `${config.baseURL}/proxy`, 62 | headers: config.headers, 63 | data: { 64 | url, 65 | method: 'POST', 66 | ...axiosConfig, 67 | }, 68 | }) 69 | return response.data 70 | } catch (error) { 71 | console.error('POST proxy request failed:', error) 72 | throw error 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/api/queue.ts: -------------------------------------------------------------------------------- 1 | import axios, { type AxiosRequestConfig, type AxiosResponse } from 'axios' 2 | import { debounce } from '../utils/debounceThrottle' 3 | 4 | interface Request { 5 | config: AxiosRequestConfig 6 | resolve: (value?: AxiosResponse | PromiseLike) => void 7 | reject: (reason?: any) => void 8 | retries: number 9 | } 10 | 11 | const MAX_RETRIES = 0 12 | 13 | class Queue { 14 | private readonly queue: Request[] = [] 15 | 16 | private readonly processQueueDebounced: () => void 17 | 18 | constructor() { 19 | this.processQueueDebounced = debounce(this.processQueue.bind(this), 1000) 20 | } 21 | 22 | async add(request: AxiosRequestConfig): Promise { 23 | return await new Promise((resolve, reject) => { 24 | this.queue.push({ 25 | config: request, 26 | resolve, 27 | reject, 28 | retries: 0, 29 | }) 30 | this.processQueueDebounced() 31 | }) 32 | } 33 | 34 | async processQueue() { 35 | if (this.queue.length === 0) return 36 | 37 | const { config, resolve, reject, retries } = this.queue.shift()! 38 | 39 | try { 40 | const response = await axios(config) 41 | resolve(response) 42 | this.processQueueDebounced() 43 | } catch (error) { 44 | if (retries < MAX_RETRIES) { 45 | // Retry the same request 46 | this.queue.unshift({ 47 | config, 48 | resolve, 49 | reject, 50 | retries: retries + 1, 51 | }) 52 | this.processQueueDebounced() 53 | } else { 54 | reject(error) 55 | } 56 | } 57 | } 58 | } 59 | 60 | const queue = new Queue() 61 | 62 | export default queue 63 | -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Black.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Black.eot -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Black.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Black.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Black.woff -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Black.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Black.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-BlackItalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-BlackItalic.eot -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-BlackItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-BlackItalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-BlackItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-BlackItalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-BlackItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-BlackItalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Bold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Bold.eot -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Bold.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Bold.woff -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Bold.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-BoldItalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-BoldItalic.eot -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-BoldItalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-BoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-BoldItalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-BoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-BoldItalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Book.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Book.eot -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Book.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Book.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Book.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Book.woff -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Book.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Book.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-BookItalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-BookItalic.eot -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-BookItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-BookItalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-BookItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-BookItalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-BookItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-BookItalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-ExtraBold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-ExtraBold.eot -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-ExtraBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-ExtraBold.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-ExtraBold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-ExtraBold.woff -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-ExtraBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-ExtraBold.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-ExtraBoldItalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-ExtraBoldItalic.eot -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-ExtraBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-ExtraBoldItalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-ExtraBoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-ExtraBoldItalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-ExtraBoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-ExtraBoldItalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Heavy.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Heavy.eot -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Heavy.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Heavy.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Heavy.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Heavy.woff -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Heavy.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Heavy.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-HeavyItalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-HeavyItalic.eot -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-HeavyItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-HeavyItalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-HeavyItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-HeavyItalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-HeavyItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-HeavyItalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Italic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Italic.eot -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Italic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Italic.woff -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Italic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Light.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Light.eot -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Light.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Light.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Light.woff -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Light.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-LightItalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-LightItalic.eot -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-LightItalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-LightItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-LightItalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-LightItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-LightItalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Medium.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Medium.eot -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Medium.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Medium.woff -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Medium.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-MediumItalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-MediumItalic.eot -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-MediumItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-MediumItalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-MediumItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-MediumItalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-MediumItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-MediumItalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Regular.eot -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Regular.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Regular.woff -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Regular.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-SemiBold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-SemiBold.eot -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-SemiBold.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-SemiBold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-SemiBold.woff -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-SemiBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-SemiBold.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-SemiBoldItalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-SemiBoldItalic.eot -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-SemiBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-SemiBoldItalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-SemiBoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-SemiBoldItalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-SemiBoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-SemiBoldItalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Thin.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Thin.eot -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Thin.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Thin.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Thin.woff -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-Thin.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-Thin.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-ThinItalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-ThinItalic.eot -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-ThinItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-ThinItalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-ThinItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-ThinItalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/Axiforma-ThinItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Axiforma/Axiforma-ThinItalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Axiforma/typography.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Axiforma'; 3 | src: url('Axiforma-SemiBold.eot'); 4 | src: 5 | local('Axiforma SemiBold'), 6 | local('Axiforma-SemiBold'), 7 | url('Axiforma-SemiBold.eot?#iefix') format('embedded-opentype'), 8 | url('Axiforma-SemiBold.woff2') format('woff2'), 9 | url('Axiforma-SemiBold.woff') format('woff'), 10 | url('Axiforma-SemiBold.ttf') format('truetype'); 11 | font-weight: 600; 12 | font-style: normal; 13 | } 14 | 15 | @font-face { 16 | font-family: 'Axiforma'; 17 | src: url('Axiforma-Thin.eot'); 18 | src: 19 | local('Axiforma Thin'), 20 | local('Axiforma-Thin'), 21 | url('Axiforma-Thin.eot?#iefix') format('embedded-opentype'), 22 | url('Axiforma-Thin.woff2') format('woff2'), 23 | url('Axiforma-Thin.woff') format('woff'), 24 | url('Axiforma-Thin.ttf') format('truetype'); 25 | font-weight: 100; 26 | font-style: normal; 27 | } 28 | 29 | @font-face { 30 | font-family: 'Axiforma'; 31 | src: url('Axiforma-Regular.eot'); 32 | src: 33 | local('Axiforma Regular'), 34 | local('Axiforma-Regular'), 35 | url('Axiforma-Regular.eot?#iefix') format('embedded-opentype'), 36 | url('Axiforma-Regular.woff2') format('woff2'), 37 | url('Axiforma-Regular.woff') format('woff'), 38 | url('Axiforma-Regular.ttf') format('truetype'); 39 | font-weight: normal; 40 | font-style: normal; 41 | } 42 | 43 | @font-face { 44 | font-family: 'Axiforma'; 45 | src: url('Axiforma-MediumItalic.eot'); 46 | src: 47 | local('Axiforma Medium Italic'), 48 | local('Axiforma-MediumItalic'), 49 | url('Axiforma-MediumItalic.eot?#iefix') format('embedded-opentype'), 50 | url('Axiforma-MediumItalic.woff2') format('woff2'), 51 | url('Axiforma-MediumItalic.woff') format('woff'), 52 | url('Axiforma-MediumItalic.ttf') format('truetype'); 53 | font-weight: 500; 54 | font-style: italic; 55 | } 56 | 57 | @font-face { 58 | font-family: 'Axiforma'; 59 | src: url('Axiforma-Black.eot'); 60 | src: 61 | local('Axiforma Black'), 62 | local('Axiforma-Black'), 63 | url('Axiforma-Black.eot?#iefix') format('embedded-opentype'), 64 | url('Axiforma-Black.woff2') format('woff2'), 65 | url('Axiforma-Black.woff') format('woff'), 66 | url('Axiforma-Black.ttf') format('truetype'); 67 | font-weight: 900; 68 | font-style: normal; 69 | } 70 | 71 | @font-face { 72 | font-family: 'Axiforma'; 73 | src: url('Axiforma-BlackItalic.eot'); 74 | src: 75 | local('Axiforma Black Italic'), 76 | local('Axiforma-BlackItalic'), 77 | url('Axiforma-BlackItalic.eot?#iefix') format('embedded-opentype'), 78 | url('Axiforma-BlackItalic.woff2') format('woff2'), 79 | url('Axiforma-BlackItalic.woff') format('woff'), 80 | url('Axiforma-BlackItalic.ttf') format('truetype'); 81 | font-weight: 900; 82 | font-style: italic; 83 | } 84 | 85 | @font-face { 86 | font-family: 'Axiforma'; 87 | src: url('Axiforma-Heavy.eot'); 88 | src: 89 | local('Axiforma Heavy'), 90 | local('Axiforma-Heavy'), 91 | url('Axiforma-Heavy.eot?#iefix') format('embedded-opentype'), 92 | url('Axiforma-Heavy.woff2') format('woff2'), 93 | url('Axiforma-Heavy.woff') format('woff'), 94 | url('Axiforma-Heavy.ttf') format('truetype'); 95 | font-weight: 900; 96 | font-style: normal; 97 | } 98 | 99 | @font-face { 100 | font-family: 'Axiforma'; 101 | src: url('Axiforma-Medium.eot'); 102 | src: 103 | local('Axiforma Medium'), 104 | local('Axiforma-Medium'), 105 | url('Axiforma-Medium.eot?#iefix') format('embedded-opentype'), 106 | url('Axiforma-Medium.woff2') format('woff2'), 107 | url('Axiforma-Medium.woff') format('woff'), 108 | url('Axiforma-Medium.ttf') format('truetype'); 109 | font-weight: 500; 110 | font-style: normal; 111 | } 112 | 113 | @font-face { 114 | font-family: 'Axiforma'; 115 | src: url('Axiforma-BoldItalic.eot'); 116 | src: 117 | local('Axiforma Bold Italic'), 118 | local('Axiforma-BoldItalic'), 119 | url('Axiforma-BoldItalic.eot?#iefix') format('embedded-opentype'), 120 | url('Axiforma-BoldItalic.woff2') format('woff2'), 121 | url('Axiforma-BoldItalic.woff') format('woff'), 122 | url('Axiforma-BoldItalic.ttf') format('truetype'); 123 | font-weight: bold; 124 | font-style: italic; 125 | } 126 | 127 | @font-face { 128 | font-family: 'Axiforma'; 129 | src: url('Axiforma-ExtraBoldItalic.eot'); 130 | src: 131 | local('Axiforma ExtraBold Italic'), 132 | local('Axiforma-ExtraBoldItalic'), 133 | url('Axiforma-ExtraBoldItalic.eot?#iefix') format('embedded-opentype'), 134 | url('Axiforma-ExtraBoldItalic.woff2') format('woff2'), 135 | url('Axiforma-ExtraBoldItalic.woff') format('woff'), 136 | url('Axiforma-ExtraBoldItalic.ttf') format('truetype'); 137 | font-weight: 800; 138 | font-style: italic; 139 | } 140 | 141 | @font-face { 142 | font-family: 'Axiforma'; 143 | src: url('Axiforma-Book.eot'); 144 | src: 145 | local('Axiforma Book'), 146 | local('Axiforma-Book'), 147 | url('Axiforma-Book.eot?#iefix') format('embedded-opentype'), 148 | url('Axiforma-Book.woff2') format('woff2'), 149 | url('Axiforma-Book.woff') format('woff'), 150 | url('Axiforma-Book.ttf') format('truetype'); 151 | font-weight: normal; 152 | font-style: normal; 153 | } 154 | 155 | @font-face { 156 | font-family: 'Axiforma'; 157 | src: url('Axiforma-Light.eot'); 158 | src: 159 | local('Axiforma Light'), 160 | local('Axiforma-Light'), 161 | url('Axiforma-Light.eot?#iefix') format('embedded-opentype'), 162 | url('Axiforma-Light.woff2') format('woff2'), 163 | url('Axiforma-Light.woff') format('woff'), 164 | url('Axiforma-Light.ttf') format('truetype'); 165 | font-weight: 300; 166 | font-style: normal; 167 | } 168 | 169 | @font-face { 170 | font-family: 'Axiforma'; 171 | src: url('Axiforma-ThinItalic.eot'); 172 | src: 173 | local('Axiforma Thin Italic'), 174 | local('Axiforma-ThinItalic'), 175 | url('Axiforma-ThinItalic.eot?#iefix') format('embedded-opentype'), 176 | url('Axiforma-ThinItalic.woff2') format('woff2'), 177 | url('Axiforma-ThinItalic.woff') format('woff'), 178 | url('Axiforma-ThinItalic.ttf') format('truetype'); 179 | font-weight: 100; 180 | font-style: italic; 181 | } 182 | 183 | @font-face { 184 | font-family: 'Axiforma'; 185 | src: url('Axiforma-Bold.eot'); 186 | src: 187 | local('Axiforma Bold'), 188 | local('Axiforma-Bold'), 189 | url('Axiforma-Bold.eot?#iefix') format('embedded-opentype'), 190 | url('Axiforma-Bold.woff2') format('woff2'), 191 | url('Axiforma-Bold.woff') format('woff'), 192 | url('Axiforma-Bold.ttf') format('truetype'); 193 | font-weight: bold; 194 | font-style: normal; 195 | } 196 | 197 | @font-face { 198 | font-family: 'Axiforma'; 199 | src: url('Axiforma-LightItalic.eot'); 200 | src: 201 | local('Axiforma Light Italic'), 202 | local('Axiforma-LightItalic'), 203 | url('Axiforma-LightItalic.eot?#iefix') format('embedded-opentype'), 204 | url('Axiforma-LightItalic.woff2') format('woff2'), 205 | url('Axiforma-LightItalic.woff') format('woff'), 206 | url('Axiforma-LightItalic.ttf') format('truetype'); 207 | font-weight: 300; 208 | font-style: italic; 209 | } 210 | 211 | @font-face { 212 | font-family: 'Axiforma'; 213 | src: url('Axiforma-SemiBoldItalic.eot'); 214 | src: 215 | local('Axiforma SemiBold Italic'), 216 | local('Axiforma-SemiBoldItalic'), 217 | url('Axiforma-SemiBoldItalic.eot?#iefix') format('embedded-opentype'), 218 | url('Axiforma-SemiBoldItalic.woff2') format('woff2'), 219 | url('Axiforma-SemiBoldItalic.woff') format('woff'), 220 | url('Axiforma-SemiBoldItalic.ttf') format('truetype'); 221 | font-weight: 600; 222 | font-style: italic; 223 | } 224 | 225 | @font-face { 226 | font-family: 'Axiforma'; 227 | src: url('Axiforma-Italic.eot'); 228 | src: 229 | local('Axiforma Italic'), 230 | local('Axiforma-Italic'), 231 | url('Axiforma-Italic.eot?#iefix') format('embedded-opentype'), 232 | url('Axiforma-Italic.woff2') format('woff2'), 233 | url('Axiforma-Italic.woff') format('woff'), 234 | url('Axiforma-Italic.ttf') format('truetype'); 235 | font-weight: normal; 236 | font-style: italic; 237 | } 238 | 239 | @font-face { 240 | font-family: 'Axiforma'; 241 | src: url('Axiforma-BookItalic.eot'); 242 | src: 243 | local('Axiforma Book Italic'), 244 | local('Axiforma-BookItalic'), 245 | url('Axiforma-BookItalic.eot?#iefix') format('embedded-opentype'), 246 | url('Axiforma-BookItalic.woff2') format('woff2'), 247 | url('Axiforma-BookItalic.woff') format('woff'), 248 | url('Axiforma-BookItalic.ttf') format('truetype'); 249 | font-weight: normal; 250 | font-style: italic; 251 | } 252 | 253 | @font-face { 254 | font-family: 'Axiforma'; 255 | src: url('Axiforma-ExtraBold.eot'); 256 | src: 257 | local('Axiforma ExtraBold'), 258 | local('Axiforma-ExtraBold'), 259 | url('Axiforma-ExtraBold.eot?#iefix') format('embedded-opentype'), 260 | url('Axiforma-ExtraBold.woff2') format('woff2'), 261 | url('Axiforma-ExtraBold.woff') format('woff'), 262 | url('Axiforma-ExtraBold.ttf') format('truetype'); 263 | font-weight: 800; 264 | font-style: normal; 265 | } 266 | 267 | @font-face { 268 | font-family: 'Axiforma'; 269 | src: url('Axiforma-HeavyItalic.eot'); 270 | src: 271 | local('Axiforma Heavy Italic'), 272 | local('Axiforma-HeavyItalic'), 273 | url('Axiforma-HeavyItalic.eot?#iefix') format('embedded-opentype'), 274 | url('Axiforma-HeavyItalic.woff2') format('woff2'), 275 | url('Axiforma-HeavyItalic.woff') format('woff'), 276 | url('Axiforma-HeavyItalic.ttf') format('truetype'); 277 | font-weight: 900; 278 | font-style: italic; 279 | } 280 | -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-Black.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-Black.eot -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-Black.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-Black.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-Black.woff -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-Black.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-Black.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-BlackItalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-BlackItalic.eot -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-BlackItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-BlackItalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-BlackItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-BlackItalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-BlackItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-BlackItalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-Bold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-Bold.eot -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-Bold.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-Bold.woff -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-Bold.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-BoldItalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-BoldItalic.eot -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-BoldItalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-BoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-BoldItalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-BoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-BoldItalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-ExtraBold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-ExtraBold.eot -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-ExtraBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-ExtraBold.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-ExtraBold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-ExtraBold.woff -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-ExtraBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-ExtraBold.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-ExtraBoldItalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-ExtraBoldItalic.eot -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-ExtraBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-ExtraBoldItalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-ExtraBoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-ExtraBoldItalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-ExtraBoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-ExtraBoldItalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-ExtraLight.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-ExtraLight.eot -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-ExtraLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-ExtraLight.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-ExtraLight.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-ExtraLight.woff -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-ExtraLight.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-ExtraLight.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-ExtraLightItalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-ExtraLightItalic.eot -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-ExtraLightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-ExtraLightItalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-ExtraLightItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-ExtraLightItalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-ExtraLightItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-ExtraLightItalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-Italic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-Italic.eot -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-Italic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-Italic.woff -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-Italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-Italic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-Light.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-Light.eot -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-Light.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-Light.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-Light.woff -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-Light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-Light.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-LightItalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-LightItalic.eot -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-LightItalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-LightItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-LightItalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-LightItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-LightItalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-Medium.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-Medium.eot -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-Medium.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-Medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-Medium.woff -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-Medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-Medium.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-MediumItalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-MediumItalic.eot -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-MediumItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-MediumItalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-MediumItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-MediumItalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-MediumItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-MediumItalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-Regular.eot -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-Regular.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-Regular.woff -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-Regular.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-SemiBold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-SemiBold.eot -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-SemiBold.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-SemiBold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-SemiBold.woff -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-SemiBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-SemiBold.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-SemiBoldItalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-SemiBoldItalic.eot -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-SemiBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-SemiBoldItalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-SemiBoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-SemiBoldItalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-SemiBoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-SemiBoldItalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-Thin.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-Thin.eot -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-Thin.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-Thin.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-Thin.woff -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-Thin.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-Thin.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-ThinItalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-ThinItalic.eot -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-ThinItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-ThinItalic.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-ThinItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-ThinItalic.woff -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/Poppins-ThinItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/assets/fonts/Poppins/Poppins-ThinItalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Poppins/typography.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Poppins'; 3 | src: url('Poppins-ExtraLight.eot'); 4 | src: 5 | local('Poppins ExtraLight'), 6 | local('Poppins-ExtraLight'), 7 | url('Poppins-ExtraLight.eot?#iefix') format('embedded-opentype'), 8 | url('Poppins-ExtraLight.woff2') format('woff2'), 9 | url('Poppins-ExtraLight.woff') format('woff'), 10 | url('Poppins-ExtraLight.ttf') format('truetype'); 11 | font-weight: 200; 12 | font-style: normal; 13 | } 14 | 15 | @font-face { 16 | font-family: 'Poppins'; 17 | src: url('Poppins-Medium.eot'); 18 | src: 19 | local('Poppins Medium'), 20 | local('Poppins-Medium'), 21 | url('Poppins-Medium.eot?#iefix') format('embedded-opentype'), 22 | url('Poppins-Medium.woff2') format('woff2'), 23 | url('Poppins-Medium.woff') format('woff'), 24 | url('Poppins-Medium.ttf') format('truetype'); 25 | font-weight: 500; 26 | font-style: normal; 27 | } 28 | 29 | @font-face { 30 | font-family: 'Poppins'; 31 | src: url('Poppins-LightItalic.eot'); 32 | src: 33 | local('Poppins Light Italic'), 34 | local('Poppins-LightItalic'), 35 | url('Poppins-LightItalic.eot?#iefix') format('embedded-opentype'), 36 | url('Poppins-LightItalic.woff2') format('woff2'), 37 | url('Poppins-LightItalic.woff') format('woff'), 38 | url('Poppins-LightItalic.ttf') format('truetype'); 39 | font-weight: 300; 40 | font-style: italic; 41 | } 42 | 43 | @font-face { 44 | font-family: 'Poppins'; 45 | src: url('Poppins-ExtraLightItalic.eot'); 46 | src: 47 | local('Poppins ExtraLight Italic'), 48 | local('Poppins-ExtraLightItalic'), 49 | url('Poppins-ExtraLightItalic.eot?#iefix') format('embedded-opentype'), 50 | url('Poppins-ExtraLightItalic.woff2') format('woff2'), 51 | url('Poppins-ExtraLightItalic.woff') format('woff'), 52 | url('Poppins-ExtraLightItalic.ttf') format('truetype'); 53 | font-weight: 200; 54 | font-style: italic; 55 | } 56 | 57 | @font-face { 58 | font-family: 'Poppins'; 59 | src: url('Poppins-Regular.eot'); 60 | src: 61 | local('Poppins Regular'), 62 | local('Poppins-Regular'), 63 | url('Poppins-Regular.eot?#iefix') format('embedded-opentype'), 64 | url('Poppins-Regular.woff2') format('woff2'), 65 | url('Poppins-Regular.woff') format('woff'), 66 | url('Poppins-Regular.ttf') format('truetype'); 67 | font-weight: normal; 68 | font-style: normal; 69 | } 70 | 71 | @font-face { 72 | font-family: 'Poppins'; 73 | src: url('Poppins-SemiBold.eot'); 74 | src: 75 | local('Poppins SemiBold'), 76 | local('Poppins-SemiBold'), 77 | url('Poppins-SemiBold.eot?#iefix') format('embedded-opentype'), 78 | url('Poppins-SemiBold.woff2') format('woff2'), 79 | url('Poppins-SemiBold.woff') format('woff'), 80 | url('Poppins-SemiBold.ttf') format('truetype'); 81 | font-weight: 600; 82 | font-style: normal; 83 | } 84 | 85 | @font-face { 86 | font-family: 'Poppins'; 87 | src: url('Poppins-Black.eot'); 88 | src: 89 | local('Poppins Black'), 90 | local('Poppins-Black'), 91 | url('Poppins-Black.eot?#iefix') format('embedded-opentype'), 92 | url('Poppins-Black.woff2') format('woff2'), 93 | url('Poppins-Black.woff') format('woff'), 94 | url('Poppins-Black.ttf') format('truetype'); 95 | font-weight: 900; 96 | font-style: normal; 97 | } 98 | 99 | @font-face { 100 | font-family: 'Poppins'; 101 | src: url('Poppins-ExtraBoldItalic.eot'); 102 | src: 103 | local('Poppins ExtraBold Italic'), 104 | local('Poppins-ExtraBoldItalic'), 105 | url('Poppins-ExtraBoldItalic.eot?#iefix') format('embedded-opentype'), 106 | url('Poppins-ExtraBoldItalic.woff2') format('woff2'), 107 | url('Poppins-ExtraBoldItalic.woff') format('woff'), 108 | url('Poppins-ExtraBoldItalic.ttf') format('truetype'); 109 | font-weight: 800; 110 | font-style: italic; 111 | } 112 | 113 | @font-face { 114 | font-family: 'Poppins'; 115 | src: url('Poppins-MediumItalic.eot'); 116 | src: 117 | local('Poppins Medium Italic'), 118 | local('Poppins-MediumItalic'), 119 | url('Poppins-MediumItalic.eot?#iefix') format('embedded-opentype'), 120 | url('Poppins-MediumItalic.woff2') format('woff2'), 121 | url('Poppins-MediumItalic.woff') format('woff'), 122 | url('Poppins-MediumItalic.ttf') format('truetype'); 123 | font-weight: 500; 124 | font-style: italic; 125 | } 126 | 127 | @font-face { 128 | font-family: 'Poppins'; 129 | src: url('Poppins-Light.eot'); 130 | src: 131 | local('Poppins Light'), 132 | local('Poppins-Light'), 133 | url('Poppins-Light.eot?#iefix') format('embedded-opentype'), 134 | url('Poppins-Light.woff2') format('woff2'), 135 | url('Poppins-Light.woff') format('woff'), 136 | url('Poppins-Light.ttf') format('truetype'); 137 | font-weight: 300; 138 | font-style: normal; 139 | } 140 | 141 | @font-face { 142 | font-family: 'Poppins'; 143 | src: url('Poppins-Bold.eot'); 144 | src: 145 | local('Poppins Bold'), 146 | local('Poppins-Bold'), 147 | url('Poppins-Bold.eot?#iefix') format('embedded-opentype'), 148 | url('Poppins-Bold.woff2') format('woff2'), 149 | url('Poppins-Bold.woff') format('woff'), 150 | url('Poppins-Bold.ttf') format('truetype'); 151 | font-weight: bold; 152 | font-style: normal; 153 | } 154 | 155 | @font-face { 156 | font-family: 'Poppins'; 157 | src: url('Poppins-Thin.eot'); 158 | src: 159 | local('Poppins Thin'), 160 | local('Poppins-Thin'), 161 | url('Poppins-Thin.eot?#iefix') format('embedded-opentype'), 162 | url('Poppins-Thin.woff2') format('woff2'), 163 | url('Poppins-Thin.woff') format('woff'), 164 | url('Poppins-Thin.ttf') format('truetype'); 165 | font-weight: 100; 166 | font-style: normal; 167 | } 168 | 169 | @font-face { 170 | font-family: 'Poppins'; 171 | src: url('Poppins-Italic.eot'); 172 | src: 173 | local('Poppins Italic'), 174 | local('Poppins-Italic'), 175 | url('Poppins-Italic.eot?#iefix') format('embedded-opentype'), 176 | url('Poppins-Italic.woff2') format('woff2'), 177 | url('Poppins-Italic.woff') format('woff'), 178 | url('Poppins-Italic.ttf') format('truetype'); 179 | font-weight: normal; 180 | font-style: italic; 181 | } 182 | 183 | @font-face { 184 | font-family: 'Poppins'; 185 | src: url('Poppins-ThinItalic.eot'); 186 | src: 187 | local('Poppins Thin Italic'), 188 | local('Poppins-ThinItalic'), 189 | url('Poppins-ThinItalic.eot?#iefix') format('embedded-opentype'), 190 | url('Poppins-ThinItalic.woff2') format('woff2'), 191 | url('Poppins-ThinItalic.woff') format('woff'), 192 | url('Poppins-ThinItalic.ttf') format('truetype'); 193 | font-weight: 100; 194 | font-style: italic; 195 | } 196 | 197 | @font-face { 198 | font-family: 'Poppins'; 199 | src: url('Poppins-BlackItalic.eot'); 200 | src: 201 | local('Poppins Black Italic'), 202 | local('Poppins-BlackItalic'), 203 | url('Poppins-BlackItalic.eot?#iefix') format('embedded-opentype'), 204 | url('Poppins-BlackItalic.woff2') format('woff2'), 205 | url('Poppins-BlackItalic.woff') format('woff'), 206 | url('Poppins-BlackItalic.ttf') format('truetype'); 207 | font-weight: 900; 208 | font-style: italic; 209 | } 210 | 211 | @font-face { 212 | font-family: 'Poppins'; 213 | src: url('Poppins-BoldItalic.eot'); 214 | src: 215 | local('Poppins Bold Italic'), 216 | local('Poppins-BoldItalic'), 217 | url('Poppins-BoldItalic.eot?#iefix') format('embedded-opentype'), 218 | url('Poppins-BoldItalic.woff2') format('woff2'), 219 | url('Poppins-BoldItalic.woff') format('woff'), 220 | url('Poppins-BoldItalic.ttf') format('truetype'); 221 | font-weight: bold; 222 | font-style: italic; 223 | } 224 | 225 | @font-face { 226 | font-family: 'Poppins'; 227 | src: url('Poppins-SemiBoldItalic.eot'); 228 | src: 229 | local('Poppins SemiBold Italic'), 230 | local('Poppins-SemiBoldItalic'), 231 | url('Poppins-SemiBoldItalic.eot?#iefix') format('embedded-opentype'), 232 | url('Poppins-SemiBoldItalic.woff2') format('woff2'), 233 | url('Poppins-SemiBoldItalic.woff') format('woff'), 234 | url('Poppins-SemiBoldItalic.ttf') format('truetype'); 235 | font-weight: 600; 236 | font-style: italic; 237 | } 238 | 239 | @font-face { 240 | font-family: 'Poppins'; 241 | src: url('Poppins-ExtraBold.eot'); 242 | src: 243 | local('Poppins ExtraBold'), 244 | local('Poppins-ExtraBold'), 245 | url('Poppins-ExtraBold.eot?#iefix') format('embedded-opentype'), 246 | url('Poppins-ExtraBold.woff2') format('woff2'), 247 | url('Poppins-ExtraBold.woff') format('woff'), 248 | url('Poppins-ExtraBold.ttf') format('truetype'); 249 | font-weight: 800; 250 | font-style: normal; 251 | } 252 | -------------------------------------------------------------------------------- /src/components/Icon.tsx: -------------------------------------------------------------------------------- 1 | import { type FC } from 'react' 2 | import * as Icons from 'tabler-icons-react' 3 | import { type IconProps } from 'tabler-icons-react' 4 | 5 | interface IconComponentProps extends IconProps { 6 | name?: keyof typeof Icons 7 | } 8 | 9 | const Icon: FC = ({ name = 'Plant', ...rest }) => { 10 | const IconComponent = Icons[name] 11 | return 12 | } 13 | 14 | export default Icon 15 | -------------------------------------------------------------------------------- /src/components/layout/Header/Header.module.pcss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/components/layout/Header/Header.module.pcss -------------------------------------------------------------------------------- /src/components/layout/Header/Header.tsx: -------------------------------------------------------------------------------- 1 | import { type FC, type ReactNode } from 'react' 2 | 3 | export interface HeaderProps { 4 | children?: ReactNode 5 | } 6 | 7 | export const Header: FC = ({ children }) =>
{children}
8 | -------------------------------------------------------------------------------- /src/components/screens/AppScreen/AppScreen.module.pcss: -------------------------------------------------------------------------------- 1 | .container { 2 | padding: var(--sp-md) var(--sp-md) 0 var(--sp-md); 3 | } 4 | -------------------------------------------------------------------------------- /src/components/screens/AppScreen/AppScreen.module.pcss.d.ts: -------------------------------------------------------------------------------- 1 | /** Generated by [postcss-d-ts](https://github.com/askirmas/postcss-d-ts) */ 2 | declare const identifiersMap: CssIdentifiersMap 3 | 4 | export default identifiersMap 5 | 6 | export interface CssIdentifiersMap { 7 | container: string | undefined 8 | } 9 | -------------------------------------------------------------------------------- /src/components/screens/AppScreen/AppScreen.tsx: -------------------------------------------------------------------------------- 1 | import { type FC, type ReactNode } from 'react' 2 | import classNames from './AppScreen.module.pcss' 3 | 4 | export interface AppScreenProps { 5 | children?: ReactNode 6 | } 7 | 8 | export const AppScreen: FC = ({ children }) =>
{children}
9 | -------------------------------------------------------------------------------- /src/constants/animations.ts: -------------------------------------------------------------------------------- 1 | export const fadeUpAnimation = { 2 | initial: { opacity: 0, translateY: 50 }, 3 | animate: { opacity: 1, translateY: 0 }, 4 | exit: { opacity: 0, translateY: 50 }, 5 | } 6 | export const fadeAnimation = { 7 | initial: { opacity: 0 }, 8 | animate: { opacity: 1 }, 9 | exit: { opacity: 0 }, 10 | } 11 | -------------------------------------------------------------------------------- /src/constants/config.ts: -------------------------------------------------------------------------------- 1 | export const config = { 2 | baseURL: 'http://localhost:4000', 3 | headers: { 4 | 'Content-Type': 'application/json', 5 | }, 6 | timeout: 10000, 7 | } 8 | -------------------------------------------------------------------------------- /src/constants/routes.ts: -------------------------------------------------------------------------------- 1 | export const routes = { 2 | home: '/', 3 | auth: '/auth', 4 | login: '/login', 5 | signup: '/signup', 6 | profile: '/profile', 7 | notFound: '/404', 8 | resetPassword: '/reset-password', 9 | } 10 | -------------------------------------------------------------------------------- /src/hooks/useTracking.tsx: -------------------------------------------------------------------------------- 1 | import posthog from 'posthog-js' 2 | import { type TrackEventProps } from '../types/TrackEventProps' 3 | 4 | // Standalone function for trackTransaction 5 | export const trackTransaction = () => { 6 | console.log('trackTransaction') 7 | } 8 | 9 | // Standalone function for trackEvent 10 | export const trackEvent = async ({ category, action, label, data }: TrackEventProps) => { 11 | try { 12 | // console.log('trackEvent', action, label, category, data) 13 | posthog.capture(action, { 14 | label, 15 | category, 16 | ...data, 17 | }) 18 | } catch (error) { 19 | console.error('trackEvent error', error) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/i18n/I18nextProvider.tsx: -------------------------------------------------------------------------------- 1 | // import i18next from 'i18next' 2 | // import { type ReactNode } from 'react' 3 | // import { I18nextProvider } from 'react-i18next' 4 | // import { translations } from './translations' 5 | // import { getItem } from '../utils/localStorage' 6 | // 7 | // interface i18nextProviderProps { 8 | // children: ReactNode 9 | // } 10 | // 11 | // export function I18Provider({ children }: i18nextProviderProps) { 12 | // const i18n = i18next.createInstance({ 13 | // debug: false, 14 | // fallbackLng: 'en', 15 | // lng: getItem('language', 'en') ?? 'en', 16 | // resources: translations, 17 | // }) 18 | // 19 | // i18n.init() 20 | // 21 | // return {children} 22 | // } 23 | -------------------------------------------------------------------------------- /src/i18n/languages.ts: -------------------------------------------------------------------------------- 1 | export interface Language { 2 | id: string 3 | title: string 4 | } 5 | 6 | export const languages: Language[] = [ 7 | { id: 'en', title: 'English' }, 8 | { id: 'es', title: 'Español' }, 9 | { id: 'fr', title: 'Français' }, 10 | { id: 'it', title: 'Italiano' }, 11 | { id: 'id', title: 'Bahasa Indonesia' }, 12 | { id: 'ko', title: '한국어' }, 13 | { id: 'pt', title: 'Português' }, 14 | { id: 'ru', title: 'Русский' }, 15 | { id: 'th', title: 'ไทย' }, 16 | { id: 'tr', title: 'Türkçe' }, 17 | { id: 'ua', title: 'Українська' }, 18 | { id: 'vi', title: 'Tiếng Việt' }, 19 | { id: 'zh', title: '中文' }, 20 | ] 21 | -------------------------------------------------------------------------------- /src/i18n/translations/en.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/vite-ts-react-template/754b6e766ebbd044a4191b31a447527a96996b64/src/i18n/translations/en.ts -------------------------------------------------------------------------------- /src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import './stylesheets/index.css' 4 | import './assets/fonts/Poppins/typography.css' 5 | import App from './App' 6 | 7 | ReactDOM.createRoot(document.getElementById('root')!).render( 8 | 9 | 10 | , 11 | ) 12 | -------------------------------------------------------------------------------- /src/stylesheets/App.css: -------------------------------------------------------------------------------- 1 | .row { 2 | flex-direction: row; 3 | } 4 | 5 | .ac { 6 | align-items: center; 7 | } 8 | 9 | .afe { 10 | align-items: flex-end; 11 | } 12 | 13 | .afs { 14 | align-items: flex-start; 15 | } 16 | 17 | .jc { 18 | justify-content: center; 19 | } 20 | 21 | .jfe { 22 | justify-content: flex-end; 23 | } 24 | 25 | .jsb { 26 | justify-content: space-between; 27 | } 28 | 29 | .jfs { 30 | justify-content: flex-start; 31 | } 32 | 33 | .f1 { 34 | flex: 1; 35 | } 36 | 37 | .gap-xs { 38 | gap: var(--sp-xs); 39 | } 40 | 41 | .gap-sm { 42 | gap: var(--sp-sm); 43 | } 44 | 45 | .gap-md { 46 | gap: var(--sp-md); 47 | } 48 | 49 | .gap-lg { 50 | gap: var(--sp-lg); 51 | } 52 | 53 | .gap-xl { 54 | gap: var(--sp-xl); 55 | } 56 | 57 | .hide-down { 58 | opacity: 0; 59 | transform: translateY(10px); 60 | } 61 | 62 | .show-up { 63 | opacity: 1; 64 | transform: translateY(0); 65 | } 66 | 67 | .fade-in-out { 68 | transition: 69 | opacity 0.25s ease-in-out, 70 | transform 0.25s ease-in-out; 71 | } 72 | -------------------------------------------------------------------------------- /src/stylesheets/App.css.d.ts: -------------------------------------------------------------------------------- 1 | /** Generated by [postcss-d-ts](https://github.com/askirmas/postcss-d-ts) */ 2 | declare const identifiersMap: CssIdentifiersMap 3 | 4 | export default identifiersMap 5 | 6 | export interface CssIdentifiersMap { 7 | ac: string | undefined 8 | afe: string | undefined 9 | afs: string | undefined 10 | f1: string | undefined 11 | 'fade-in-out': string | undefined 12 | 'gap-lg': string | undefined 13 | 'gap-md': string | undefined 14 | 'gap-sm': string | undefined 15 | 'gap-xl': string | undefined 16 | 'gap-xs': string | undefined 17 | 'hide-down': string | undefined 18 | jc: string | undefined 19 | jfe: string | undefined 20 | jfs: string | undefined 21 | jsb: string | undefined 22 | row: string | undefined 23 | 'show-up': string | undefined 24 | } 25 | -------------------------------------------------------------------------------- /src/stylesheets/index.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --st-br-xl: 20px; 3 | --st-br-lg: 16px; 4 | --st-br-md: 12px; 5 | --st-br-sm: 8px; 6 | --st-br-xs: 4px; 7 | --sp-xxl: 48px; 8 | --sp-xl: 32px; 9 | --sp-lg: 24px; 10 | --sp-md: 12px; 11 | --sp-sm: 8px; 12 | --sp-xs: 4px; 13 | --sp-xxs: 2px; 14 | --sp-screen-v: 20px; 15 | --sp-screen-h: 20px; 16 | 17 | --color-base-background: #000000; 18 | --color-text-primary: #ffffff; 19 | --color-text-secondary: #fafafa; 20 | 21 | color-scheme: light dark; 22 | font-family: Poppins, sans-serif; 23 | font-size: 16px; /* base font size, 1rem */ 24 | -webkit-font-smoothing: antialiased; 25 | font-synthesis: none; 26 | -moz-osx-font-smoothing: grayscale; 27 | text-rendering: optimizeLegibility; 28 | -webkit-text-size-adjust: 100%; 29 | } 30 | 31 | header, 32 | main, 33 | footer, 34 | aside, 35 | nav, 36 | section, 37 | article, 38 | figure, 39 | figcaption, 40 | ul, 41 | ol, 42 | li { 43 | display: flex; 44 | } 45 | 46 | body { 47 | background-color: var(--color-base-background); 48 | box-sizing: border-box; 49 | display: flex; 50 | height: 100vh; 51 | margin: 0; 52 | overflow: hidden; 53 | padding: 0; 54 | width: 100vw; 55 | scrollbar-width: none; 56 | } 57 | 58 | div { 59 | box-sizing: border-box; 60 | color: var(--color-text-primary); 61 | display: flex; 62 | flex-direction: column; 63 | scrollbar-width: none; 64 | } 65 | 66 | div::-webkit-scrollbar { 67 | display: none; 68 | } 69 | 70 | h1, 71 | h2, 72 | h3, 73 | h4, 74 | h5, 75 | h6, 76 | p, 77 | a, 78 | button, 79 | input, 80 | label, 81 | span, 82 | li { 83 | box-sizing: border-box; 84 | color: var(--color-text-primary); 85 | font-family: inherit; 86 | margin: 0; 87 | padding: 0; 88 | -moz-user-select: none; 89 | -ms-user-select: none; 90 | -webkit-user-select: none; 91 | user-select: none; 92 | } 93 | 94 | ul, 95 | ol, 96 | li { 97 | margin-block: 0; 98 | margin-inline: 0; 99 | padding-inline: 0; 100 | } 101 | 102 | h1 { 103 | font-size: 2rem; 104 | font-weight: 600; 105 | } 106 | 107 | h2 { 108 | font-size: 1.5rem; 109 | font-weight: 500; 110 | } 111 | 112 | h3 { 113 | font-size: 1.25rem; 114 | font-weight: 500; 115 | } 116 | 117 | h4 { 118 | font-size: 1rem; 119 | font-weight: 500; 120 | } 121 | 122 | h5 { 123 | font-size: 0.875rem; 124 | font-weight: 500; 125 | } 126 | 127 | p { 128 | display: inline; 129 | font-size: 1rem; 130 | font-weight: 400; 131 | } 132 | 133 | a { 134 | color: inherit; 135 | text-decoration: none; 136 | } 137 | 138 | .body1 { 139 | color: var(--color-text-secondary); 140 | font-size: 0.85rem; 141 | } 142 | 143 | button { 144 | border: none; 145 | cursor: pointer; 146 | font-weight: 500; 147 | line-height: 0; 148 | outline: none; 149 | } 150 | -------------------------------------------------------------------------------- /src/stylesheets/index.css.d.ts: -------------------------------------------------------------------------------- 1 | /** Generated by [postcss-d-ts](https://github.com/askirmas/postcss-d-ts) */ 2 | declare const identifiersMap: CssIdentifiersMap 3 | 4 | export default identifiersMap 5 | 6 | export interface CssIdentifiersMap { 7 | body1: string | undefined 8 | } 9 | -------------------------------------------------------------------------------- /src/types/TrackEventProps.d.ts: -------------------------------------------------------------------------------- 1 | export interface TrackEventProps { 2 | action: string 3 | category: string 4 | label: string 5 | value?: number 6 | data?: Record 7 | } 8 | -------------------------------------------------------------------------------- /src/utils/cookies.ts: -------------------------------------------------------------------------------- 1 | export const setCookie = (name: string, value: string, days = 7): void => { 2 | const expires = new Date(Date.now() + days * 86400000).toUTCString() 3 | document.cookie = `${name}=${encodeURIComponent(value)}; expires=${expires}; path=/` 4 | } 5 | 6 | export const getCookie = (name: string): string | null => { 7 | const matches = document.cookie.match(new RegExp(`(?:^|; )${name.replace(/([.$?*|{}()[\]\\/+^])/g, '\\$1')}=([^;]*)`)) 8 | return matches ? decodeURIComponent(matches[1]) : null 9 | } 10 | 11 | export const deleteCookie = (name: string): void => { 12 | setCookie(name, '', -1) 13 | } 14 | 15 | export const isCookieSet = (name: string): boolean => getCookie(name) !== null 16 | 17 | export const clearCookies = (): void => { 18 | const cookies = document.cookie.split('; ') 19 | for (const cookie of cookies) { 20 | const [name] = cookie.split('=') 21 | deleteCookie(name) 22 | } 23 | } 24 | 25 | export const getAllCookies = (): Record => { 26 | const cookies = document.cookie.split('; ') 27 | const result: Record = {} 28 | for (const cookie of cookies) { 29 | const [name, value] = cookie.split('=') 30 | result[name] = decodeURIComponent(value) 31 | } 32 | return result 33 | } 34 | -------------------------------------------------------------------------------- /src/utils/copyToClipboard.ts: -------------------------------------------------------------------------------- 1 | export async function copyToClipboard(value: string): Promise { 2 | await window.navigator.clipboard.writeText(value) 3 | } 4 | -------------------------------------------------------------------------------- /src/utils/debounceThrottle.ts: -------------------------------------------------------------------------------- 1 | // Debounce 2 | export const debounce = any>(func: T, wait: number, immediate = false): ((...args: Parameters) => void) => { 3 | let timeout: ReturnType | null = null 4 | return (...args: Parameters): void => { 5 | const later = () => { 6 | timeout = null 7 | if (!immediate) func(...args) 8 | } 9 | 10 | const callNow = immediate && !timeout 11 | if (timeout) clearTimeout(timeout) 12 | timeout = setTimeout(later, wait) 13 | 14 | if (callNow) func(...args) 15 | } 16 | } 17 | 18 | // Throttle 19 | export const throttle = any>(func: T, limit: number): ((...args: Parameters) => void) => { 20 | let inThrottle = false 21 | return (...args: Parameters): void => { 22 | if (!inThrottle) { 23 | func(...args) 24 | inThrottle = true 25 | setTimeout(() => (inThrottle = false), limit) 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/utils/errors.ts: -------------------------------------------------------------------------------- 1 | /** 2 | Logs an error to the console and sends it to an external error tracking service, if available. 3 | @param {Error} error - The error to be logged. 4 | @param {*} [additionalInfo] - Any additional information to be included in the error log. 5 | @returns {void} 6 | */ 7 | export const logError = (error: Error, additionalInfo?: any): void => { 8 | console.error(`Error: ${error.message}`, error, additionalInfo) 9 | 10 | // Send the error to an external error tracking service (e.g., Sentry, Rollbar) 11 | // Example: Sentry.captureException(error, { extra: additionalInfo }); 12 | } 13 | 14 | /** 15 | Wraps a function with error handling logic to log and handle any errors that may occur. 16 | @template TArgs - The types of the function arguments. 17 | @template TResult - The return type of the function. 18 | @param {(...args: TArgs) => TResult} fn - The function to wrap with error handling logic. 19 | @param {string} errorMessage - The error message to be logged if an error occurs. 20 | @returns {(...args: TArgs) => TResult | null} - The wrapped function with error handling logic. 21 | */ 22 | export const withErrorHandling = 23 | (fn: (...args: TArgs) => TResult, errorMessage: string): ((...args: TArgs) => TResult | null) => 24 | (...args: TArgs): TResult | null => { 25 | try { 26 | return fn(...args) 27 | } catch (error) { 28 | logError(new Error(errorMessage), { originalError: error }) 29 | return null 30 | } 31 | } 32 | 33 | /** 34 | Wraps an async function with error handling logic to log and handle any errors that may occur. 35 | @template TArgs - The types of the function arguments. 36 | @template TResult - The return type of the function. 37 | @param {(...args: TArgs) => Promise} fn - The async function to wrap with error handling logic. 38 | @param {string} errorMessage - The error message to be logged if an error occurs. 39 | @returns {(...args: TArgs) => Promise} - The wrapped async function with error handling logic. 40 | */ 41 | export const withErrorHandlingAsync = 42 | (fn: (...args: TArgs) => Promise, errorMessage: string): ((...args: TArgs) => Promise) => 43 | async (...args: TArgs): Promise => { 44 | try { 45 | return await fn(...args) 46 | } catch (error) { 47 | logError(new Error(errorMessage), { originalError: error }) 48 | return null 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/utils/formatting.ts: -------------------------------------------------------------------------------- 1 | import relativeTime from 'dayjs/plugin/relativeTime' 2 | import updateLocale from 'dayjs/plugin/updateLocale' 3 | import dayjs from 'dayjs' 4 | import BigNumber from 'bignumber.js' 5 | 6 | dayjs.extend(relativeTime) 7 | dayjs.extend(updateLocale) 8 | dayjs.updateLocale('en', { 9 | relativeTime: { 10 | future: 'in %s', 11 | past: '%s', 12 | s: 'now', 13 | m: 'a min', 14 | mm: '%dm', 15 | h: '1h', 16 | hh: '%dh', 17 | d: 'a day', 18 | dd: '%dd', 19 | M: '1 mon', 20 | MM: '%dm', 21 | y: 'a year', 22 | yy: '%dy', 23 | }, 24 | }) 25 | export default dayjs 26 | 27 | export function isValidNumber(number: string | number) { 28 | if (typeof number === 'string') { 29 | return number !== '' 30 | } else { 31 | return !(number === undefined || number === null || isNaN(number)) 32 | } 33 | } 34 | 35 | // Date and time formatting 36 | const formatDate = (date: string | Date, format = 'YYYY-MM-DD'): string => dayjs(date).format(format) 37 | 38 | export const formatDateTime = (date: string | Date, format = 'YYYY-MM-DD HH:mm'): string => dayjs(date).format(format) 39 | 40 | export const formatTime = (date: string | Date, format = 'HH:mm'): string => dayjs(date).format(format) 41 | 42 | export const fromNow = (date: string | Date): string => dayjs(date).fromNow() 43 | 44 | export const unixtimeFromNow = (unixtime: number): string => dayjs.unix(unixtime).fromNow() 45 | 46 | export const unixTimeFormat = (unixtime: number, format = 'YYYY-MM-DD HH:mm'): string => dayjs.unix(unixtime).format(format) 47 | 48 | // Number and currency formatting 49 | // export const formatNumber = (num: number, decimalPlaces = 2): string => num.toFixed(decimalPlaces) 50 | 51 | export const formatCurrency = (amount: number, currency = 'USD'): string => 52 | new Intl.NumberFormat('en-US', { 53 | style: 'currency', 54 | currency, 55 | }).format(amount) 56 | 57 | // String formatting 58 | export const toTitleCase = (str: string): string => str.replace(/\w\S*/g, txt => txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()) 59 | 60 | export const toCamelCase = (str: string): string => str.replace(/([-_][a-z])/g, group => group.toUpperCase().replace('-', '').replace('_', '')) 61 | 62 | export const toSnakeCase = (str: string): string => str.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`).replace(/^-/, '') 63 | 64 | // URL formatting 65 | export const slugify = (str: string): string => 66 | str 67 | .toLowerCase() 68 | .replace(/ /g, '-') 69 | .replace(/[^\w-]+/g, '') 70 | 71 | export const getHostname = (url: string): string => new URL(url).hostname 72 | 73 | // turns 'https://cointelegraph.com/abcd' into cointelegraph 74 | export const getDomain = (url: string): string => getHostname(url).replace('www.', '').split('.')[0] 75 | // String manipulation 76 | 77 | export const truncate = (str: string, length = 100, ending = '...'): string => (str.length > length ? str.substring(0, length - ending.length) + ending : str) 78 | 79 | // trucate wallet address to 6 characters on the end 80 | export const truncateWallet = (str: string): string => `${str.slice(0, 6)}...${str.slice(-4)}` 81 | 82 | export const capitalize = (str: string): string => str.charAt(0).toUpperCase() + str.slice(1) 83 | 84 | export const removeWhitespace = (str: string): string => str.replace(/\s/g, '') 85 | 86 | export const removeNonNumeric = (str: string): string => str.replace(/\D/g, '') 87 | 88 | export const removeNonAlphaNumeric = (str: string): string => str.replace(/\W/g, '') 89 | 90 | export function addingAmountDecimals(number: number | string, decimals: number): string | null { 91 | if (!isValidNumber(number) || !isValidNumber(decimals)) return null 92 | let bNumber = new BigNumber(number) 93 | 94 | while (!bNumber.isInteger()) { 95 | bNumber = bNumber.times(10) 96 | decimals-- 97 | } 98 | 99 | return bNumber.toString() + '0'.repeat(decimals) 100 | } 101 | 102 | export const secondsConverter = (seconds: number): string => { 103 | if (seconds > 60) return `${Math.round(seconds / 60)}m ${seconds % 60 ? `${Math.round(seconds % 60).toString()}s` : ''}` 104 | return `${seconds}s` 105 | } 106 | 107 | export const numberToFormatString = (number: number, decimals = 4, isTransformNeeded = false): string | null => { 108 | if (number === undefined || number === null) return null 109 | const result = parseFloat(number.toFixed(decimals)) 110 | if (isTransformNeeded && result <= 0.001) return '< 0.01' 111 | return result?.toString() 112 | } 113 | 114 | export function roundNumberByDecimals(number: number | string | undefined | null, decimals = 4): string | null { 115 | if (!isValidNumber(number) || !isValidNumber(decimals)) return null 116 | const bigNumber = new BigNumber(number) 117 | const decimalPart = bigNumber.toString().split('.')[1] 118 | let count = 0 119 | if (decimalPart) { 120 | while (decimalPart[count] === '0') count++ 121 | count++ 122 | } 123 | const factor = Math.max(count, decimals) 124 | return bigNumber 125 | .toFixed(factor) 126 | .toString() 127 | .replace(/\.?0*$/, '') 128 | } 129 | 130 | export function addingTokenDecimals(amount: number | string, decimals: number): string | null { 131 | if (!isValidNumber(amount) || !isValidNumber(decimals)) return null 132 | const number = new BigNumber(amount).dividedBy(BigNumber(10).pow(decimals)).toString() 133 | return roundNumberByDecimals(number, 4) 134 | } 135 | 136 | export const timestampToLocalTime = (timestamp: number): number => { 137 | const currentTime = new Date() 138 | const timeZoneOffsetInSeconds = currentTime.getTimezoneOffset() * 60 139 | return Number(timestamp) - timeZoneOffsetInSeconds 140 | } 141 | interface FormatNumberOptions { 142 | decimals?: number 143 | decimalPlaces?: number 144 | separator?: string 145 | minDigits?: number 146 | disableUnit?: boolean 147 | } 148 | 149 | export function formatNumber(num: number, options: FormatNumberOptions = {}): string { 150 | // console.log('formatNumber', num, options) 151 | let { decimals = 10, decimalPlaces = 4, separator, minDigits = 1, disableUnit = false } = options 152 | if (num === undefined || num === null) return '' 153 | 154 | const op = num < 0 ? '-' : '' 155 | num = Math.abs(num) 156 | 157 | if (num > 1 && !options.decimalPlaces) decimalPlaces = 2 158 | 159 | if (num < 0.001 && num > 0) { 160 | return '< 0.001' 161 | } 162 | 163 | let unit = '' 164 | let factor = 1 165 | 166 | if (!separator && !disableUnit) { 167 | if (num >= 1e9) { 168 | unit = 'B' 169 | factor = 1e9 170 | } else if (num >= 1e6) { 171 | unit = 'M' 172 | factor = 1e6 173 | } else if (num >= 1e3) { 174 | unit = 'K' 175 | factor = 1e3 176 | } 177 | } 178 | 179 | if (disableUnit && decimals) { 180 | factor = 10 ** decimals 181 | } 182 | 183 | let formattedNumber = num / factor 184 | const roundingFactor = 10 ** decimals 185 | formattedNumber = Math.round(formattedNumber * roundingFactor) / roundingFactor 186 | 187 | let [intPart, decPart] = formattedNumber.toFixed(decimalPlaces ?? decimals).split('.') 188 | 189 | if (separator && !unit) { 190 | const regex = /\B(?=(\d{3})+(?!\d))/g 191 | intPart = intPart.replace(regex, separator) 192 | } 193 | 194 | if (decPart && minDigits > 0) { 195 | while (decPart.length < minDigits) { 196 | decPart += '0' 197 | } 198 | } 199 | 200 | let result = `${op}${intPart}${decPart ? '.' : ''}${decPart || ''}` 201 | 202 | if (unit) { 203 | result += ` ${unit}` 204 | } 205 | 206 | return result 207 | } 208 | 209 | // // Tests 210 | const tests = [ 211 | { num: 1234567890, options: { decimals: 0 }, expected: '1 B' }, 212 | { num: 12345678, options: { separator: "'", decimals: 0 }, expected: "12'345'678" }, 213 | { num: 12345678, options: { decimals: 2 }, expected: '12.35 M' }, 214 | { num: 123456, options: { decimals: 1 }, expected: '123.5 K' }, 215 | { num: 0.12345678, options: { decimals: 2 }, expected: '0.12' }, 216 | { num: 0.00012345678, options: { decimals: 3 }, expected: '< 0.001' }, 217 | // eth token numbers with 18 decimals 218 | { num: 253218960916491300, options: { decimals: 18, decimalPlaces: 4, disableUnit: true }, expected: '1.2345' }, 219 | { num: 1000000, options: { decimals: 6, decimalPlaces: 2, disableUnit: true }, expected: '1.00' }, 220 | ] 221 | 222 | for (const test of tests) { 223 | const result = formatNumber(test.num, test.options) 224 | } 225 | -------------------------------------------------------------------------------- /src/utils/initPosthog.ts: -------------------------------------------------------------------------------- 1 | import posthog from 'posthog-js' 2 | import { config } from '../constants/config' 3 | 4 | export function initPosthog() { 5 | if (!process.env.DEVELOPMENT) { 6 | posthog.init(config.POSTHOG_API_KEY, { 7 | api_host: config.POSTHOG_HOST, 8 | }) 9 | localStorage.setItem('app-concero-session-id', posthog.get_session_id()) 10 | localStorage.setItem('app-concero-replay-id', posthog.get_distinct_id()) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/utils/localStorage.ts: -------------------------------------------------------------------------------- 1 | export const setItem = (key: string, value: any): void => { 2 | localStorage.setItem(key, JSON.stringify(value)) 3 | } 4 | 5 | export const getItem = (key: string, defaultValue: T): T => { 6 | const storedValue = localStorage.getItem(key) 7 | if (storedValue === null) return defaultValue 8 | return JSON.parse(storedValue) as T 9 | } 10 | 11 | export const removeItem = (key: string): void => { 12 | localStorage.removeItem(key) 13 | } 14 | 15 | export const isItemSet = (key: string): boolean => localStorage.getItem(key) !== null 16 | 17 | export const clearStorage = (): void => { 18 | localStorage.clear() 19 | } 20 | 21 | export const getStorageLength = (): number => JSON.stringify(localStorage).length 22 | 23 | export const getStorageRemaining = (): number => 5242880 - getStorageLength() 24 | -------------------------------------------------------------------------------- /src/utils/objectUtils.ts: -------------------------------------------------------------------------------- 1 | // Array utilities 2 | export const arrayUnique = (array: T[]): T[] => [...new Set(array)] 3 | 4 | export const arrayRemove = (array: T[], value: T): T[] => array.filter(item => item !== value) 5 | 6 | export const arrayToObject = (array: T[], key: keyof T): Record => 7 | array.reduce>((accumulator, item) => { 8 | accumulator[String(item[key])] = item 9 | return accumulator 10 | }, {}) 11 | 12 | // Object utilities 13 | export const objectToArray = (object: Record): T[] => Object.values(object) 14 | 15 | export const objectDeepMerge = (target: Record, source: Record): Record => { 16 | const output = { ...target } 17 | for (const key in source) { 18 | if (source.hasOwnProperty(key)) { 19 | if (isObject(source[key]) && isObject(target[key])) { 20 | output[key] = objectDeepMerge(target[key], source[key]) 21 | } else { 22 | output[key] = source[key] 23 | } 24 | } 25 | } 26 | return output 27 | } 28 | 29 | export const isObject = (item: any): boolean => item && typeof item === 'object' && !Array.isArray(item) 30 | -------------------------------------------------------------------------------- /src/utils/retryRequest.ts: -------------------------------------------------------------------------------- 1 | interface Options { 2 | retryCount?: number 3 | throwCondition?: (e: any) => boolean 4 | } 5 | 6 | export async function retryRequest(request: (i: number) => Promise, options: Options): Promise { 7 | const { retryCount = 3, throwCondition = () => false } = options 8 | let error = 'Unknown error' 9 | 10 | for (let i = 0; i < retryCount; i++) { 11 | try { 12 | const response = await request(i) 13 | if (response) return response 14 | } catch (e: any) { 15 | console.error(e) 16 | if (throwCondition(e)) throw e 17 | error = e 18 | } 19 | } 20 | 21 | throw new Error(error) 22 | } 23 | -------------------------------------------------------------------------------- /src/utils/storage.ts: -------------------------------------------------------------------------------- 1 | import * as localStorageUtils from './localStorage' 2 | import * as cookieUtils from './cookies' 3 | 4 | export type StorageType = 'localStorage' | 'cookie' 5 | 6 | export const setItem = (key: string, value: any, storageType: StorageType = 'localStorage'): void => { 7 | if (storageType === 'localStorage') { 8 | localStorageUtils.setItem(key, value) 9 | } else if (storageType === 'cookie') { 10 | cookieUtils.setCookie(key, JSON.stringify(value)) 11 | } 12 | } 13 | 14 | export const getItem = (key: string, defaultValue: T, storageType: StorageType = 'localStorage'): T => { 15 | if (storageType === 'localStorage') { 16 | return localStorageUtils.getItem(key, defaultValue) 17 | } 18 | if (storageType === 'cookie') { 19 | const cookieValue = cookieUtils.getCookie(key) 20 | return cookieValue ? JSON.parse(cookieValue) : defaultValue 21 | } 22 | return defaultValue 23 | } 24 | 25 | export const removeItem = (key: string, storageType: StorageType = 'localStorage'): void => { 26 | if (storageType === 'localStorage') { 27 | localStorageUtils.removeItem(key) 28 | } else if (storageType === 'cookie') { 29 | cookieUtils.deleteCookie(key) 30 | } 31 | } 32 | 33 | export const clearStorage = (storageType: StorageType = 'localStorage'): void => { 34 | if (storageType === 'localStorage') { 35 | localStorageUtils.clearStorage() 36 | } else if (storageType === 'cookie') { 37 | const allCookies = cookieUtils.getAllCookies() 38 | for (const key in allCookies) { 39 | cookieUtils.deleteCookie(key) 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/utils/validation.ts: -------------------------------------------------------------------------------- 1 | // Email validation 2 | export const isValidEmail = (email: string): boolean => { 3 | const emailRegex = /^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,7}$/ 4 | return emailRegex.test(email) 5 | } 6 | 7 | // Phone number validation (simplified, may not cover all cases) 8 | export const isValidPhoneNumber = (phoneNumber: string): boolean => { 9 | const phoneRegex = /^\+?[\d\s\-()]{7,}$/ 10 | return phoneRegex.test(phoneNumber) 11 | } 12 | 13 | // Password validation (example: at least 8 characters, 1 uppercase letter, 1 lowercase letter, 1 number) 14 | export const isValidPassword = (password: string): boolean => { 15 | const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,}$/ 16 | return passwordRegex.test(password) 17 | } 18 | 19 | // Password strength level (0-4) 20 | export const passwordStrengthLevel = (password: string): number => { 21 | let strength = 0 22 | if (password.length >= 12) strength++ 23 | if (/[a-z]/.test(password)) strength++ 24 | if (/[A-Z]/.test(password)) strength++ 25 | if (/[0-9]/.test(password)) strength++ 26 | if (/[ `!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?~]/.test(password)) strength++ 27 | return strength 28 | } 29 | 30 | // Non-empty string validation 31 | export const isNotEmpty = (str: string): boolean => str.length > 0 32 | 33 | // Numeric validation 34 | export const isNumeric = (num: string): boolean => !isNaN(parseFloat(num)) && isFinite(Number(num)) 35 | 36 | export const isDigit = (num: string): boolean => /^\d+$/.test(num) 37 | 38 | // Float validation 39 | export const isFloat = (num: string): boolean => { 40 | const floatRegex = /^-?\d*(\.\d+)?$/ 41 | return floatRegex.test(num) 42 | } 43 | 44 | export const isFloatInput = (num: string): boolean => { 45 | const floatRegex = /^(?!00)\d+(\.\d*)?$/ 46 | return floatRegex.test(num) 47 | } 48 | // Non-numeric validation 49 | export const isNotNumeric = (str: string): boolean => !/\d/.test(str) 50 | 51 | // URL validation 52 | export const isValidURL = (url: string): boolean => { 53 | const urlRegex = /^(https?:\/\/)?([\da-z.-]+)\.([a-z.]{2,6})([/\w .-]*)*\/?$/ 54 | return urlRegex.test(url) 55 | } 56 | 57 | // IP address validation 58 | export const isValidIPAddress = (ipAddress: string): boolean => { 59 | const ipAddressRegex = /^([0-9]{1,3}\.){3}[0-9]{1,3}$/ 60 | return ipAddressRegex.test(ipAddress) 61 | } 62 | 63 | // Credit card validation 64 | export const isValidCreditCard = (creditCard: string): boolean => { 65 | const creditCardRegex = /^([0-9]{4}-){3}[0-9]{4}$/ 66 | return creditCardRegex.test(creditCard) 67 | } 68 | 69 | // Hex color validation 70 | export const isValidHexColor = (hexColor: string): boolean => { 71 | const hexColorRegex = /^#([0-9a-f]{3}){1,2}$/i 72 | return hexColorRegex.test(hexColor) 73 | } 74 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "lib": [ 5 | "DOM", 6 | "DOM.Iterable", 7 | "ESNext", 8 | "es2015.promise" 9 | ], 10 | "plugins": [ 11 | { 12 | "name": "typescript-plugin-css-modules", 13 | "options": { 14 | "postcssOptions": { 15 | "useConfig": true 16 | } 17 | } 18 | } 19 | ], 20 | "module": "ESNext", 21 | "skipLibCheck": true, 22 | /* Bundler mode */ 23 | "moduleResolution": "node", 24 | "allowImportingTsExtensions": false, 25 | "resolveJsonModule": true, 26 | "isolatedModules": true, 27 | "noEmit": true, 28 | "jsx": "react-jsx", 29 | "types": [ 30 | "vitest/globals" 31 | ], 32 | /* Linting */ 33 | "strict": true, 34 | "noUnusedLocals": true, 35 | "noUnusedParameters": true, 36 | "noFallthroughCasesInSwitch": true, 37 | "allowSyntheticDefaultImports": true 38 | }, 39 | "include": [ 40 | "src" 41 | ], 42 | "references": [ 43 | { 44 | "path": "./tsconfig.node.json" 45 | } 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["vite.config.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import stylelint from 'vite-plugin-stylelint' 3 | import react from '@vitejs/plugin-react-swc' 4 | import precss from 'precss' 5 | import EnvironmentPlugin from 'vite-plugin-environment' 6 | 7 | export default defineConfig({ 8 | plugins: [ 9 | react(), 10 | stylelint({ 11 | fix: true, 12 | include: ['./src/**/*.css', './src/**/*.pcss'], 13 | configFile: './.stylelintrc.json', 14 | emitErrorAsWarning: true, 15 | }), 16 | EnvironmentPlugin('all'), 17 | ], 18 | css: { 19 | postcss: { 20 | plugins: [precss()], 21 | }, 22 | }, 23 | build: { 24 | outDir: './dist', 25 | emptyOutDir: true, 26 | }, 27 | }) 28 | -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitest/config' 2 | import react from '@vitejs/plugin-react' 3 | 4 | export default defineConfig({ 5 | plugins: [react()], 6 | test: { 7 | globals: true, 8 | environment: 'jsdom', 9 | css: true, 10 | setupFiles: ['./src/__tests__/setup.ts'], 11 | }, 12 | }) 13 | --------------------------------------------------------------------------------