This commit is contained in:
Kakabay 2025-01-29 13:40:38 +05:00
parent 6022ebce64
commit 17b0691c85
59 changed files with 5585 additions and 0 deletions

24
.gitignore vendored Normal file
View File

@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

21
components.json Normal file
View File

@ -0,0 +1,21 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "tailwind.config.js",
"css": "src/index.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"iconLibrary": "lucide"
}

28
eslint.config.js Normal file
View File

@ -0,0 +1,28 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
export default tseslint.config(
{ ignores: ['dist'] },
{
extends: [js.configs.recommended, ...tseslint.configs.recommended],
files: ['**/*.{ts,tsx}'],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
plugins: {
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
},
rules: {
...reactHooks.configs.recommended.rules,
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
},
)

13
index.html Normal file
View File

@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>

52
package.json Normal file
View File

@ -0,0 +1,52 @@
{
"name": "turkmen-textile",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"@hookform/resolvers": "^3.10.0",
"@radix-ui/react-dialog": "^1.1.5",
"@radix-ui/react-label": "^2.1.1",
"@radix-ui/react-popover": "^1.1.4",
"@radix-ui/react-radio-group": "^1.2.2",
"@radix-ui/react-slot": "^1.1.1",
"axios": "^1.7.9",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"embla-carousel-react": "^8.5.2",
"lucide-react": "^0.473.0",
"motion": "^12.0.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-hook-form": "^7.54.2",
"react-router-dom": "^7.1.3",
"tailwind-merge": "^2.6.0",
"tailwindcss-animate": "^1.0.7",
"usehooks-ts": "^3.1.0",
"zod": "^3.24.1",
"zustand": "^5.0.3"
},
"devDependencies": {
"@eslint/js": "^9.17.0",
"@types/node": "^22.12.0",
"@types/react": "^18.3.18",
"@types/react-dom": "^18.3.5",
"@vitejs/plugin-react-swc": "^3.5.0",
"autoprefixer": "^10.4.20",
"eslint": "^9.17.0",
"eslint-plugin-react-hooks": "^5.0.0",
"eslint-plugin-react-refresh": "^0.4.16",
"globals": "^15.14.0",
"postcss": "^8.5.1",
"tailwindcss": "^3.4.17",
"typescript": "~5.6.2",
"typescript-eslint": "^8.18.2",
"vite": "^6.0.5"
}
}

3495
pnpm-lock.yaml Normal file

File diff suppressed because it is too large Load Diff

6
postcss.config.js Normal file
View File

@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

45
public/logo.svg Normal file
View File

@ -0,0 +1,45 @@
<svg width="257" height="64" viewBox="0 0 257 64" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_57_251)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M89.535 25.9779H84.5608V8.97425H83.6133C82.429 8.97425 81.2447 9.21041 80.2972 9.9189C79.3498 10.6274 78.876 11.572 78.6392 12.7528L78.876 7.32111H94.9829L95.2198 12.7528C94.9829 11.572 94.5092 10.6274 93.5617 9.9189C92.6143 9.21041 91.6668 8.97425 90.2456 8.97425H89.2981V25.9779H89.535Z" fill="#FCC46A"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M103.036 21.7269V13.4613H107.3V22.9078C107.3 23.3801 107.537 23.8524 107.774 24.0886C108.01 24.3247 108.484 24.5609 109.195 24.5609C109.905 24.5609 110.142 24.5609 110.616 24.3247C110.379 24.7971 109.905 25.2694 109.195 25.7417C108.484 25.9779 107.774 26.214 106.826 26.214C105.168 26.214 104.221 25.5055 103.51 24.3247C102.563 25.5055 101.141 26.214 99.0095 26.214C97.8252 26.214 96.8778 25.9779 95.9303 25.2694C95.2197 24.5609 94.746 23.6162 94.746 22.1993V15.5867C94.746 14.4059 94.2722 13.6974 93.0879 13.4613H99.0095V21.9631C99.0095 23.6162 99.7202 24.3247 101.141 24.3247C101.852 24.3247 102.326 24.0886 102.563 23.6162C103.036 23.1439 103.036 22.6716 103.036 21.7269Z" fill="#FCC46A"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M113.932 25.978H109.906V15.3507C109.906 14.1699 109.432 13.4614 108.248 13.2252H113.932V15.3507C114.169 14.6422 114.643 14.1699 115.354 13.6976C115.827 13.2252 116.538 12.9891 117.248 12.9891C117.485 12.9891 117.722 12.9891 117.959 12.9891C118.196 12.9891 118.433 12.9891 118.433 13.2252C118.67 13.2252 118.67 13.4614 118.907 13.4614L118.433 17.24C117.722 16.0592 117.012 15.3507 116.064 15.3507C115.59 15.3507 114.88 15.5869 114.643 16.2954C114.169 16.7677 114.169 17.4762 114.169 18.1847V25.978H113.932Z" fill="#FCC46A"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M134.303 24.3248C133.829 25.5057 132.408 26.2141 130.75 26.2141C129.802 26.2141 129.092 25.978 128.381 25.7418C127.907 25.2695 127.197 24.7972 126.723 24.0887L124.591 20.5462L123.644 21.2547V25.978H119.38V10.3913C119.38 9.21045 118.906 8.50196 117.722 8.2658H123.644V19.1293L125.065 17.9485L126.96 16.0592C127.434 15.3507 127.907 14.8783 127.907 14.6422C127.907 14.406 127.907 14.1699 127.671 13.9337C127.434 13.6975 127.197 13.6975 127.197 13.6975C126.96 13.6975 126.96 13.6975 126.723 13.4614H132.171L127.907 17.9485L131.224 22.9079C131.934 24.0887 132.882 24.561 133.829 24.561C133.829 24.561 134.066 24.561 134.303 24.3248Z" fill="#FCC46A"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M149.463 22.9078V17.476C149.463 15.8229 148.989 15.1144 147.805 15.1144C147.094 15.1144 146.62 15.3506 146.147 15.8229C145.673 16.2952 145.436 17.0037 145.436 17.9484V25.9779H141.172V17.476C141.172 15.8229 140.699 15.1144 139.514 15.1144C138.804 15.1144 138.33 15.3506 137.856 15.8229C137.619 16.2952 137.383 17.0037 137.383 17.9484V25.9779H133.119V15.5867C133.119 14.4059 132.645 13.6974 131.461 13.4613H137.383V15.1144C138.33 13.9336 139.751 13.4613 141.646 13.4613C143.541 13.4613 144.725 14.1698 145.199 15.5867C146.384 14.1698 147.805 13.4613 149.7 13.4613C150.884 13.4613 151.831 13.6974 152.542 14.4059C153.253 15.1144 153.49 16.0591 153.49 17.2399V22.9078C153.49 23.3801 153.726 23.8524 153.963 24.0886C154.2 24.3247 154.674 24.5609 155.384 24.5609C156.095 24.5609 156.332 24.5609 156.806 24.3247C156.569 24.7971 156.095 25.2694 155.384 25.7417C154.674 25.9779 153.963 26.214 153.016 26.214C151.831 26.214 150.884 25.9779 150.41 25.2694C149.937 24.7971 149.463 23.8524 149.463 22.9078Z" fill="#FCC46A"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M167.938 22.9078C167.701 23.3802 167.465 23.8525 167.228 24.0886C166.043 25.5056 164.148 26.4503 161.543 26.4503C159.648 26.4503 157.99 25.9779 156.806 24.7971C155.621 23.6163 155.147 22.1993 155.147 20.0739C155.147 17.9484 155.858 16.2953 157.279 15.1145C158.7 13.6975 160.359 13.2252 162.49 13.2252C162.964 13.2252 163.675 13.2252 164.148 13.4613C164.622 13.4613 165.333 13.6975 165.806 13.9337C166.28 14.1698 166.754 14.406 166.991 14.8783C167.228 15.3506 167.464 15.823 167.464 16.5314C167.464 17.2399 167.228 17.9484 166.754 18.6569C166.28 19.3654 165.57 19.6016 164.622 20.0739C163.675 20.31 162.964 20.5462 162.253 20.7824C161.543 21.0185 160.832 21.0185 159.885 21.2547C160.122 22.4355 160.359 23.3802 161.069 23.8525C161.78 24.561 162.727 24.7971 163.912 24.7971C165.57 24.3248 166.754 23.8525 167.938 22.9078ZM159.885 19.8377C160.595 19.8377 161.543 19.6016 162.253 19.3654C162.727 18.8931 163.201 18.6569 163.438 18.1846C163.675 17.7123 163.912 17.0038 163.912 16.2953C163.912 15.823 163.675 15.3506 163.438 14.8783C163.201 14.406 162.727 14.1698 162.253 14.1698C161.78 14.1698 161.306 14.406 161.069 14.6421C160.832 14.8783 160.359 15.3506 160.359 16.0591C160.122 16.5314 160.122 17.2399 160.122 17.7123C160.122 18.1846 160.122 18.6569 160.122 19.1292C159.885 19.3654 159.885 19.6016 159.885 19.8377Z" fill="#FCC46A"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M177.412 22.9078V17.476C177.412 15.8229 176.702 15.1144 175.517 15.1144C174.807 15.1144 174.333 15.3506 173.859 15.8229C173.386 16.2952 173.149 17.0037 173.149 17.9484V25.9779H168.885V15.5867C168.885 14.4059 168.411 13.6974 167.227 13.4613H173.149V15.1144C174.333 13.9336 175.517 13.4613 177.412 13.4613C178.597 13.4613 179.544 13.6974 180.492 14.4059C181.202 15.1144 181.676 16.0591 181.676 17.2399V22.9078C181.676 23.3801 181.913 23.8524 182.15 24.0886C182.387 24.3247 182.86 24.5609 183.571 24.5609C184.281 24.5609 184.518 24.5609 184.992 24.3247C184.755 24.7971 184.281 25.2694 183.571 25.7417C182.86 25.9779 182.15 26.214 181.202 26.214C180.018 26.214 179.07 25.9779 178.597 25.2694C177.886 24.7971 177.412 23.8524 177.412 22.9078Z" fill="#FCC46A"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M193.993 25.9779H189.019V8.97425H188.071C186.887 8.97425 185.703 9.21041 184.755 9.9189C183.808 10.6274 183.334 11.572 183.097 12.7528L183.334 7.32111H199.441L199.678 12.7528C199.441 11.572 198.967 10.6274 198.02 9.9189C197.072 9.21041 196.125 8.97425 194.704 8.97425H193.756V25.9779H193.993Z" fill="#FCC46A"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M211.284 22.9078C211.048 23.3802 210.811 23.8525 210.574 24.0886C209.389 25.5056 207.495 26.4503 204.889 26.4503C202.994 26.4503 201.336 25.9779 200.152 24.7971C198.967 23.6163 198.494 22.1993 198.494 20.0739C198.494 17.9484 199.204 16.2953 200.625 15.1145C202.047 13.6975 203.705 13.2252 205.837 13.2252C206.31 13.2252 207.021 13.2252 207.495 13.4613C207.968 13.4613 208.679 13.6975 209.153 13.9337C209.626 14.1698 210.1 14.406 210.337 14.8783C210.811 15.1145 210.811 15.5868 210.811 16.2953C210.811 17.0038 210.574 17.7123 210.1 18.4207C209.626 18.8931 208.916 19.3654 207.968 19.8377C207.021 20.0739 206.31 20.31 205.6 20.5462C204.889 20.7824 204.178 20.7824 203.231 21.0185C203.468 22.1993 203.705 23.144 204.415 23.6163C205.126 24.3248 206.073 24.561 207.258 24.561C208.679 24.3248 210.1 23.8525 211.284 22.9078ZM202.994 19.8377C203.705 19.8377 204.652 19.6016 205.363 19.3654C206.073 19.1292 206.547 18.6569 206.784 18.1846C207.021 17.7123 207.258 17.0038 207.258 16.2953C207.258 15.823 207.021 15.3506 206.784 14.8783C206.31 14.406 205.836 14.1698 205.363 14.1698C204.889 14.1698 204.415 14.406 204.178 14.6421C203.942 14.8783 203.468 15.3506 203.468 16.0591C203.231 16.5314 203.231 17.2399 203.231 17.7123C203.231 18.1846 203.231 18.6569 203.231 19.1292C202.994 19.3654 202.994 19.6016 202.994 19.8377Z" fill="#FCC46A"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M219.101 18.6568L224.075 25.9779H219.101L216.258 21.4908L212.468 25.9779H210.573L215.311 20.0738L212.231 15.1144C211.758 14.6421 211.521 14.1698 211.284 13.9336C211.047 13.6974 210.573 13.4613 210.1 13.4613H215.548L216.495 14.8782L218.153 17.2399L219.101 16.0591C219.574 15.5867 219.811 15.1144 219.811 14.6421C219.811 14.4059 219.811 14.1698 219.574 13.9336C219.337 13.6974 219.101 13.4613 218.864 13.4613H223.127L219.101 18.6568Z" fill="#FCC46A"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M224.312 22.4355V16.0592C224.312 15.1145 223.839 14.406 222.654 14.406L228.576 10.3913V13.4614H231.181L230.471 14.8784H228.576V21.9632C228.576 22.6717 228.813 23.3802 229.287 23.8525C229.76 24.3248 230.471 24.561 231.181 24.561C231.892 24.561 232.366 24.561 232.84 24.3248C232.603 25.0333 231.892 25.5057 231.181 25.978C230.471 26.4503 229.523 26.6865 228.339 26.6865C226.918 26.6865 225.97 26.4503 225.26 25.7418C224.786 24.561 224.312 23.6164 224.312 22.4355Z" fill="#FCC46A"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M235.919 7.55734C236.392 8.02967 236.629 8.50199 236.629 8.97432C236.629 9.44664 236.392 10.1551 235.919 10.3913C235.445 10.8636 234.971 10.8636 234.261 10.8636C233.55 10.8636 233.076 10.6275 232.602 10.3913C232.129 10.3913 232.129 9.91897 232.129 9.21048C232.129 8.50199 232.366 8.02967 232.602 7.79351C233.076 7.32118 233.55 7.08502 234.261 7.08502C234.971 7.08502 235.445 7.32118 235.919 7.55734ZM236.392 25.978H232.129V15.5869C232.129 14.4061 231.655 13.6976 230.471 13.4614H236.392V25.978Z" fill="#FCC46A"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M243.024 25.978H238.761V10.3913C238.761 9.21045 238.287 8.50196 237.103 8.2658H243.024V25.978Z" fill="#FCC46A"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M256.999 22.9078C256.762 23.3802 256.526 23.8525 256.289 24.0886C255.104 25.5056 253.209 26.4503 250.604 26.4503C248.709 26.4503 247.051 25.9779 245.867 24.7971C244.682 23.6163 244.208 22.1993 244.208 20.0739C244.208 17.9484 244.919 16.2953 246.34 15.1145C247.761 13.6975 249.42 13.2252 251.551 13.2252C252.025 13.2252 252.736 13.2252 253.209 13.4613C253.683 13.4613 254.394 13.6975 254.867 13.9337C255.341 14.1698 255.815 14.406 256.052 14.8783C256.289 15.3506 256.526 15.823 256.526 16.5314C256.526 17.2399 256.289 17.9484 255.578 18.6569C254.867 19.3654 254.394 19.6016 253.446 20.0739C252.499 20.31 251.788 20.5462 251.078 20.7824C250.367 21.0185 249.656 21.0185 248.709 21.2547C248.946 22.4355 249.183 23.3802 249.893 23.8525C250.604 24.561 251.551 24.7971 252.736 24.7971C254.631 24.3248 255.815 23.8525 256.999 22.9078ZM248.709 19.8377C249.42 19.8377 250.367 19.6016 251.078 19.3654C251.788 19.1292 252.262 18.6569 252.499 18.1846C252.736 17.7123 252.973 17.0038 252.973 16.2953C252.973 15.823 252.736 15.3506 252.499 14.8783C252.262 14.406 251.788 14.1698 251.314 14.1698C250.841 14.1698 250.367 14.406 250.13 14.6421C249.893 14.8783 249.42 15.3506 249.42 16.0591C249.183 16.5314 249.183 17.2399 249.183 17.7123C249.183 18.1846 249.183 18.6569 249.183 19.1292C248.709 19.3654 248.709 19.6016 248.709 19.8377Z" fill="#FCC46A"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M102.326 50.3026L101.615 56.9152H85.5084V37.5499C85.5084 36.3691 85.2715 35.4244 84.7978 34.9521C84.3241 34.4798 83.6135 34.0074 82.666 33.7713H100.905L100.431 40.3838C99.4835 37.3137 97.5886 35.6606 94.5093 35.6606H91.1932V43.4539H95.6937C96.6411 43.4539 97.3517 42.9816 97.5886 42.2731V46.9964C97.3517 46.0517 96.6411 45.5794 95.6937 45.5794H91.1932V55.0259H95.6937C97.1149 55.0259 98.5361 54.5536 99.7204 53.6089C101.142 52.6643 101.852 51.4834 102.326 50.3026Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M116.537 43.2178L125.301 56.9152H117.722L112.274 48.1772L105.878 56.9152H102.799L110.852 46.0517L105.168 36.8414C104.22 35.1882 103.273 34.2436 102.088 33.7713H110.379C110.616 34.0074 112.274 36.6052 115.353 41.3285L117.248 38.7307C118.195 37.5499 118.669 36.6052 118.669 35.8967C118.669 34.9521 118.195 34.2436 117.485 33.7713H123.643L116.537 43.2178Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M132.645 46.9964V56.9152H126.724V38.0223C126.724 36.8414 126.487 36.133 126.25 35.4245C125.776 34.9521 125.302 34.716 124.355 34.4798C128.619 33.7713 132.172 33.5352 135.488 33.5352C141.646 33.5352 144.489 35.6606 144.489 39.9116C144.489 41.0924 144.252 42.037 143.778 42.9817C143.304 43.9263 142.831 44.6348 142.12 45.1071C141.409 45.5795 140.699 46.0518 139.751 46.2879C138.804 46.5241 137.856 46.7603 136.909 46.9964C135.961 47.2326 135.251 47.2326 134.303 47.2326H132.645V46.9964ZM132.645 45.5795H133.593C135.014 45.5795 136.198 45.1071 136.909 44.1625C137.619 43.2178 138.093 41.8009 138.093 39.9116C138.093 38.2584 137.856 37.0776 137.146 36.133C136.435 35.1883 135.725 34.716 134.54 34.716C133.83 34.716 133.356 34.9521 133.119 35.1883C132.645 35.4245 132.645 35.8968 132.645 36.3691V45.5795Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M153.725 55.0259C154.436 55.7344 155.384 55.9706 156.568 55.9706C157.752 55.9706 158.7 55.7344 159.41 55.0259C160.121 54.3174 160.831 53.3728 161.068 52.192C161.305 51.0112 161.542 49.8304 161.779 48.8857C161.779 47.9411 162.016 46.7603 162.016 45.5794C162.016 38.2584 160.121 34.716 156.568 34.716C153.015 34.716 151.12 38.2584 151.12 45.5794C151.12 46.7603 151.12 47.9411 151.357 48.8857C151.357 49.8304 151.594 51.0112 152.067 52.192C152.304 53.3728 153.015 54.3174 153.725 55.0259ZM165.332 54.0813C163.2 56.4429 160.358 57.6237 156.805 57.6237C153.252 57.6237 150.409 56.4429 148.278 54.0813C146.146 51.7197 144.961 48.8857 144.961 45.3433C144.961 41.8008 146.146 38.9669 148.278 36.6053C150.409 34.2436 153.252 33.0628 156.805 33.0628C160.358 33.0628 163.2 34.2436 165.332 36.6053C167.464 38.9669 168.648 41.8008 168.648 45.3433C168.648 48.8857 167.464 51.7197 165.332 54.0813Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M204.416 56.9152H190.915V56.4428C191.625 55.0259 193.283 52.9004 195.652 49.8303C198.494 46.524 199.679 43.6901 199.679 41.0923C199.679 39.9115 199.205 38.7307 198.494 38.0222C197.784 37.3137 196.836 36.8414 195.415 36.8414C193.52 36.8414 191.862 37.3137 190.678 38.4945V38.2583C191.151 37.0775 192.099 35.8967 193.52 34.7159C194.941 33.7712 196.363 33.2989 198.257 33.2989C200.152 33.2989 201.574 33.7712 202.758 34.9521C203.942 35.8967 204.653 37.3137 204.653 39.203C204.653 41.8008 203.232 44.6347 200.152 47.7048L196.836 51.0111L195.178 52.6642H202.284C202.995 52.6642 203.942 52.4281 204.653 51.9557C205.363 51.4834 205.837 51.0111 206.311 50.0664L204.416 56.9152Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M216.022 55.7344C217.206 55.7344 217.917 55.0259 218.391 53.3728C218.864 51.7197 219.101 48.8857 219.101 44.871C219.101 41.5647 218.864 38.9669 218.391 37.3138C217.917 35.6606 217.206 34.9521 216.022 34.9521C213.89 34.9521 212.706 38.2584 212.706 44.871C212.706 48.6496 212.943 51.2474 213.416 53.1367C213.89 55.0259 214.838 55.7344 216.022 55.7344ZM216.022 57.3876C214.601 57.3876 213.18 57.1514 212.232 56.4429C211.048 55.7344 210.1 54.7898 209.39 53.609C208.679 52.4282 207.968 51.2474 207.732 49.8304C207.258 48.4134 207.021 46.9964 207.021 45.5795C207.021 43.6902 207.258 41.5647 207.968 39.9116C208.679 38.0223 209.627 36.6053 211.048 35.4245C212.469 34.2437 214.127 33.5352 216.022 33.5352C217.917 33.5352 219.575 34.2437 220.996 35.4245C222.417 36.6053 223.365 38.0223 224.075 39.9116C224.786 41.8009 225.023 43.6902 225.023 45.5795C225.023 47.7049 224.786 49.5942 224.075 51.2474C223.365 53.1367 222.417 54.5536 220.996 55.7344C219.338 56.6791 217.917 57.3876 216.022 57.3876Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M238.998 56.9152H225.496V56.4428C226.207 55.0259 227.865 52.9004 230.233 49.8303C233.076 46.524 234.26 43.6901 234.26 41.0923C234.26 39.9115 233.786 38.7307 233.076 38.0222C232.365 37.3137 231.418 36.8414 229.997 36.8414C228.102 36.8414 226.444 37.3137 225.259 38.4945V38.2583C225.733 37.0775 226.68 35.8967 228.102 34.7159C229.523 33.7712 230.944 33.2989 232.839 33.2989C234.734 33.2989 236.155 33.7712 237.339 34.9521C238.524 35.8967 239.234 37.3137 239.234 39.203C239.234 41.8008 237.813 44.6347 234.734 47.7048L231.418 51.0111L229.76 52.6642H236.866C237.576 52.6642 238.524 52.4281 239.234 51.9557C239.945 51.4834 240.419 51.0111 240.892 50.0664L238.998 56.9152Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M254.157 38.0222H245.393L244.682 41.8008C245.393 41.8008 246.341 41.8008 247.288 41.8008C249.657 41.8008 251.788 42.5093 253.683 43.9263C255.578 45.3433 256.289 46.9964 256.289 49.358C256.289 51.9558 255.578 53.8451 253.92 55.4983C252.262 56.9152 250.13 57.6237 247.525 57.6237C246.104 57.6237 244.682 57.3876 243.498 56.9152C242.314 56.4429 241.366 55.4983 240.893 54.5536C242.551 55.2621 243.972 55.4983 245.63 55.4983C247.288 55.4983 248.709 55.0259 249.657 54.0813C250.604 53.1366 251.078 51.9558 251.078 50.5388C251.078 48.6496 250.367 47.2326 249.183 46.5241C247.999 45.5794 246.341 45.3433 244.446 45.3433C243.498 45.3433 242.788 45.3433 242.314 45.3433L243.261 41.0924L244.682 34.2436H252.499C253.92 34.2436 254.868 33.7713 255.341 33.0628L254.157 38.0222Z" fill="white"/>
<path d="M186.65 44.1625H174.57V46.9965H186.65V44.1625Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.1592 19.6016C15.1592 19.6016 30.3187 8.02969 34.3454 5.90423C38.609 3.77877 44.0569 3.77877 44.0569 3.77877H45.2413L51.3998 9.91899C51.3998 9.91899 44.7675 13.4614 37.4247 17.7123C30.0818 21.9633 21.3178 31.1736 21.3178 31.1736L14.9224 21.7271L15.1592 19.6016Z" fill="#840D10"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.78985 35.8968C3.78985 35.8968 4.73732 32.5906 6.63225 34.9522C8.52718 37.3138 12.5539 42.9817 12.5539 42.9817L13.5014 48.6496L9.94838 52.192L2.36865 45.5795L3.78985 35.8968Z" fill="#840D10"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.5802 3.77867L20.1332 0.708562C22.5019 -1.4169 28.6604 1.18089 31.9765 3.54251C31.9765 3.54251 36.9507 0.944725 40.2668 0.708562C43.3461 0.236238 44.7673 0.708562 44.7673 0.708562L54.2419 10.3912C54.2419 10.3912 55.1894 12.5167 54.7157 16.0591C54.4788 17.4761 54.0051 18.8931 53.5314 20.5462C54.242 21.4908 55.6631 22.9078 56.8475 24.3248C58.5055 26.4503 58.5055 26.4503 58.5055 26.4503C60.1636 22.4355 60.4005 20.7824 60.4005 16.5314L64.4272 20.31C64.4272 20.31 64.4272 24.561 63.2429 27.6311C62.0585 30.7012 61.5848 31.6458 61.5848 31.6458C61.5848 31.6458 63.4797 35.8968 63.9535 39.203C64.4272 42.7455 63.9535 44.3986 63.9535 44.3986L60.4005 48.6495C60.4005 46.7602 59.6899 38.7307 54.7157 30.9373C53.5314 29.048 52.1102 27.1587 50.9258 25.7418C50.9258 25.7418 49.7415 23.8525 48.3203 22.4355C46.8991 21.0185 42.8724 17.0038 42.8724 17.0038L36.9507 21.2547C36.9507 21.2547 37.8982 22.1993 40.03 24.3248C42.1618 26.4503 46.8991 31.882 46.8991 31.882C48.0834 33.5351 49.5046 35.6606 50.9258 37.7861C54.9525 44.8709 55.4263 51.7196 55.4263 53.6089C52.8208 55.9706 47.136 62.1108 45.241 63.2916C44.0567 64.0001 37.4244 63.2916 35.2926 62.1108C32.924 60.93 32.924 60.93 32.924 60.93C32.924 60.93 28.8973 62.5831 25.5811 63.2916C22.0281 64.0001 21.0807 63.7639 21.0807 63.7639L16.5802 59.9853C16.5802 59.9853 23.2125 60.4576 29.6079 57.1514C36.0032 53.8451 42.3986 48.1772 42.3986 48.1772L47.8466 42.7455C47.8466 42.7455 45.0042 37.7861 43.8198 36.3691C34.8189 46.5241 22.0281 55.0259 11.8429 54.5536L0.473289 44.8709C0.473289 44.8709 -1.42164 41.5646 2.60509 32.8266C2.84195 32.5905 2.84195 32.1182 3.07882 31.882C2.36822 30.2289 1.42075 27.8672 0.710155 25.7418C-0.23731 21.9632 0.710155 19.3654 0.710155 19.3654C0.710155 19.3654 8.28988 11.0997 10.1848 10.1551C12.0797 9.44657 15.8696 9.91889 17.7645 10.6274C18.4751 10.8635 19.1857 11.3359 19.6595 11.572L19.8963 11.3359C23.9231 8.0296 26.5286 6.37646 26.5286 6.37646C22.9756 4.95948 20.3701 4.48716 16.5802 3.77867ZM8.76361 50.3027C9.47421 48.1772 10.1848 46.2879 10.6585 44.1624L5.92121 38.2584C5.92121 38.2584 5.21062 38.9669 4.73688 41.0923C4.26315 43.2178 3.31569 44.8709 4.73688 46.2879C5.92122 47.7049 8.76361 50.3027 8.76361 50.3027ZM21.0807 27.6311C21.0807 27.6311 30.0816 18.1846 37.6613 14.1698C45.4779 10.1551 49.7415 9.91889 49.7415 9.91889C49.7415 9.91889 47.6097 6.84878 45.7148 5.43181C43.8198 4.01483 41.688 4.95949 39.5562 5.66797C37.6613 6.37646 34.582 7.79343 29.1341 11.0997C21.3175 16.0591 17.0539 21.727 17.0539 21.727L21.0807 27.6311ZM4.02628 19.8377C4.02628 19.8377 4.02628 21.2547 4.73688 23.6163C5.44748 25.9779 7.57928 30.2289 11.606 36.3691C15.8696 42.5093 21.3175 47.2325 21.3175 47.2325L27.0023 43.2178C27.0023 43.2178 22.7387 39.9115 19.1857 34.9521C15.3959 29.9927 12.5535 25.5056 11.1323 22.1993C9.71108 18.8931 8.76361 14.8783 8.76361 14.8783C7.10555 16.5314 5.92122 17.7123 4.02628 19.8377ZM24.8705 32.3543L32.2134 39.6754L38.8456 32.3543L31.9765 25.5056L24.8705 32.3543ZM37.4244 58.096L38.6088 58.5683C39.5562 59.0407 43.3461 60.2215 44.2936 59.9853C45.0042 59.7491 48.794 56.2067 49.5046 55.4982C49.2678 55.4982 43.8198 53.3728 43.8198 53.3728C41.688 55.4982 40.03 56.9152 37.4244 58.096Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M19.8965 24.0886C20.3703 24.0886 20.844 23.8525 21.3177 23.8525C21.7915 23.8525 22.2652 23.6163 22.7389 23.6163C22.7389 23.144 22.7389 22.4355 22.9758 21.9632C22.9758 21.4908 23.2127 20.7823 23.2127 20.31C22.7389 20.31 22.2652 20.5462 21.5546 20.5462C21.0809 20.5462 20.6071 20.7823 19.8965 20.7823C19.8965 21.2547 19.8965 21.9632 19.6597 22.4355C19.8965 23.144 19.8965 23.6163 19.8965 24.0886ZM22.2652 22.9078C22.2652 23.144 22.0283 23.144 21.5546 23.144C20.844 23.144 20.844 23.144 20.844 22.1993C20.844 21.727 20.844 21.4908 21.0809 21.4908C21.0809 21.4908 21.3177 21.2547 21.5546 21.2547C22.2652 21.2547 22.5021 21.2547 22.2652 22.1993C22.2652 22.6716 22.2652 22.6716 22.2652 22.9078Z" fill="#EE8900"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M27.2397 17.0038C27.7135 17.0038 28.1872 17.24 28.8978 17.24C29.3715 17.24 30.0821 17.4761 30.5559 17.4761C30.7927 16.7676 30.7927 16.2953 31.0296 15.823C31.2665 15.3507 31.2665 14.6422 31.5033 14.1698C31.0296 14.1698 30.319 13.9337 29.8453 13.9337C29.3715 13.9337 28.6609 13.6975 28.1872 13.6975C27.9503 14.1698 27.9503 14.8783 27.7135 15.3507C27.4766 15.823 27.4766 16.5315 27.2397 17.0038ZM29.8453 16.2953C29.8453 16.5315 29.6084 16.5315 29.1347 16.5315C28.4241 16.2953 28.1872 16.2953 28.4241 15.5868C28.4241 15.1145 28.6609 14.8783 28.6609 14.8783C28.8978 14.8783 29.1347 14.8783 29.3715 14.8783C30.0821 15.1145 30.319 15.1145 30.0821 16.0591C30.0821 16.0591 30.0821 16.2953 29.8453 16.2953Z" fill="#EE8900"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M36.0029 11.336C36.4767 11.5721 37.1873 11.5721 37.661 11.8083C38.1347 12.0445 38.8453 12.0445 39.3191 12.2806C39.5559 11.8083 39.7928 11.336 40.0297 10.8637C40.2665 10.1552 40.5034 9.44668 40.7403 8.97436C40.0297 8.7382 39.5559 8.7382 38.8453 8.50203C38.1347 8.26587 37.661 8.26587 36.9504 8.02971C36.7135 8.50203 36.4767 9.21052 36.2398 9.68284C36.2398 10.1552 36.0029 10.8637 36.0029 11.336ZM38.8453 11.0998C38.6085 11.336 38.3716 11.0998 37.8979 11.0998C36.9504 10.8637 36.9504 10.8637 37.4241 9.91901C37.4241 9.44668 37.661 9.21052 37.8979 9.21052C38.1347 9.21052 38.3716 9.21052 38.8453 9.21052C39.7928 9.44668 39.7928 9.44668 39.3191 10.3913C39.0822 10.6275 38.8453 10.8637 38.8453 11.0998Z" fill="#EE8900"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.21045 43.6902C5.21045 43.9263 5.92105 43.9263 6.63165 43.6902C7.81598 43.2179 7.81598 43.2179 8.05285 44.1625C8.28971 45.1072 8.05285 45.1072 7.34225 45.3433C6.39478 45.5795 6.39478 45.1072 7.34225 44.871C7.57911 44.871 7.81598 44.6348 7.57911 44.3987C7.57911 44.1625 7.10538 44.1625 6.63165 44.3987C5.68418 44.871 5.68418 44.871 5.92105 45.8156C6.15791 46.7603 6.15791 46.7603 7.57911 46.288C8.05285 46.0518 8.52658 46.0518 9.00031 45.8156C9.00031 45.3433 8.76344 44.6348 8.76344 43.9263C8.52658 43.454 8.52658 42.7455 8.52658 42.037C7.81598 42.2732 7.10538 42.5094 6.63165 42.7455C5.92105 42.9817 5.21045 43.454 5.21045 43.6902Z" fill="#FCC46A"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M28.897 15.3506C28.897 15.5867 28.897 15.8229 29.1338 15.8229C29.3707 15.8229 29.3707 15.8229 29.6076 15.8229C29.6076 15.8229 29.6076 15.8229 29.8444 15.5867C29.8444 15.3506 29.8444 15.1144 29.6076 15.1144C29.3707 15.1144 29.3707 15.1144 28.897 15.3506C29.1338 15.3506 29.1338 15.1144 28.897 15.3506Z" fill="#FCC46A"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M23.9233 17.24C23.9233 17.4762 24.397 17.7123 25.1076 17.7123C26.2919 17.9485 26.2919 17.9485 26.0551 18.657C25.8182 19.6016 25.8182 19.6016 24.8707 19.3655C23.9233 19.3655 24.1601 18.657 25.1076 18.8931C25.3445 18.8931 25.5813 18.657 25.5813 18.4208C25.5813 18.1847 25.1076 17.9485 24.6339 17.9485C23.6864 17.9485 23.6864 17.9485 23.4495 18.8931C23.2127 19.8378 23.2127 19.8378 24.8707 20.074C25.3445 20.074 25.8182 20.074 26.5288 20.3101C26.7656 19.8378 26.7656 19.1293 27.0025 18.657C27.2394 18.1847 27.2394 17.4762 27.4762 17.0038C27.0025 17.0038 26.5288 17.0038 25.8182 16.7677C24.6339 16.7677 23.9233 17.0038 23.9233 17.24Z" fill="#FCC46A"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M37.8984 9.91899C37.6615 10.1552 37.8984 10.3913 38.1353 10.3913C38.3721 10.3913 38.3721 10.3913 38.609 10.3913C38.609 10.3913 38.609 10.3913 38.8459 10.1552C39.0827 9.91899 38.8459 9.68283 38.609 9.68283C38.3721 9.68283 38.3721 9.68283 37.8984 9.91899Z" fill="#FCC46A"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M32.2133 11.0998C32.2133 11.3359 32.6871 11.5721 33.3977 11.8083C34.8189 12.0444 34.8189 12.0444 34.3451 12.9891C34.1083 13.9337 33.8714 13.9337 33.1608 13.6976C32.2133 13.4614 32.4502 12.9891 33.3977 13.2252C33.6345 13.2252 33.8714 13.2252 33.8714 12.9891C33.8714 12.7529 33.3977 12.5167 32.9239 12.5167C31.9765 12.5167 31.9765 12.5167 31.5027 13.4614C31.2659 14.406 31.2659 14.406 32.9239 14.6422C33.3977 14.8784 34.1083 14.8784 34.582 15.1145C34.8189 14.6422 35.0557 13.9337 35.0557 13.4614C35.2926 12.5167 35.5295 11.8083 35.7663 11.3359C35.2926 11.0998 34.582 11.0998 34.1083 10.8636C33.1608 10.8636 32.2133 10.8636 32.2133 11.0998Z" fill="#FCC46A"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M41.9246 6.1403C41.6877 6.37646 42.3983 6.61263 43.1089 6.84879C44.5301 7.32111 44.5301 7.32111 44.0564 8.0296C43.5827 8.73809 43.5827 8.73809 42.6352 8.50192C41.6877 8.26576 41.9246 7.79344 42.8721 8.0296C43.3458 8.0296 43.5827 8.0296 43.5827 7.79344C43.5827 7.55727 43.1089 7.32111 42.6352 7.08495C41.6877 7.08495 41.4509 7.08495 40.9771 8.0296C40.5034 8.97425 40.5034 8.97425 42.1615 9.44657C42.6352 9.68274 43.3458 9.9189 43.8195 9.9189C44.2933 9.44657 44.767 8.97425 45.0039 8.50192C45.2407 8.0296 45.4776 7.55727 45.9513 7.08495C45.2407 6.84879 44.767 6.61263 44.0564 6.37646C43.1089 5.90414 42.1615 5.90414 41.9246 6.1403Z" fill="#FCC46A"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M21.0811 22.1994C21.0811 22.4355 21.0811 22.6717 21.3179 22.6717C21.5548 22.6717 21.5548 22.6717 21.7917 22.4355C21.7917 22.4355 21.7917 22.4355 21.7917 22.1994C21.7917 21.9632 21.7917 21.7271 21.5548 21.7271C21.5548 21.7271 21.3179 21.7271 21.3179 21.9632L21.0811 22.1994Z" fill="#FCC46A"/>
</g>
<defs>
<clipPath id="clip0_57_251">
<rect width="257" height="64" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 26 KiB

1
public/vite.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

42
src/App.css Normal file
View File

@ -0,0 +1,42 @@
#root {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.react:hover {
filter: drop-shadow(0 0 2em #61dafbaa);
}
@keyframes logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@media (prefers-reduced-motion: no-preference) {
a:nth-of-type(2) .logo {
animation: logo-spin infinite 20s linear;
}
}
.card {
padding: 2em;
}
.read-the-docs {
color: #888;
}

16
src/App.tsx Normal file
View File

@ -0,0 +1,16 @@
import { Outlet } from "react-router-dom";
import { Footer, Header } from "./components/layout";
function App() {
return (
<main className="flex flex-col min-h-screen">
<Header />
<div className="flex-auto">
<Outlet />
</div>
<Footer />
</main>
);
}
export default App;

View File

@ -0,0 +1,75 @@
import { FC, useState } from "react";
import {
Sheet,
SheetClose,
SheetContent,
SheetHeader,
SheetTrigger,
} from "../ui/sheet";
import { Link } from "react-router-dom";
import { Button } from "../ui/button";
import { navData2 } from "./header";
import { ArrowUpRight } from "lucide-react";
interface Props {
className?: string;
}
export const Burger: FC<Props> = () => {
const [open, setOpen] = useState(false);
return (
<Sheet onOpenChange={() => setOpen(!open)} open={open}>
<SheetTrigger>
<div className="flex flex-col gap-1 lg:hidden items-center justify-center size-10">
<div className="w-[18px] h-0.5 bg-on_secondary_container rounded-[2px]" />
<div className="w-[18px] h-0.5 bg-on_secondary_container rounded-[2px]" />
<div className="w-[18px] h-0.5 bg-on_secondary_container rounded-[2px]" />
</div>
</SheetTrigger>
<SheetContent className="overflow-y-auto">
<SheetClose />
<SheetHeader className="mt-16 flex flex-col gap-2">
<Link to="https://qacis.turkmenexpo.com/" target="_blank">
<Button variant="outline" className="w-full" size={"sm"}>
QACIS 2025
<ArrowUpRight />
</Button>
</Link>
<Link to="">
<Button
variant={"secondary"}
size={"sm"}
className="bg-[#FFAE2A] w-full text-on_teritary hover:bg-[#FFAE2A]/90"
>
Официальная поддержка
</Button>
</Link>
<Link to="/B2B-B2G" onClick={() => setOpen(false)}>
<Button className="text-base w-full" size={"sm"}>
B2B | B2G встречи
</Button>
</Link>
</SheetHeader>
<hr className="border-slate-500/20 my-8" />
<div className="flex flex-col gap-6">
{navData2.map((item) => (
<Link
onClick={() => setOpen(false)}
className="h-10 text-on_surface "
key={item.title}
to={item.link}
>
{item.title}
</Link>
))}
</div>
</SheetContent>
</Sheet>
);
};

View File

@ -0,0 +1,17 @@
import { cn } from "@/lib/utils";
import { FC, PropsWithChildren } from "react";
interface Props {
className?: string;
}
export const Container: FC<PropsWithChildren<Props>> = ({
className,
children,
}) => {
return (
<div className={cn("w-full mx-auto max-w-[1240px] px-4", className)}>
{children}
</div>
);
};

View File

@ -0,0 +1,17 @@
import { FC } from "react";
interface Props {
title: string;
}
export const Cover: FC<Props> = ({ title }) => {
return (
<div className="relative flex items-center h-[216px] w-full justify-center">
<img
src="/b2b-cover.png"
className="-z-10 absolute size-full object-cover top-0 left-0"
/>
<h1 className="text-on_primary md:text-5xl text-3xl">{title}</h1>
</div>
);
};

View File

@ -0,0 +1,26 @@
import { FC } from "react";
import { Container } from "./";
export const Footer: FC = () => {
return (
<footer className="py-5 bg-bg_surface_container">
<Container className="flex flex-col gap-6">
<div className="flex flex-col md:flex-row gap-6 md:items-end md:justify-between items-center">
{/* <Logo /> */}
<div className="flex items-center gap-6">
<img src="/inst.svg" />
<img src="/in.svg" />
<img src="/x.svg" />
</div>
</div>
<hr className="border-outline_v" />
<h5 className="text-base text-center normal text-on_surface_v">
©2025 Все права защищены
</h5>
</Container>
</footer>
);
};

View File

@ -0,0 +1,106 @@
import { FC } from "react";
import { Container, Burger } from "./";
import { ArrowUpRight, MapPin, Smartphone } from "lucide-react";
import { Link } from "react-router-dom";
import { Button } from "../ui/button";
import { Logo } from "../shared";
export const navData = [
{
title: "Медиа",
link: "",
},
{
title: "Контакты",
link: "/contacts",
},
];
export const navData2 = [
{
title: "О выставке",
link: "/about",
},
{
title: "Посетителям",
link: "",
},
{
title: "Экспонентам",
link: "",
},
];
export const Header: FC = () => {
return (
<header>
<div className="h-12 hidden lg:flex bg-primary text-on_primary items-center overflow-hidden">
<Container className="flex items-center justify-between">
<div className="gap-8 flex items-center justify-between">
<div className="flex items-center gap-2">
<MapPin />
<h4 className="text-sm">Ашхабад, Туркменистан</h4>
</div>
<nav className="flex items-center gap-6">
{navData.map(({ title, link }) => (
<Link className="py-2" key={title} to={link}>
{title}
</Link>
))}
</nav>
</div>
<div className="flex items-center gap-6">
<div className="flex items-center gap-2">
<Smartphone size={16} strokeWidth="3px" />
<h4 className="text-sm">+99371871814</h4>
</div>
{/* <LangMenu /> */}
</div>
</Container>
</div>
<div className="bg-white py-2 flex items-center justify-between h-20 overflow-hidden">
<Container className="flex items-center justify-between ">
<div className="flex items-center gap-8">
<Link to="/">
<Logo />
</Link>
<nav className="lg:flex hidden items-center gap-6">
{navData2.map(({ title, link }) => (
<Link key={title} to={link} className="flex items-center gap-2">
{title} <img src="/chevron.svg" />
</Link>
))}
</nav>
</div>
<div className="flex items-center">
{/* <LangMenu className="lg:hidden" /> */}
<Burger />
</div>
<div className="lg:flex hidden items-center gap-2">
<Link to="https://qacis.turkmenexpo.com/" target="_blank">
<Button variant="outline" size={"sm"}>
QACIS 2025
<ArrowUpRight />
</Button>
</Link>
<Button
variant={"secondary"}
size={"sm"}
className="bg-[#FFAE2A] text-on_teritary hover:bg-[#FFAE2A]/90"
>
Официальная поддержка
</Button>
</div>
</Container>
</div>
</header>
);
};

View File

@ -0,0 +1,5 @@
export { Burger } from "./burger";
export { Header } from "./header";
export { Footer } from "./footer";
export { Container } from "./container";
export { Cover } from "./cover";

View File

@ -0,0 +1,26 @@
import { cn } from "@/lib/utils";
import { FC } from "react";
interface Props {
nums: string;
text: string;
className?: string;
}
export const AboutCard: FC<Props> = ({ className, nums, text }) => {
return (
<article
className={cn(
"px-6 py-4 relative bg-bg_surface_container h-[160px] w-full overflow-hidden",
className
)}
>
<img src="/bg-logo.svg" className="absolute top-2 right-0" />
<h2 className="text-primary text-[32px] semibold leading-[130%] mb-4">
{nums}
</h2>
<h4 className="text-on_surface normal text-base">{text}</h4>
</article>
);
};

View File

@ -0,0 +1,47 @@
import { cn } from "@/lib/utils";
import { FC } from "react";
import { Container } from "../container";
import { Button } from "@/components/ui/button";
import { Link } from "react-router-dom";
interface Props {
className?: string;
}
export const AboutBron: FC<Props> = ({ className }) => {
return (
<section
className={cn("md:py-20 py-10 relative overflow-hidden", className)}
>
<img
src="/CTA.png"
className="absolute top-0 left-0 size-full -z-10 object-cover"
/>
<Container>
<h3 className="h2 text-center !text-on_primary mb-6">
Приглашение к участию
</h3>
<p className="text-center md:text-lg text-sm text-primary_04 max-w-[808px] mx-auto mb-10">
Торгово-промышленная палата Туркменистана приглашает бизнес-сообщество
со всего мира присоединиться к этому уникальному событию, которое
станет важным шагом к укреплению позиций Туркменистана на глобальной
экономической арене.
</p>
<div className="flex flex-col md:flex-row items-center gap-6">
<Link to={"/stend-form"} className="w-full">
<Button className="bg-white w-full text-primary hover:bg-white/90">
Забронировать стенд
</Button>
</Link>
<Link to={"/B2B-B2G"} className="w-full">
<Button className="bg-white w-full hover:bg-white/90 text-primary">
B2B | B2G встречи
</Button>
</Link>
</div>
</Container>
</section>
);
};

View File

@ -0,0 +1,37 @@
import { cn } from "@/lib/utils";
import { FC } from "react";
import { Container } from "../container";
interface Props {
className?: string;
}
export const AboutPlace: FC<Props> = ({ className }) => {
return (
<section
className={cn(
"flex items-center gap-6 relative md:py-20 py-10 overflow-hidden",
className
)}
>
<Container>
<h3 className="h2 w-[312px] mb-6">Место проведения</h3>
<p className="text-lg max-w-[490px] text-on_surface_v normal">
Торгово-промышленная палата Туркменистана создана в целях содействия
развитию экономики Туркменистана, ее интегрированию в мировую
хозяйственную систему, формированию современной промышленной,
финансовой и торговой инфраструктуры, создания благоприятных условий
для предпринимательской деятельности, оказания содействия в
установлении торгово-экономических, научных и технических связей с
зарубежными партнерами.
</p>
{/* <img
src="/map.png"
alt="map"
className="absolute top-0 right-0 w-[900px] h-full object-cover"
/> */}
</Container>
</section>
);
};

View File

@ -0,0 +1,48 @@
import { Container } from "@/components/layout";
import { cn } from "@/lib/utils";
import { FC } from "react";
import { ThemeCard } from "../theme-card";
import { themes } from "../home/home-theme";
interface Props {
className?: string;
}
export const AboutThemes: FC<Props> = ({ className }) => {
return (
<section
className={cn("relative w-full bg-[#FDE8C4] -z-10 py-10", className)}
>
<img
src="/about-bg.svg"
alt=""
className="absolute top-0 left-0 size-full object-cover"
/>
<Container>
<h3 className="h2 mb-4">Отрасли</h3>
<p className="text-lg text-on_surface_v mb-6">
Мероприятие объединит ключевых игроков в таких отраслях, как:
</p>
<div className="grid md:grid-cols-4 grid-cols-2 gap-6">
{themes.map((item) => (
<ThemeCard
className="!bg-teritary_surface_container"
key={item.title}
{...item}
/>
))}
</div>
<div className="flex items-center gap-3 mt-8 text-on_surface_v text-lg">
<div className="md:w-1 w-4 md:h-[38px] h-40 bg-teritary_08" />
<p className="text-18">
Участники смогут продемонстрировать свои инновационные решения,
наладить взаимовыгодные партнерства и выйти на новые рынки.
</p>
</div>
</Container>
</section>
);
};

View File

@ -0,0 +1,31 @@
import { cn } from "@/lib/utils";
import { FC } from "react";
import { Container } from "../container";
import { times } from "../home/home-time";
import { TimeCard } from "../time-card";
interface Props {
className?: string;
}
export const AboutTime: FC<Props> = ({ className }) => {
return (
<section
className={cn("bg-bg_surface_container py-10 md:py-[160px]", className)}
>
<Container>
<h3 className="h2 mb-6">Время выставки</h3>
<div className="flex flex-col md:flex-row items-center gap-6">
{times.map((item) => (
<TimeCard
bottomClassName="!bg-white rounded-b-[2px]"
{...item}
key={item.name}
className="w-full"
/>
))}
</div>
</Container>
</section>
);
};

View File

@ -0,0 +1,4 @@
export { AboutThemes } from "./about-themes";
export { AboutTime } from "./about-time";
export { AboutPlace } from "./about-place";
export { AboutBron } from "./about-bron";

View File

@ -0,0 +1,22 @@
import { cn } from "@/lib/utils";
import { FC } from "react";
interface Props {
className?: string;
subtitle: string;
title: string;
img: string;
}
export const ContactCard: FC<Props> = ({ className, subtitle, title, img }) => {
return (
<div className={cn("flex items-center gap-4", className)}>
<img src={img} alt="contact icon" />
<div className="flex flex-col gap-2">
<h5 className="text-sm text-[#454545]">{subtitle}</h5>
<h4 className="text-[#171717] semibold">{title}</h4>
</div>
</div>
);
};

View File

@ -0,0 +1,65 @@
import { FC } from "react";
import { Button } from "@/components/ui/button";
import { Link } from "react-router-dom";
import useEmblaCarousel from "embla-carousel-react";
import { Container } from "@/components/layout";
import { AboutCard } from "../about-card";
const data = [
{
nums: "4,200 m²",
text: "выставочной площади",
},
{
nums: "10000+",
text: "Посетители посетят выставку",
},
{
nums: "100+",
text: "Экспоненты из более чем 30 стран",
},
{
nums: "80%",
text: "Участники принимают участие в принятии решений о закупках",
},
];
export const HomeAbout: FC = () => {
const [ebmblaRef] = useEmblaCarousel();
return (
<section>
<Container className="flex flex-col gap-6">
<div className="text-center">
<h2 className="h2 md:mb-3 mb-6 text-left sm:text-center">
Выставка-ярмарка «Международная Торговля и Услуги» в Ашхабаде
</h2>
<p className="md:text-base text-sm normal text-left sm:text-center text-[#454545]">
С 29 апреля по 1 мая 2025 года столица Туркменистана, Ашхабад,
станет центром международного делового сообщества благодаря
крупнейшей выставке-ярмарке «Торговля и услуги». Организованная
Торгово-промышленной палатой Туркменистана и компанией Turkmen Expo,
эта выставка направлена на укрепление глобальных торговых связей,
привлечение инвестиций и демонстрацию экономического потенциала
страны.
</p>
</div>
<div ref={ebmblaRef} className="embla overflow-hidden">
<div className="flex embla__container items-center gap-6">
{data.map((item) => (
<AboutCard
key={item.text}
{...item}
className="embla__slide flex-[0_0_288px]"
/>
))}
</div>
</div>
<Link to="/about" className="mx-auto">
<Button variant={"outline"}>Подробнее о выставке</Button>
</Link>
</Container>
</section>
);
};

View File

@ -0,0 +1,68 @@
import useEmblaCarousel from "embla-carousel-react";
import { FC } from "react";
import { Link } from "react-router-dom";
import { Button } from "@/components/ui/button";
import { useMediaQuery } from "usehooks-ts";
import { Container } from "@/components/layout";
export const btns = [
{
title: "План выставки",
link: "",
},
{
title: "Забронировать стенд",
link: "/stend-form",
},
{
title: "B2B | B2G встречи",
link: "/B2B-B2G",
},
{
title: "Стать спонсором",
link: "/become-sponsor",
},
];
export const HomeHero: FC = () => {
const [embalRef] = useEmblaCarousel();
const lg = useMediaQuery("(min-width: 1024px)");
const md = useMediaQuery("(min-width: 768px)");
function getBanner() {
if (lg) return "/banners/ru/l.jpg";
else if (md) return "/banners/ru/m.jpg";
else return "/banners/ru/s.jpg";
}
return (
<section className="flex flex-col gap-5">
<div ref={embalRef} className="embla">
<div className="embla__container">
<div className="embla__slide">
<img
src={getBanner()}
alt=""
className="size-full object-cover lg:max-h-[600px] lg:min-h-[320px]"
/>
</div>
</div>
</div>
<Container className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 items-center gap-6 text-2xl">
{btns.map(({ title, link }) => (
<Link key={title} to={link} className="w-full">
<Button
size={"lg"}
variant={"secondary"}
className="w-full drop-shadow-sm shadow-md bg-[#FFAE2A] text-on_teritary hover:bg-[#FFAE2A]/90"
>
{title}
</Button>
</Link>
))}
</Container>
</section>
);
};

View File

@ -0,0 +1,31 @@
import { FC } from "react";
import useEmblaCarousel from "embla-carousel-react";
import { Container } from "@/components/layout";
import { OfferCard } from "../";
export const HomeOffers: FC = () => {
const [emblaRef] = useEmblaCarousel({ align: "start" });
return (
<section className="bg-surface_high py-10 relative overflow-hidden">
<Container>
<div ref={emblaRef} className="embla ">
<div className="mb-2 flex gap-6 embla__container">
<OfferCard
img="/offer-1.png"
className="embla__slide flex-[0_0_300px] md:flex-[0_0_600px]"
title="Гостиницы, трансфер, визы"
text="По вопросам размещения в гостиницах, визовой поддержки, транспортного и экскурсионного обслуживания Вы можете обращаться к официальным туроператорам выставки"
/>
<OfferCard
img="/offer-2.png"
className="embla__slide flex-[0_0_300px] md:flex-[0_0_600px]"
title="Ознакомьтесь с планом выставки ITSE 2025"
text="Как выбрать лучшее место на выставке? Вы всегда должны помнить, что удачное расположение выставочной экспозиции повышает Ваши шансы привлечь внимание Ваших потенциальных клиентов"
/>
</div>
</div>
</Container>
</section>
);
};

View File

@ -0,0 +1,83 @@
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
import { FC, useCallback, useEffect, useState } from "react";
import { Container, EmblaDots } from "../";
import useEmblaCarousel from "embla-carousel-react";
import { ArrowLeft, ArrowRight } from "lucide-react";
interface Props {
className?: string;
}
export const HomePartners: FC<Props> = ({ className }) => {
const [emblaRef, emblaApi] = useEmblaCarousel();
const [selectedIndex, setSelectedIndex] = useState(0);
useEffect(() => {
if (!emblaApi) return;
const onSelect = () => setSelectedIndex(emblaApi.selectedScrollSnap());
emblaApi.on("select", onSelect);
onSelect();
return () => {
emblaApi.off("select", onSelect);
};
}, [emblaApi]);
const scrollTo = useCallback(
(index: number) => {
if (emblaApi) emblaApi.scrollTo(index);
},
[emblaApi]
);
const scrollPrev = useCallback(() => {
if (emblaApi) emblaApi.scrollPrev();
}, [emblaApi]);
const scrollNext = useCallback(() => {
if (emblaApi) emblaApi.scrollNext();
}, [emblaApi]);
return (
<section className={cn("", className)}>
<Container className="flex flex-col gap-10 relative w-full">
<div className="flex item-center justify-between">
<h2 className="h2">Участники выставки ITSE 2025</h2>
<Button variant="outline" size={"sm"}>
Все экспоненты
</Button>
</div>
<button
onClick={scrollPrev}
className="nav-btn absolute top-[55%] -translate-y-1/2 -left-12"
>
<ArrowLeft />
</button>
<button
onClick={scrollNext}
className="nav-btn absolute top-[55%] -translate-y-1/2 -right-12"
>
<ArrowRight />
</button>
<div ref={emblaRef} className="embla overflow-hidden">
<div className="embla__container gap-6 flex">
{Array.from({ length: 12 }).map((_, i) => (
<div
key={i}
className="embla__slide size-[184px] flex-[0_0_184px] bg-[#D9D9D9]"
/>
))}
</div>
</div>
<EmblaDots scrollTo={scrollTo} slides={4} active={selectedIndex} />
</Container>
</section>
);
};

View File

@ -0,0 +1,56 @@
import { FC } from "react";
import { Container } from "..";
import { ThemeCard } from "../theme-card";
export const themes = [
{
title: "Пищевая продукция и сельское хозяйство",
img: "/theme/1.svg",
},
{
title: "Товары и услуги",
img: "/theme/2.svg",
},
{
title: "E-commerce",
img: "/theme/3.svg",
},
{
title: "Волокна, текстиль и одежда",
img: "/theme/4.svg",
},
{
title: "Продукция промышленного производства",
img: "/theme/5.svg",
},
{
title: "Профессиональные услуги",
img: "/theme/6.svg",
},
{
title: "Ремесленные производства",
img: "/theme/7.svg",
},
{
title: "Креативные индустрии",
img: "/theme/8.svg",
},
];
export const HomeTheme: FC = () => {
return (
<section className="">
<Container>
<h2 className="h2 mb-10 text-center">
Тематические направления выставки
</h2>
<div className="grid md:grid-cols-4 grid-cols-2 gap-6">
{themes.map((item) => (
<ThemeCard key={item.title} {...item} />
))}
</div>
</Container>
</section>
);
};

View File

@ -0,0 +1,71 @@
import { cn } from "@/lib/utils";
import { FC } from "react";
import { Button } from "@/components/ui/button";
import { Link } from "react-router-dom";
import { Container } from "@/components/layout";
import { TimeCard } from "../";
interface Props {
className?: string;
}
export const times = [
{
name: "Монтаж выставки",
date: "1 — 27 апреля 2025 года",
},
{
name: "Работа",
date: "29 — 1 мая 2025 года",
},
{
name: "Демонтаж",
date: "1 — 2 мая 2025 года",
},
];
const contacts = [
{
title: "contact@turkmenexpo.com",
subtitle: "Адрес электронной почты",
img: "/contacts/mail.svg",
},
{
title: "здание ТПП Туркменистана",
subtitle: "Адрес выставки",
img: "/contacts/location.svg",
},
{
title: "+99371871814; 99363719588",
subtitle: "Контактный номер",
img: "/contacts/mobile.svg",
},
];
export const HomeTime: FC<Props> = ({ className }) => {
return (
<section className={cn("bg-surface_high pt-10 pb-20", className)}>
<Container>
<h2 className="h2 mb-10">Время мероприятий</h2>
<div className="flex flex-col gap-6">
<div className="flex flex-col md:flex-row items-center gap-6">
{times.map((item) => (
<TimeCard {...item} key={item.name} className="w-full" />
))}
</div>
<div className="md:p-10 pt-16 flex flex-col md:flex-row items-center gap-6">
{contacts.map((item) => (
<ContactCard {...item} key={item.title} className="w-full" />
))}
</div>
<Link to="/stend-form" className="md:w-fit w-full mx-auto">
<Button className="w-full">Забронируйте стенд </Button>
</Link>
</div>
</Container>
</section>
);
};

View File

@ -0,0 +1,6 @@
export { HomeHero } from "./home-hero";
export { HomeTime } from "./home-time";
export { HomeAbout } from "./home-about";
export { HomeTheme } from "./home-theme";
export { HomePartners } from "./home-partners";
export { HomeOffers } from "./home-offers";

View File

@ -0,0 +1,9 @@
export { Logo } from "./logo";
export { ThemeCard } from "./theme-card";
export { AboutCard } from "./about-card";
export { OfferCard } from "./offer-card";
export { TimeCard } from "./time-card";
export { ContactCard } from "./contact-card";
export * from "./about";
export * from "./home";

View File

@ -0,0 +1,14 @@
import { cn } from "@/lib/utils";
import { FC } from "react";
interface Props {
className?: string;
}
export const Logo: FC<Props> = ({ className }) => {
return (
<div className={cn("", className)}>
<img src="/logo.svg" alt="logo" />
</div>
);
};

View File

@ -0,0 +1,39 @@
import { cn } from "@/lib/utils";
import { FC } from "react";
import { Button } from "../ui/button";
import { ArrowUpRight } from "lucide-react";
interface Props {
title: string;
text: string;
className?: string;
img: string;
}
export const OfferCard: FC<Props> = ({ className, title, text, img }) => {
return (
<article
className={cn(
"md:px-8 md:py-6 p-4 relative overflow-hidden h-[296px] md:w-full w-[300px] text-on_primary",
className
)}
>
<div className="absolute size-full z-10 top-0 left-0 bg-gradient-to-r from-25% from-[#2C57A7] to-[#2C57A7]/20 " />
<img
src={img}
className="absolute size-full top-0 right-0 object-cover"
/>
<div className="relative z-20">
<h4 className="md:text-2xl text-lg mb-4 max-w-[444px] z-20 h-16">
{title}
</h4>
<p className="md:text-base text-sm normal max-w-[360px] z-20">{text}</p>
<Button className="text-sm px-0 mt-4 py-1.5 z-20" variant={"link"}>
Скачать PDF <ArrowUpRight />
</Button>
</div>
</article>
);
};

View File

@ -0,0 +1,23 @@
import { cn } from "@/lib/utils";
import { FC } from "react";
interface Props {
img: string;
title: string;
className?: string;
}
export const ThemeCard: FC<Props> = ({ className, img, title }) => {
return (
<article
className={cn(
"bg-bg_surface_container relative hover:bg-teritary_surface_container transition-all md:px-6 px-2 md:h-[224px] h-[124px]",
className
)}
>
<div className="bg-primary size-full -z-[10] absolute top-2.5 left-2.5" />
<img src={img} alt="theme icon" className="md:size-20 size-12" />
<h3 className="md:mt-6 mt-2 md:text-xl text-sm">{title}</h3>
</article>
);
};

View File

@ -0,0 +1,33 @@
import { cn } from "@/lib/utils";
import { FC } from "react";
interface Props {
className?: string;
name: string;
date: string;
bottomClassName?: string;
}
export const TimeCard: FC<Props> = ({
className,
name,
date,
bottomClassName,
}) => {
return (
<div className={cn("rounded-t-[4px] overflow-hidden", className)}>
<div className="bg-teritary_07 flex items-center text-teritary_11 h-11 px-4">
{name}
</div>
<div
className={cn(
"h-14 bg-bg_surface_container semibold flex items-center text-lg px-4",
bottomClassName
)}
>
{date}
</div>
</div>
);
};

View File

@ -0,0 +1,57 @@
import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
{
variants: {
variant: {
default:
"bg-primary text-primary-foreground shadow hover:bg-primary/90",
destructive:
"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
outline:
"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
secondary:
"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
default: "h-9 px-4 py-2",
sm: "h-8 rounded-md px-3 text-xs",
lg: "h-10 rounded-md px-8",
icon: "h-9 w-9",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean
}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button"
return (
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
)
}
)
Button.displayName = "Button"
export { Button, buttonVariants }

176
src/components/ui/form.tsx Normal file
View File

@ -0,0 +1,176 @@
import * as React from "react"
import * as LabelPrimitive from "@radix-ui/react-label"
import { Slot } from "@radix-ui/react-slot"
import {
Controller,
ControllerProps,
FieldPath,
FieldValues,
FormProvider,
useFormContext,
} from "react-hook-form"
import { cn } from "@/lib/utils"
import { Label } from "@/components/ui/label"
const Form = FormProvider
type FormFieldContextValue<
TFieldValues extends FieldValues = FieldValues,
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
> = {
name: TName
}
const FormFieldContext = React.createContext<FormFieldContextValue>(
{} as FormFieldContextValue
)
const FormField = <
TFieldValues extends FieldValues = FieldValues,
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
>({
...props
}: ControllerProps<TFieldValues, TName>) => {
return (
<FormFieldContext.Provider value={{ name: props.name }}>
<Controller {...props} />
</FormFieldContext.Provider>
)
}
const useFormField = () => {
const fieldContext = React.useContext(FormFieldContext)
const itemContext = React.useContext(FormItemContext)
const { getFieldState, formState } = useFormContext()
const fieldState = getFieldState(fieldContext.name, formState)
if (!fieldContext) {
throw new Error("useFormField should be used within <FormField>")
}
const { id } = itemContext
return {
id,
name: fieldContext.name,
formItemId: `${id}-form-item`,
formDescriptionId: `${id}-form-item-description`,
formMessageId: `${id}-form-item-message`,
...fieldState,
}
}
type FormItemContextValue = {
id: string
}
const FormItemContext = React.createContext<FormItemContextValue>(
{} as FormItemContextValue
)
const FormItem = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => {
const id = React.useId()
return (
<FormItemContext.Provider value={{ id }}>
<div ref={ref} className={cn("space-y-2", className)} {...props} />
</FormItemContext.Provider>
)
})
FormItem.displayName = "FormItem"
const FormLabel = React.forwardRef<
React.ElementRef<typeof LabelPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>
>(({ className, ...props }, ref) => {
const { error, formItemId } = useFormField()
return (
<Label
ref={ref}
className={cn(error && "text-destructive", className)}
htmlFor={formItemId}
{...props}
/>
)
})
FormLabel.displayName = "FormLabel"
const FormControl = React.forwardRef<
React.ElementRef<typeof Slot>,
React.ComponentPropsWithoutRef<typeof Slot>
>(({ ...props }, ref) => {
const { error, formItemId, formDescriptionId, formMessageId } = useFormField()
return (
<Slot
ref={ref}
id={formItemId}
aria-describedby={
!error
? `${formDescriptionId}`
: `${formDescriptionId} ${formMessageId}`
}
aria-invalid={!!error}
{...props}
/>
)
})
FormControl.displayName = "FormControl"
const FormDescription = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLParagraphElement>
>(({ className, ...props }, ref) => {
const { formDescriptionId } = useFormField()
return (
<p
ref={ref}
id={formDescriptionId}
className={cn("text-[0.8rem] text-muted-foreground", className)}
{...props}
/>
)
})
FormDescription.displayName = "FormDescription"
const FormMessage = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLParagraphElement>
>(({ className, children, ...props }, ref) => {
const { error, formMessageId } = useFormField()
const body = error ? String(error?.message) : children
if (!body) {
return null
}
return (
<p
ref={ref}
id={formMessageId}
className={cn("text-[0.8rem] font-medium text-destructive", className)}
{...props}
>
{body}
</p>
)
})
FormMessage.displayName = "FormMessage"
export {
useFormField,
Form,
FormItem,
FormLabel,
FormControl,
FormDescription,
FormMessage,
FormField,
}

View File

@ -0,0 +1,22 @@
import * as React from "react"
import { cn } from "@/lib/utils"
const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>(
({ className, type, ...props }, ref) => {
return (
<input
type={type}
className={cn(
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
className
)}
ref={ref}
{...props}
/>
)
}
)
Input.displayName = "Input"
export { Input }

View File

@ -0,0 +1,26 @@
"use client"
import * as React from "react"
import * as LabelPrimitive from "@radix-ui/react-label"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const labelVariants = cva(
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
)
const Label = React.forwardRef<
React.ElementRef<typeof LabelPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &
VariantProps<typeof labelVariants>
>(({ className, ...props }, ref) => (
<LabelPrimitive.Root
ref={ref}
className={cn(labelVariants(), className)}
{...props}
/>
))
Label.displayName = LabelPrimitive.Root.displayName
export { Label }

View File

@ -0,0 +1,42 @@
import * as React from "react"
import * as RadioGroupPrimitive from "@radix-ui/react-radio-group"
import { Circle } from "lucide-react"
import { cn } from "@/lib/utils"
const RadioGroup = React.forwardRef<
React.ElementRef<typeof RadioGroupPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root>
>(({ className, ...props }, ref) => {
return (
<RadioGroupPrimitive.Root
className={cn("grid gap-2", className)}
{...props}
ref={ref}
/>
)
})
RadioGroup.displayName = RadioGroupPrimitive.Root.displayName
const RadioGroupItem = React.forwardRef<
React.ElementRef<typeof RadioGroupPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>
>(({ className, ...props }, ref) => {
return (
<RadioGroupPrimitive.Item
ref={ref}
className={cn(
"aspect-square h-4 w-4 rounded-full border border-primary text-primary shadow focus:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
className
)}
{...props}
>
<RadioGroupPrimitive.Indicator className="flex items-center justify-center">
<Circle className="h-3.5 w-3.5 fill-primary" />
</RadioGroupPrimitive.Indicator>
</RadioGroupPrimitive.Item>
)
})
RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName
export { RadioGroup, RadioGroupItem }

138
src/components/ui/sheet.tsx Normal file
View File

@ -0,0 +1,138 @@
import * as React from "react"
import * as SheetPrimitive from "@radix-ui/react-dialog"
import { cva, type VariantProps } from "class-variance-authority"
import { X } from "lucide-react"
import { cn } from "@/lib/utils"
const Sheet = SheetPrimitive.Root
const SheetTrigger = SheetPrimitive.Trigger
const SheetClose = SheetPrimitive.Close
const SheetPortal = SheetPrimitive.Portal
const SheetOverlay = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Overlay>,
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>
>(({ className, ...props }, ref) => (
<SheetPrimitive.Overlay
className={cn(
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
className
)}
{...props}
ref={ref}
/>
))
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName
const sheetVariants = cva(
"fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500 data-[state=open]:animate-in data-[state=closed]:animate-out",
{
variants: {
side: {
top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
bottom:
"inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
right:
"inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
},
},
defaultVariants: {
side: "right",
},
}
)
interface SheetContentProps
extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
VariantProps<typeof sheetVariants> {}
const SheetContent = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Content>,
SheetContentProps
>(({ side = "right", className, children, ...props }, ref) => (
<SheetPortal>
<SheetOverlay />
<SheetPrimitive.Content
ref={ref}
className={cn(sheetVariants({ side }), className)}
{...props}
>
<SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary">
<X className="h-4 w-4" />
<span className="sr-only">Close</span>
</SheetPrimitive.Close>
{children}
</SheetPrimitive.Content>
</SheetPortal>
))
SheetContent.displayName = SheetPrimitive.Content.displayName
const SheetHeader = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col space-y-2 text-center sm:text-left",
className
)}
{...props}
/>
)
SheetHeader.displayName = "SheetHeader"
const SheetFooter = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
className
)}
{...props}
/>
)
SheetFooter.displayName = "SheetFooter"
const SheetTitle = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Title>,
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>
>(({ className, ...props }, ref) => (
<SheetPrimitive.Title
ref={ref}
className={cn("text-lg font-semibold text-foreground", className)}
{...props}
/>
))
SheetTitle.displayName = SheetPrimitive.Title.displayName
const SheetDescription = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Description>,
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>
>(({ className, ...props }, ref) => (
<SheetPrimitive.Description
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
))
SheetDescription.displayName = SheetPrimitive.Description.displayName
export {
Sheet,
SheetPortal,
SheetOverlay,
SheetTrigger,
SheetClose,
SheetContent,
SheetHeader,
SheetFooter,
SheetTitle,
SheetDescription,
}

View File

@ -0,0 +1,22 @@
import * as React from "react"
import { cn } from "@/lib/utils"
const Textarea = React.forwardRef<
HTMLTextAreaElement,
React.ComponentProps<"textarea">
>(({ className, ...props }, ref) => {
return (
<textarea
className={cn(
"flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
className
)}
ref={ref}
{...props}
/>
)
})
Textarea.displayName = "Textarea"
export { Textarea }

View File

@ -0,0 +1,7 @@
import { useEffect } from "react";
export const useScrollTop = (devs?: any) => {
useEffect(() => {
window.scrollTo({ behavior: "smooth", top: 0 });
}, [devs]);
};

137
src/index.css Normal file
View File

@ -0,0 +1,137 @@
@font-face {
font-family: "Gilroy-Regular";
src: local("Gilroy-Regular"),
url(../fonts/Gilroy-Regular.woff2) format("woff2");
font-weight: 400;
}
@font-face {
font-family: "Gilroy-Medium";
src: local("Gilroy-Medium"), url(../fonts/Gilroy-Medium.woff2) format("woff2");
font-weight: 500;
}
@font-face {
font-family: "Gilroy-Semibold";
src: local("Gilroy-Semibold"),
url(../fonts/Gilroy-Semibold.woff2) format("woff2");
font-weight: 600;
}
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
* {
@apply box-border;
}
body {
font-family: "Gilroy-Medium";
@apply bg-background;
}
:root {
--background: 0 0% 100%;
--foreground: 0 0% 3.9%;
--card: 0 0% 100%;
--card-foreground: 0 0% 3.9%;
--popover: 0 0% 100%;
--popover-foreground: 0 0% 3.9%;
--primary: 0 0% 9%;
--primary-foreground: 0 0% 98%;
--secondary: 0 0% 96.1%;
--secondary-foreground: 0 0% 9%;
--muted: 0 0% 96.1%;
--muted-foreground: 0 0% 45.1%;
--accent: 0 0% 96.1%;
--accent-foreground: 0 0% 9%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;
--border: 0 0% 89.8%;
--input: 0 0% 89.8%;
--ring: 0 0% 3.9%;
--chart-1: 12 76% 61%;
--chart-2: 173 58% 39%;
--chart-3: 197 37% 24%;
--chart-4: 43 74% 66%;
--chart-5: 27 87% 67%;
--radius: 0.5rem;
}
.dark {
--background: 0 0% 3.9%;
--foreground: 0 0% 98%;
--card: 0 0% 3.9%;
--card-foreground: 0 0% 98%;
--popover: 0 0% 3.9%;
--popover-foreground: 0 0% 98%;
--primary: 0 0% 98%;
--primary-foreground: 0 0% 9%;
--secondary: 0 0% 14.9%;
--secondary-foreground: 0 0% 98%;
--muted: 0 0% 14.9%;
--muted-foreground: 0 0% 63.9%;
--accent: 0 0% 14.9%;
--accent-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 0% 98%;
--border: 0 0% 14.9%;
--input: 0 0% 14.9%;
--ring: 0 0% 83.1%;
--chart-1: 220 70% 50%;
--chart-2: 160 60% 45%;
--chart-3: 30 80% 55%;
--chart-4: 280 65% 60%;
--chart-5: 340 75% 55%;
}
}
@layer utilities {
.normal {
@apply font-["Gilroy-Regular"] font-normal;
}
.semibold {
@apply font-["Gilroy-Semibold"] font-semibold;
}
.h1 {
@apply text-[28px] leading-[130%] font-medium;
}
.h2 {
@apply md:text-3xl text-2xl text-[#171717];
}
.p {
@apply text-base leading-[130%];
}
.text-18 {
@apply text-lg normal text-on_surface_v;
}
.dot {
@apply w-5 h-1 cursor-pointer bg-on_surface_v rounded-[2px];
}
.dot-active {
@apply w-5 h-1 bg-on_surface rounded-[2px];
}
.nav-btn {
@apply bg-[#D9D9D9] size-12 rounded-full flex items-center justify-center;
}
.progress-circle {
@apply size-14 rounded-full text-2xl z-10 text-[#5F6674];
}
}
@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}

6
src/lib/utils.ts Normal file
View File

@ -0,0 +1,6 @@
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}

29
src/main.tsx Normal file
View File

@ -0,0 +1,29 @@
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import "./index.css";
import App from "./App.tsx";
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import { About, Home } from "./pages";
const router = createBrowserRouter([
{
element: <App />,
path: "/",
children: [
{
element: <Home />,
path: "",
},
{
element: <About />,
path: "/about",
},
],
},
]);
createRoot(document.getElementById("root")!).render(
<StrictMode>
<RouterProvider router={router} />
</StrictMode>
);

75
src/pages/about.tsx Normal file
View File

@ -0,0 +1,75 @@
import { Container, Cover } from "@/components/layout";
import {
AboutBron,
AboutPlace,
AboutThemes,
AboutTime,
} from "@/components/shared";
import { useScrollTop } from "@/hooks/use-scroll-top";
import { cn } from "@/lib/utils";
import { FC } from "react";
interface Props {
className?: string;
}
export const About: FC<Props> = ({ className }) => {
useScrollTop();
return (
<div className={cn("", className)}>
<Cover title="О выставке" />
<Container className="flex flex-col md:my-20 my-10 gap-16">
<div className="flex flex-col gap-6">
<h3 className="h2">
Международная выставка-ярмарка «Торговля и услуги»
</h3>
<p className="text-18">
Международная выставка-ярмарка «Торговля и услуги» в Ашхабаде: новые
возможности для бизнеса С 29 апреля по 1 мая 2025 года столица
Туркменистана, Ашхабад, станет центром международного делового
сообщества благодаря крупнейшей выставке-ярмарке «Торговля и
услуги». Организованная Торгово-промышленной палатой Туркменистана и
компанией Turkmen Expo, эта выставка направлена на укрепление
глобальных торговых связей, привлечение инвестиций и демонстрацию
экономического потенциала страны.
</p>
</div>
<div className="flex flex-col gap-6">
<h3 className="h2">Цели выставки</h3>
<ul className="list-disc pl-8 flex flex-col gap-3 text-lg text-on_surface_v normal">
<li>
Поддержка малых и средних предприятий, их интеграция в
международную экономику.
</li>
<li>Продвижение экспортного потенциала Туркменистана.</li>
<li>Укрепление деловых связей через B2B- и B2G-встречи.</li>
<li>Привлечение инвестиций в ключевые секторы экономики.</li>
</ul>
</div>
<div className="flex flex-col gap-6">
<h3 className="h2">Ключевые особенности мероприятия</h3>
<ul className="list-disc pl-8 flex flex-col gap-3 text-lg text-on_surface_v normal">
<li>Специализированные выставочные зоны </li>
<li>Форумы по качеству продукции</li>
<li>Воркшопы и бизнес-миссии</li>
</ul>
<p className="text-18">
Участники смогут обсудить современные технологии, лучшие практики и
эффективные стратегии для устойчивого бизнеса.
</p>
</div>
</Container>
<AboutThemes />
<AboutTime />
<AboutPlace />
<AboutBron />
</div>
);
};

21
src/pages/home.tsx Normal file
View File

@ -0,0 +1,21 @@
import { FC } from "react";
import {
HomeAbout,
HomeHero,
HomeOffers,
HomeTheme,
HomeTime,
} from "@/components/shared";
export const Home: FC = () => {
return (
<div className="flex flex-col gap-20">
<HomeHero />
<HomeAbout />
<HomeOffers />
<HomeTheme />
<HomeTime />
</div>
);
};

2
src/pages/index.ts Normal file
View File

@ -0,0 +1,2 @@
export { Home } from "./home";
export { About } from "./about";

1
src/vite-env.d.ts vendored Normal file
View File

@ -0,0 +1 @@
/// <reference types="vite/client" />

47
tailwind.config.js Normal file
View File

@ -0,0 +1,47 @@
/** @type {import('tailwindcss').Config} */
export default {
darkMode: ["class"],
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
theme: {
extend: {
borderRadius: {
lg: "var(--radius)",
md: "calc(var(--radius) - 2px)",
sm: "calc(var(--radius) - 4px)",
},
colors: {
primary: "#2C57A7",
primary_04: "#9AB4E4",
on_primary: "#ffffff",
primary_container: "#BBCDED",
on_primary_container: "#112343",
primary_outline_reverse: "#789BDB",
secondary: "#495F89",
on_secondary: "#ffffff",
secondary_container: "#C7D0E1",
on_secondary_container: "#1D2637",
teritary: "#FFAE2A",
on_teritary: "#2A1A00",
teritary_container: "#FFDDBA",
on_teritary_container: "#2B1700",
teritary_04: "#FFCE7F",
teritary_07: "#FF9E00",
teritary_08: "#D48400",
teritary_11: "#553400",
teritary_surface_container: "#FFF3E0",
surface_high: "#E8E7EF",
on_surface: "#26292E",
on_surface_v: "#5F6674",
outline: "#A1A7B2",
outline_v: "#D0D3D8",
background: "#F9F9FA",
bg_surface_container: "#EEEDF4",
},
},
},
plugins: [require("tailwindcss-animate")],
};

31
tsconfig.app.json Normal file
View File

@ -0,0 +1,31 @@
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
},
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["src"]
}

13
tsconfig.json Normal file
View File

@ -0,0 +1,13 @@
{
"files": [],
"references": [
{ "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.node.json" }
],
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}

24
tsconfig.node.json Normal file
View File

@ -0,0 +1,24 @@
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
"target": "ES2022",
"lib": ["ES2023"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["vite.config.ts"]
}

7
vite.config.ts Normal file
View File

@ -0,0 +1,7 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
// https://vite.dev/config/
export default defineConfig({
plugins: [react()],
})