diff --git a/src/food-market.public/.gitignore b/src/food-market.public/.gitignore new file mode 100644 index 0000000..8ee464f --- /dev/null +++ b/src/food-market.public/.gitignore @@ -0,0 +1 @@ +scripts/fonts/ diff --git a/src/food-market.public/deploy/nginx.conf b/src/food-market.public/deploy/nginx.conf index c1a0e0b..70a9245 100644 --- a/src/food-market.public/deploy/nginx.conf +++ b/src/food-market.public/deploy/nginx.conf @@ -16,8 +16,8 @@ server { } # Старый URL — постоянный редирект на новую страницу импорта. - location = /migration-from-moysklad { return 301 /import/; } - location = /migration-from-moysklad/ { return 301 /import/; } + location = /migration-from-other-system { return 301 /import/; } + location = /migration-from-other-system/ { return 301 /import/; } # Pretty URLs: /pricing → /pricing/index.html или /pricing.html location / { diff --git a/src/food-market.public/package.json b/src/food-market.public/package.json index ffe37aa..c585356 100644 --- a/src/food-market.public/package.json +++ b/src/food-market.public/package.json @@ -9,15 +9,20 @@ "preview": "astro preview" }, "dependencies": { - "astro": "^4.16.18", "@astrojs/react": "^3.6.3", "@astrojs/sitemap": "^3.2.1", "@astrojs/tailwind": "^5.1.4", - "tailwindcss": "^3.4.17", - "react": "^19.2.5", - "react-dom": "^19.2.5", "@types/react": "^19.2.14", "@types/react-dom": "^19.2.3", - "lucide-react": "^1.8.0" + "astro": "^4.16.18", + "lucide-react": "^1.8.0", + "react": "^19.2.5", + "react-dom": "^19.2.5", + "tailwindcss": "^3.4.17" + }, + "devDependencies": { + "@resvg/resvg-js": "^2.6.2", + "playwright": "^1.59.1", + "satori": "^0.26.0" } } diff --git a/src/food-market.public/pnpm-lock.yaml b/src/food-market.public/pnpm-lock.yaml index 4c9dfbb..7d892c3 100644 --- a/src/food-market.public/pnpm-lock.yaml +++ b/src/food-market.public/pnpm-lock.yaml @@ -38,6 +38,16 @@ importers: tailwindcss: specifier: ^3.4.17 version: 3.4.19(yaml@2.8.3) + devDependencies: + '@resvg/resvg-js': + specifier: ^2.6.2 + version: 2.6.2 + playwright: + specifier: ^1.59.1 + version: 1.59.1 + satori: + specifier: ^0.26.0 + version: 0.26.0 packages: @@ -468,6 +478,86 @@ packages: '@oslojs/encoding@1.1.0': resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==} + '@resvg/resvg-js-android-arm-eabi@2.6.2': + resolution: {integrity: sha512-FrJibrAk6v29eabIPgcTUMPXiEz8ssrAk7TXxsiZzww9UTQ1Z5KAbFJs+Z0Ez+VZTYgnE5IQJqBcoSiMebtPHA==} + engines: {node: '>= 10'} + cpu: [arm] + os: [android] + + '@resvg/resvg-js-android-arm64@2.6.2': + resolution: {integrity: sha512-VcOKezEhm2VqzXpcIJoITuvUS/fcjIw5NA/w3tjzWyzmvoCdd+QXIqy3FBGulWdClvp4g+IfUemigrkLThSjAQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + + '@resvg/resvg-js-darwin-arm64@2.6.2': + resolution: {integrity: sha512-nmok2LnAd6nLUKI16aEB9ydMC6Lidiiq2m1nEBDR1LaaP7FGs4AJ90qDraxX+CWlVuRlvNjyYJTNv8qFjtL9+A==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@resvg/resvg-js-darwin-x64@2.6.2': + resolution: {integrity: sha512-GInyZLjgWDfsVT6+SHxQVRwNzV0AuA1uqGsOAW+0th56J7Nh6bHHKXHBWzUrihxMetcFDmQMAX1tZ1fZDYSRsw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@resvg/resvg-js-linux-arm-gnueabihf@2.6.2': + resolution: {integrity: sha512-YIV3u/R9zJbpqTTNwTZM5/ocWetDKGsro0SWp70eGEM9eV2MerWyBRZnQIgzU3YBnSBQ1RcxRZvY/UxwESfZIw==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@resvg/resvg-js-linux-arm64-gnu@2.6.2': + resolution: {integrity: sha512-zc2BlJSim7YR4FZDQ8OUoJg5holYzdiYMeobb9pJuGDidGL9KZUv7SbiD4E8oZogtYY42UZEap7dqkkYuA91pg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@resvg/resvg-js-linux-arm64-musl@2.6.2': + resolution: {integrity: sha512-3h3dLPWNgSsD4lQBJPb4f+kvdOSJHa5PjTYVsWHxLUzH4IFTJUAnmuWpw4KqyQ3NA5QCyhw4TWgxk3jRkQxEKg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@resvg/resvg-js-linux-x64-gnu@2.6.2': + resolution: {integrity: sha512-IVUe+ckIerA7xMZ50duAZzwf1U7khQe2E0QpUxu5MBJNao5RqC0zwV/Zm965vw6D3gGFUl7j4m+oJjubBVoftw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@resvg/resvg-js-linux-x64-musl@2.6.2': + resolution: {integrity: sha512-UOf83vqTzoYQO9SZ0fPl2ZIFtNIz/Rr/y+7X8XRX1ZnBYsQ/tTb+cj9TE+KHOdmlTFBxhYzVkP2lRByCzqi4jQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@resvg/resvg-js-win32-arm64-msvc@2.6.2': + resolution: {integrity: sha512-7C/RSgCa+7vqZ7qAbItfiaAWhyRSoD4l4BQAbVDqRRsRgY+S+hgS3in0Rxr7IorKUpGE69X48q6/nOAuTJQxeQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@resvg/resvg-js-win32-ia32-msvc@2.6.2': + resolution: {integrity: sha512-har4aPAlvjnLcil40AC77YDIk6loMawuJwFINEM7n0pZviwMkMvjb2W5ZirsNOZY4aDbo5tLx0wNMREp5Brk+w==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + + '@resvg/resvg-js-win32-x64-msvc@2.6.2': + resolution: {integrity: sha512-ZXtYhtUr5SSaBrUDq7DiyjOFJqBVL/dOBN7N/qmi/pO0IgiWW/f/ue3nbvu9joWE5aAKDoIzy/CxsY0suwGosQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@resvg/resvg-js@2.6.2': + resolution: {integrity: sha512-xBaJish5OeGmniDj9cW5PRa/PtmuVU3ziqrbr5xJj901ZDN4TosrVaNZpEiLZAxdfnhAe7uQ7QFWfjPe9d9K2Q==} + engines: {node: '>= 10'} + '@rolldown/pluginutils@1.0.0-beta.27': resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} @@ -639,6 +729,11 @@ packages: '@shikijs/vscode-textmate@10.0.2': resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + '@shuding/opentype.js@1.4.0-beta.0': + resolution: {integrity: sha512-3NgmNyH3l/Hv6EvsWJbsvpcpUba6R8IREQ83nH83cyakCw7uM1arZKNfHwv1Wz6jgqrF/j4x5ELvR6PnK9nTcA==} + engines: {node: '>= 8.0.0'} + hasBin: true + '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -763,6 +858,10 @@ packages: base-64@1.0.0: resolution: {integrity: sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==} + base64-js@0.0.8: + resolution: {integrity: sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==} + engines: {node: '>= 0.4'} + baseline-browser-mapping@2.10.22: resolution: {integrity: sha512-6qruVrb5rse6WylFkU0FhBKKGuecWseqdpQfhkawn6ztyk2QlfwSRjsDxMCLJrkfmfN21qvhl9ABgaMeRkuwww==} engines: {node: '>=6.0.0'} @@ -793,6 +892,9 @@ packages: resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==} engines: {node: '>=16'} + camelize@1.0.1: + resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==} + caniuse-lite@1.0.30001791: resolution: {integrity: sha512-yk0l/YSrOnFZk3UROpDLQD9+kC1l4meK/wed583AXrzoarMGJcbRi2Q4RaUYbKxYAsZ8sWmaSa/DsLmdBeI1vQ==} @@ -867,6 +969,23 @@ packages: resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} + css-background-parser@0.1.0: + resolution: {integrity: sha512-2EZLisiZQ+7m4wwur/qiYJRniHX4K5Tc9w93MT3AS0WS1u5kaZ4FKXlOTBhOjc+CgEgPiGY+fX1yWD8UwpEqUA==} + + css-box-shadow@1.0.0-3: + resolution: {integrity: sha512-9jaqR6e7Ohds+aWwmhe6wILJ99xYQbfmK9QQB9CcMjDbTxPZjwEmUQpU91OG05Xgm8BahT5fW+svbsQGjS/zPg==} + + css-color-keywords@1.0.0: + resolution: {integrity: sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==} + engines: {node: '>=4'} + + css-gradient-parser@0.0.17: + resolution: {integrity: sha512-w2Xy9UMMwlKtou0vlRnXvWglPAceXCTtcmVSo8ZBUvqCV5aXEFP/PC6d+I464810I9FT++UACwTD5511bmGPUg==} + engines: {node: '>=16'} + + css-to-react-native@3.2.0: + resolution: {integrity: sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==} + cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} @@ -925,6 +1044,10 @@ packages: emoji-regex-xs@1.0.0: resolution: {integrity: sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==} + emoji-regex-xs@2.0.1: + resolution: {integrity: sha512-1QFuh8l7LqUcKe24LsPUNzjrzJQ7pgRwp1QMcZ5MX6mFplk2zQ08NVCM84++1cveaUUYtcCYHmeFEuNg16sU4g==} + engines: {node: '>=10.0.0'} + emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -951,6 +1074,9 @@ packages: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + escape-string-regexp@5.0.0: resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} engines: {node: '>=12'} @@ -992,6 +1118,9 @@ packages: picomatch: optional: true + fflate@0.7.4: + resolution: {integrity: sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -1014,6 +1143,11 @@ packages: fraction.js@5.3.4: resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} + fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -1082,6 +1216,10 @@ packages: hastscript@9.0.1: resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} + hex-rgb@4.3.0: + resolution: {integrity: sha512-Ox1pJVrDCyGHMG9CFg1tmrRUMRPRsAWYc/PinY0XzJU4K7y7vjNoLKIQ7BR5UJMCxNN8EM1MNDmHWA/B3aZUuw==} + engines: {node: '>=6'} + html-escaper@3.0.3: resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==} @@ -1196,6 +1334,9 @@ packages: resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} engines: {node: '>=14'} + linebreak@1.1.0: + resolution: {integrity: sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ==} + lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} @@ -1438,6 +1579,12 @@ packages: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} + pako@0.2.9: + resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} + + parse-css-color@0.2.1: + resolution: {integrity: sha512-bwS/GGIFV3b6KS4uwpzCFj4w297Yl3uqnSgIPsoQkx7GMLROXfMnWvxfNkL0oh8HVhZA4hvJoEoEIqonfJ3BWg==} + parse-latin@7.0.0: resolution: {integrity: sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==} @@ -1478,6 +1625,16 @@ packages: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} + playwright-core@1.59.1: + resolution: {integrity: sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg==} + engines: {node: '>=18'} + hasBin: true + + playwright@1.59.1: + resolution: {integrity: sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw==} + engines: {node: '>=18'} + hasBin: true + postcss-import@15.1.0: resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} engines: {node: '>=14.0.0'} @@ -1645,6 +1802,10 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + satori@0.26.0: + resolution: {integrity: sha512-tkMFrfIs3l2mQ2JEcyW0ADTy3zGggFRFzi6Ef8YozQSFsFKEqaSO1Y8F9wJg4//PJGQauMalHGTUEkPrFwhVPA==} + engines: {node: '>=16'} + sax@1.6.0: resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} engines: {node: '>=11.0.0'} @@ -1712,6 +1873,9 @@ packages: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} + string.prototype.codepointat@0.2.1: + resolution: {integrity: sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==} + stringify-entities@4.0.4: resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} @@ -1752,6 +1916,9 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + tiny-inflate@1.0.3: + resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} + tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} @@ -1800,6 +1967,9 @@ packages: undici-types@7.16.0: resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + unicode-trie@2.0.0: + resolution: {integrity: sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==} + unified@11.0.5: resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} @@ -1925,6 +2095,9 @@ packages: resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} engines: {node: '>=12.20'} + yoga-layout@3.2.1: + resolution: {integrity: sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==} + zod-to-json-schema@3.25.2: resolution: {integrity: sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==} peerDependencies: @@ -2342,6 +2515,57 @@ snapshots: '@oslojs/encoding@1.1.0': {} + '@resvg/resvg-js-android-arm-eabi@2.6.2': + optional: true + + '@resvg/resvg-js-android-arm64@2.6.2': + optional: true + + '@resvg/resvg-js-darwin-arm64@2.6.2': + optional: true + + '@resvg/resvg-js-darwin-x64@2.6.2': + optional: true + + '@resvg/resvg-js-linux-arm-gnueabihf@2.6.2': + optional: true + + '@resvg/resvg-js-linux-arm64-gnu@2.6.2': + optional: true + + '@resvg/resvg-js-linux-arm64-musl@2.6.2': + optional: true + + '@resvg/resvg-js-linux-x64-gnu@2.6.2': + optional: true + + '@resvg/resvg-js-linux-x64-musl@2.6.2': + optional: true + + '@resvg/resvg-js-win32-arm64-msvc@2.6.2': + optional: true + + '@resvg/resvg-js-win32-ia32-msvc@2.6.2': + optional: true + + '@resvg/resvg-js-win32-x64-msvc@2.6.2': + optional: true + + '@resvg/resvg-js@2.6.2': + optionalDependencies: + '@resvg/resvg-js-android-arm-eabi': 2.6.2 + '@resvg/resvg-js-android-arm64': 2.6.2 + '@resvg/resvg-js-darwin-arm64': 2.6.2 + '@resvg/resvg-js-darwin-x64': 2.6.2 + '@resvg/resvg-js-linux-arm-gnueabihf': 2.6.2 + '@resvg/resvg-js-linux-arm64-gnu': 2.6.2 + '@resvg/resvg-js-linux-arm64-musl': 2.6.2 + '@resvg/resvg-js-linux-x64-gnu': 2.6.2 + '@resvg/resvg-js-linux-x64-musl': 2.6.2 + '@resvg/resvg-js-win32-arm64-msvc': 2.6.2 + '@resvg/resvg-js-win32-ia32-msvc': 2.6.2 + '@resvg/resvg-js-win32-x64-msvc': 2.6.2 + '@rolldown/pluginutils@1.0.0-beta.27': {} '@rollup/pluginutils@5.3.0(rollup@4.60.2)': @@ -2462,6 +2686,11 @@ snapshots: '@shikijs/vscode-textmate@10.0.2': {} + '@shuding/opentype.js@1.4.0-beta.0': + dependencies: + fflate: 0.7.4 + string.prototype.codepointat: 0.2.1 + '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.29.2 @@ -2662,6 +2891,8 @@ snapshots: base-64@1.0.0: {} + base64-js@0.0.8: {} + baseline-browser-mapping@2.10.22: {} binary-extensions@2.3.0: {} @@ -2693,6 +2924,8 @@ snapshots: camelcase@8.0.0: {} + camelize@1.0.1: {} + caniuse-lite@1.0.30001791: {} ccount@2.0.1: {} @@ -2734,8 +2967,7 @@ snapshots: color-name: 1.1.4 optional: true - color-name@1.1.4: - optional: true + color-name@1.1.4: {} color-string@1.9.1: dependencies: @@ -2759,6 +2991,20 @@ snapshots: cookie@0.7.2: {} + css-background-parser@0.1.0: {} + + css-box-shadow@1.0.0-3: {} + + css-color-keywords@1.0.0: {} + + css-gradient-parser@0.0.17: {} + + css-to-react-native@3.2.0: + dependencies: + camelize: 1.0.1 + css-color-keywords: 1.0.0 + postcss-value-parser: 4.2.0 + cssesc@3.0.0: {} csstype@3.2.3: {} @@ -2798,6 +3044,8 @@ snapshots: emoji-regex-xs@1.0.0: {} + emoji-regex-xs@2.0.1: {} + emoji-regex@10.6.0: {} emoji-regex@8.0.0: {} @@ -2836,6 +3084,8 @@ snapshots: escalade@3.2.0: {} + escape-html@1.0.3: {} + escape-string-regexp@5.0.0: {} esprima@4.0.1: {} @@ -2870,6 +3120,8 @@ snapshots: optionalDependencies: picomatch: 4.0.4 + fflate@0.7.4: {} + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -2890,6 +3142,9 @@ snapshots: fraction.js@5.3.4: {} + fsevents@2.3.2: + optional: true + fsevents@2.3.3: optional: true @@ -3009,6 +3264,8 @@ snapshots: property-information: 7.1.0 space-separated-tokens: 2.0.2 + hex-rgb@4.3.0: {} + html-escaper@3.0.3: {} html-void-elements@3.0.0: {} @@ -3083,6 +3340,11 @@ snapshots: lilconfig@3.1.3: {} + linebreak@1.1.0: + dependencies: + base64-js: 0.0.8 + unicode-trie: 2.0.0 + lines-and-columns@1.2.4: {} load-yaml-file@0.2.0: @@ -3512,6 +3774,13 @@ snapshots: p-try@2.2.0: {} + pako@0.2.9: {} + + parse-css-color@0.2.1: + dependencies: + color-name: 1.1.4 + hex-rgb: 4.3.0 + parse-latin@7.0.0: dependencies: '@types/nlcst': 2.0.3 @@ -3545,6 +3814,14 @@ snapshots: dependencies: find-up: 4.1.0 + playwright-core@1.59.1: {} + + playwright@1.59.1: + dependencies: + playwright-core: 1.59.1 + optionalDependencies: + fsevents: 2.3.2 + postcss-import@15.1.0(postcss@8.5.11): dependencies: postcss: 8.5.11 @@ -3775,6 +4052,20 @@ snapshots: dependencies: queue-microtask: 1.2.3 + satori@0.26.0: + dependencies: + '@shuding/opentype.js': 1.4.0-beta.0 + css-background-parser: 0.1.0 + css-box-shadow: 1.0.0-3 + css-gradient-parser: 0.0.17 + css-to-react-native: 3.2.0 + emoji-regex-xs: 2.0.1 + escape-html: 1.0.3 + linebreak: 1.1.0 + parse-css-color: 0.2.1 + postcss-value-parser: 4.2.0 + yoga-layout: 3.2.1 + sax@1.6.0: {} scheduler@0.27.0: {} @@ -3864,6 +4155,8 @@ snapshots: get-east-asian-width: 1.5.0 strip-ansi: 7.2.0 + string.prototype.codepointat@0.2.1: {} + stringify-entities@4.0.4: dependencies: character-entities-html4: 2.1.0 @@ -3929,6 +4222,8 @@ snapshots: dependencies: any-promise: 1.3.0 + tiny-inflate@1.0.3: {} + tinyexec@0.3.2: {} tinyglobby@0.2.16: @@ -3961,6 +4256,11 @@ snapshots: undici-types@7.16.0: {} + unicode-trie@2.0.0: + dependencies: + pako: 0.2.9 + tiny-inflate: 1.0.3 + unified@11.0.5: dependencies: '@types/unist': 3.0.3 @@ -4077,6 +4377,8 @@ snapshots: yocto-queue@1.2.2: {} + yoga-layout@3.2.1: {} + zod-to-json-schema@3.25.2(zod@3.25.76): dependencies: zod: 3.25.76 diff --git a/src/food-market.public/public/og/about.png b/src/food-market.public/public/og/about.png new file mode 100644 index 0000000..bdb664e Binary files /dev/null and b/src/food-market.public/public/og/about.png differ diff --git a/src/food-market.public/public/og/for-alcohol.png b/src/food-market.public/public/og/for-alcohol.png new file mode 100644 index 0000000..adff7d7 Binary files /dev/null and b/src/food-market.public/public/og/for-alcohol.png differ diff --git a/src/food-market.public/public/og/for-cafe.png b/src/food-market.public/public/og/for-cafe.png new file mode 100644 index 0000000..3db63fb Binary files /dev/null and b/src/food-market.public/public/og/for-cafe.png differ diff --git a/src/food-market.public/public/og/for-clothing.png b/src/food-market.public/public/og/for-clothing.png new file mode 100644 index 0000000..242b8de Binary files /dev/null and b/src/food-market.public/public/og/for-clothing.png differ diff --git a/src/food-market.public/public/og/for-grocery.png b/src/food-market.public/public/og/for-grocery.png new file mode 100644 index 0000000..80970a7 Binary files /dev/null and b/src/food-market.public/public/og/for-grocery.png differ diff --git a/src/food-market.public/public/og/for-household.png b/src/food-market.public/public/og/for-household.png new file mode 100644 index 0000000..abb7faa Binary files /dev/null and b/src/food-market.public/public/og/for-household.png differ diff --git a/src/food-market.public/public/og/for-pharmacy.png b/src/food-market.public/public/og/for-pharmacy.png new file mode 100644 index 0000000..7e4067c Binary files /dev/null and b/src/food-market.public/public/og/for-pharmacy.png differ diff --git a/src/food-market.public/public/og/home.png b/src/food-market.public/public/og/home.png new file mode 100644 index 0000000..6c5db78 Binary files /dev/null and b/src/food-market.public/public/og/home.png differ diff --git a/src/food-market.public/public/og/import.png b/src/food-market.public/public/og/import.png new file mode 100644 index 0000000..9e85f04 Binary files /dev/null and b/src/food-market.public/public/og/import.png differ diff --git a/src/food-market.public/public/og/pos.png b/src/food-market.public/public/og/pos.png new file mode 100644 index 0000000..88d5fc6 Binary files /dev/null and b/src/food-market.public/public/og/pos.png differ diff --git a/src/food-market.public/public/og/pricing.png b/src/food-market.public/public/og/pricing.png new file mode 100644 index 0000000..ffcd5a6 Binary files /dev/null and b/src/food-market.public/public/og/pricing.png differ diff --git a/src/food-market.public/public/photos/CREDITS.md b/src/food-market.public/public/photos/CREDITS.md new file mode 100644 index 0000000..6175f19 --- /dev/null +++ b/src/food-market.public/public/photos/CREDITS.md @@ -0,0 +1,20 @@ +# Photo credits + +Все фотографии скачаны с [Unsplash](https://unsplash.com) под Unsplash License. + +| Файл | Photo ID | Автор | Профиль | +|---|---|---|---| +| pos-hero.jpg | -gkndM1GvSA | Simon Kadula | https://unsplash.com/@simonkadula | +| import-hero.jpg | phS1wAgXOQI | prashant hiremath | https://unsplash.com/@prashanth_hiremath | +| vertical-grocery.jpg | je2x0sIUtjM | Artem Stoliar | https://unsplash.com/@artem_stoliar | +| vertical-pharmacy.jpg | FOSgYGDktlE | Bernd Dittrich | https://unsplash.com/@hdbernd | +| vertical-cafe.jpg | 4bKpMYjVquo | KWON JUNHO | https://unsplash.com/@junho01 | +| vertical-alcohol.jpg | e0d-QR0gUFE | Alexander Schimmeck | https://unsplash.com/@alschim | +| vertical-clothing.jpg | DS7N9ZnKpO0 | Tanya Barrow | https://unsplash.com/@tanya_barrow | +| vertical-household.jpg | sf6YUxvCoro | Tianlei Wu | https://unsplash.com/@tianlei_wu | +| about-hero.jpg | _BHlEskTT4c | Vitaly Gariev | https://unsplash.com/@silverkblack | +| blog-launch.jpg | O1jUvZX9DOA | Andy Hermawan | https://unsplash.com/@andyhermawan | +| blog-scales.jpg | cCFb5QAgFLs | Far Chinberdiev | https://unsplash.com/@farchinberdiev | +| blog-quickstart.jpg | wgj5GDDPA0I | javier trueba | https://unsplash.com/@javitrapero | +| integrations.jpg | bf9sZBcGQl4 | 1981 Digital | https://unsplash.com/@nineteen81digital | +| cta-banner.jpg | 2oBnIuO9wv4 | Vitaly Gariev | https://unsplash.com/@silverkblack | diff --git a/src/food-market.public/public/photos/about-hero.jpg b/src/food-market.public/public/photos/about-hero.jpg new file mode 100644 index 0000000..72771a5 Binary files /dev/null and b/src/food-market.public/public/photos/about-hero.jpg differ diff --git a/src/food-market.public/public/photos/blog-launch.jpg b/src/food-market.public/public/photos/blog-launch.jpg new file mode 100644 index 0000000..69b0547 Binary files /dev/null and b/src/food-market.public/public/photos/blog-launch.jpg differ diff --git a/src/food-market.public/public/photos/blog-quickstart.jpg b/src/food-market.public/public/photos/blog-quickstart.jpg new file mode 100644 index 0000000..cdca02c Binary files /dev/null and b/src/food-market.public/public/photos/blog-quickstart.jpg differ diff --git a/src/food-market.public/public/photos/blog-scales.jpg b/src/food-market.public/public/photos/blog-scales.jpg new file mode 100644 index 0000000..f937eb6 Binary files /dev/null and b/src/food-market.public/public/photos/blog-scales.jpg differ diff --git a/src/food-market.public/public/photos/cta-banner.jpg b/src/food-market.public/public/photos/cta-banner.jpg new file mode 100644 index 0000000..9939332 Binary files /dev/null and b/src/food-market.public/public/photos/cta-banner.jpg differ diff --git a/src/food-market.public/public/photos/import-hero.jpg b/src/food-market.public/public/photos/import-hero.jpg new file mode 100644 index 0000000..61f2f3c Binary files /dev/null and b/src/food-market.public/public/photos/import-hero.jpg differ diff --git a/src/food-market.public/public/photos/integrations.jpg b/src/food-market.public/public/photos/integrations.jpg new file mode 100644 index 0000000..7746ee2 Binary files /dev/null and b/src/food-market.public/public/photos/integrations.jpg differ diff --git a/src/food-market.public/public/photos/pos-hero.jpg b/src/food-market.public/public/photos/pos-hero.jpg new file mode 100644 index 0000000..c5181e1 Binary files /dev/null and b/src/food-market.public/public/photos/pos-hero.jpg differ diff --git a/src/food-market.public/public/photos/vertical-alcohol.jpg b/src/food-market.public/public/photos/vertical-alcohol.jpg new file mode 100644 index 0000000..f29a7bc Binary files /dev/null and b/src/food-market.public/public/photos/vertical-alcohol.jpg differ diff --git a/src/food-market.public/public/photos/vertical-cafe.jpg b/src/food-market.public/public/photos/vertical-cafe.jpg new file mode 100644 index 0000000..199cd18 Binary files /dev/null and b/src/food-market.public/public/photos/vertical-cafe.jpg differ diff --git a/src/food-market.public/public/photos/vertical-clothing.jpg b/src/food-market.public/public/photos/vertical-clothing.jpg new file mode 100644 index 0000000..936abf8 Binary files /dev/null and b/src/food-market.public/public/photos/vertical-clothing.jpg differ diff --git a/src/food-market.public/public/photos/vertical-grocery.jpg b/src/food-market.public/public/photos/vertical-grocery.jpg new file mode 100644 index 0000000..1fee5bd Binary files /dev/null and b/src/food-market.public/public/photos/vertical-grocery.jpg differ diff --git a/src/food-market.public/public/photos/vertical-household.jpg b/src/food-market.public/public/photos/vertical-household.jpg new file mode 100644 index 0000000..e16fbc3 Binary files /dev/null and b/src/food-market.public/public/photos/vertical-household.jpg differ diff --git a/src/food-market.public/public/photos/vertical-pharmacy.jpg b/src/food-market.public/public/photos/vertical-pharmacy.jpg new file mode 100644 index 0000000..8656ec2 Binary files /dev/null and b/src/food-market.public/public/photos/vertical-pharmacy.jpg differ diff --git a/src/food-market.public/public/screenshots/analytics.png b/src/food-market.public/public/screenshots/analytics.png new file mode 100644 index 0000000..177f173 Binary files /dev/null and b/src/food-market.public/public/screenshots/analytics.png differ diff --git a/src/food-market.public/public/screenshots/catalog.png b/src/food-market.public/public/screenshots/catalog.png new file mode 100644 index 0000000..b789ecb Binary files /dev/null and b/src/food-market.public/public/screenshots/catalog.png differ diff --git a/src/food-market.public/public/screenshots/counterparties.png b/src/food-market.public/public/screenshots/counterparties.png new file mode 100644 index 0000000..0883d6c Binary files /dev/null and b/src/food-market.public/public/screenshots/counterparties.png differ diff --git a/src/food-market.public/public/screenshots/dashboard-hero.png b/src/food-market.public/public/screenshots/dashboard-hero.png new file mode 100644 index 0000000..177f173 Binary files /dev/null and b/src/food-market.public/public/screenshots/dashboard-hero.png differ diff --git a/src/food-market.public/public/screenshots/product-card.png b/src/food-market.public/public/screenshots/product-card.png new file mode 100644 index 0000000..126fc37 Binary files /dev/null and b/src/food-market.public/public/screenshots/product-card.png differ diff --git a/src/food-market.public/public/screenshots/supply-form.png b/src/food-market.public/public/screenshots/supply-form.png new file mode 100644 index 0000000..cd946a6 Binary files /dev/null and b/src/food-market.public/public/screenshots/supply-form.png differ diff --git a/src/food-market.public/scripts/og.mjs b/src/food-market.public/scripts/og.mjs new file mode 100644 index 0000000..c457796 --- /dev/null +++ b/src/food-market.public/scripts/og.mjs @@ -0,0 +1,117 @@ +import satori from 'satori' +import { Resvg } from '@resvg/resvg-js' +import fs from 'node:fs/promises' +import path from 'node:path' +import { fileURLToPath } from 'node:url' + +const __dirname = path.dirname(fileURLToPath(import.meta.url)) +const FONTS = path.join(__dirname, 'fonts') +const OUT = path.resolve(__dirname, '..', 'public', 'og') + +const interReg = await fs.readFile(path.join(FONTS, 'Inter-Regular.ttf')) +const interBold = await fs.readFile(path.join(FONTS, 'Inter-Bold.ttf')) + +const pages = [ + { file: 'home.png', title: 'Программа учёта и касса для розничных магазинов в Казахстане', sub: 'Касса с торговыми весами, импорт каталога, ОФД РК. Бесплатно 90 дней.' }, + { file: 'pos.png', title: 'Касса для Windows с поддержкой торговых весов', sub: 'Установка за 5 минут. Офлайн-режим. Стандартное оборудование.' }, + { file: 'pricing.png', title: 'Прозрачные тарифы Food Market', sub: 'От 5 000 ₸/мес. Все возможности на любом тарифе. 90 дней триал.' }, + { file: 'import.png', title: 'Перенесите каталог за один клик', sub: 'Excel, CSV, REST API. До 100 000 товаров. Бесплатно.' }, + { file: 'about.png', title: 'О Food Market', sub: 'Программа учёта розничной торговли, созданная в Казахстане.' }, + { file: 'for-grocery.png', title: 'Food Market для продуктового магазина', sub: 'Весовой товар, скоропорт, штрихкоды, ABC-анализ.' }, + { file: 'for-pharmacy.png', title: 'Food Market для аптеки', sub: 'Серии, сроки годности, рецептурный отпуск, контроль ЛП.' }, + { file: 'for-cafe.png', title: 'Food Market для кафе и общепита', sub: 'Модификаторы блюд, столики, печать на кухню.' }, + { file: 'for-alcohol.png', title: 'Food Market для алкомаркета', sub: 'Акцизные марки, контроль времени продаж, маркировка.' }, + { file: 'for-clothing.png', title: 'Food Market для магазина одежды', sub: 'Размерные сетки, цветовые матрицы, остатки по размерам.' }, + { file: 'for-household.png', title: 'Food Market для дома и быта', sub: 'Гарантийные сроки, серийные номера, характеристики.' }, +] + +const tmpl = ({ title, sub }) => ({ + type: 'div', + props: { + style: { + width: '1200px', height: '630px', display: 'flex', flexDirection: 'column', + justifyContent: 'space-between', padding: '64px', + background: 'linear-gradient(135deg, #ECFDF5 0%, #D1FAE5 60%, #A7F3D0 100%)', + fontFamily: 'Inter', + }, + children: [ + // Logo + brand row + { + type: 'div', + props: { + style: { display: 'flex', alignItems: 'center', gap: '14px' }, + children: [ + { + type: 'div', + props: { + style: { + width: '56px', height: '56px', borderRadius: '14px', + background: '#00B207', + display: 'flex', alignItems: 'center', justifyContent: 'center', + color: '#FFFFFF', fontSize: '32px', fontWeight: 700, + }, + children: 'F', + }, + }, + { + type: 'div', + props: { + style: { display: 'flex', flexDirection: 'column' }, + children: [ + { type: 'span', props: { style: { color: '#0F172A', fontSize: '26px', fontWeight: 700, lineHeight: 1 }, children: 'Food Market' } }, + { type: 'span', props: { style: { color: '#475569', fontSize: '15px', fontWeight: 400, marginTop: '4px' }, children: 'Программа учёта · Касса · Касса для Windows' } }, + ], + }, + }, + ], + }, + }, + // Title + subtitle + { + type: 'div', + props: { + style: { display: 'flex', flexDirection: 'column', gap: '20px', maxWidth: '1000px' }, + children: [ + { type: 'div', props: { style: { color: '#0F172A', fontSize: title.length > 60 ? '54px' : '64px', fontWeight: 700, lineHeight: 1.15 }, children: title } }, + { type: 'div', props: { style: { color: '#475569', fontSize: '28px', fontWeight: 400, lineHeight: 1.3 }, children: sub } }, + ], + }, + }, + // Footer + { + type: 'div', + props: { + style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between' }, + children: [ + { type: 'div', props: { style: { color: '#0F172A', fontSize: '20px', fontWeight: 700 }, children: 'food-market.zat.kz' } }, + { + type: 'div', + props: { + style: { + background: '#00B207', color: '#FFFFFF', + padding: '14px 28px', borderRadius: '10px', fontSize: '20px', fontWeight: 700, + }, + children: 'Начать бесплатно →', + }, + }, + ], + }, + }, + ], + }, +}) + +await fs.mkdir(OUT, { recursive: true }) +for (const p of pages) { + const svg = await satori(tmpl(p), { + width: 1200, height: 630, + fonts: [ + { name: 'Inter', data: interReg, weight: 400, style: 'normal' }, + { name: 'Inter', data: interBold, weight: 700, style: 'normal' }, + ], + }) + const png = new Resvg(svg, { fitTo: { mode: 'width', value: 1200 } }).render().asPng() + await fs.writeFile(path.join(OUT, p.file), png) + console.log('og →', p.file) +} +console.log('done') diff --git a/src/food-market.public/scripts/screenshots.mjs b/src/food-market.public/scripts/screenshots.mjs new file mode 100644 index 0000000..0cc9a49 --- /dev/null +++ b/src/food-market.public/scripts/screenshots.mjs @@ -0,0 +1,111 @@ +import { chromium } from 'playwright' +import path from 'node:path' +import { fileURLToPath } from 'node:url' + +const __dirname = path.dirname(fileURLToPath(import.meta.url)) +const OUT = path.resolve(__dirname, '..', 'public', 'screenshots') + +const APP = 'https://app.food-market.zat.kz' +const EMAIL = 'admin@food-market.local' +const PASSWORD = 'Admin12345!' + +const browser = await chromium.launch({ headless: true }) +const ctx = await browser.newContext({ ignoreHTTPSErrors: true, viewport: { width: 1600, height: 1000 } }) +const page = await ctx.newPage() + +console.log('login →', APP) +await page.goto(`${APP}/login`, { waitUntil: 'networkidle' }) +await page.fill('input[type="email"]', EMAIL) +await page.fill('input[type="password"]', PASSWORD) +await page.click('button[type="submit"]') +await page.waitForURL((u) => !u.pathname.startsWith('/login'), { timeout: 30000 }) +await page.waitForTimeout(1500) +console.log('logged in →', page.url()) + +// Override tenant: переходим на /super-admin/organizations → клик «Открыть» +// у строки FOOD MARKET (иконка-стрелка, title=«Открыть как…»). +console.log('tenant override → FOOD MARKET') +await page.goto(`${APP}/super-admin/organizations`, { waitUntil: 'networkidle' }) +await page.waitForTimeout(1000) +// Клик на ряд FOOD MARKET — берём первую строку с этим текстом и в ней +// первую кнопку-ссылку (login-icon). +const rows = await page.$$('table tbody tr, tbody tr, [role="row"]') +let opened = false +for (const r of rows) { + const txt = (await r.innerText()).trim() + if (/FOOD MARKET/i.test(txt)) { + const btn = await r.$('a, button') + if (btn) { + await btn.click() + opened = true + break + } + } +} +if (!opened) { + // Fallback: клик по последней login-стрелке (там обычно FOOD MARKET). + const arrows = await page.$$('a[href*="/api/super-admin/organizations/"][href*="open"], button[title*="ткрыт"]') + if (arrows.length) await arrows[arrows.length - 1].click() +} +await page.waitForTimeout(2000) +await page.waitForLoadState('networkidle') +console.log('after override →', page.url()) + +const shots = [ + { name: 'dashboard-hero.png', path: '/dashboard', vp: { width: 1600, height: 1000 } }, + { name: 'analytics.png', path: '/dashboard', vp: { width: 1600, height: 1000 }, scrollY: 500 }, + { name: 'catalog.png', path: '/catalog/products', vp: { width: 1600, height: 1000 } }, + { name: 'product-card.png', path: '/catalog/products', vp: { width: 1200, height: 900 }, openFirst: true }, + { name: 'counterparties.png', path: '/catalog/counterparties', vp: { width: 1200, height: 900 } }, + { name: 'supply-form.png', path: '/purchases/supplies/new', vp: { width: 1200, height: 900 } }, +] + +// CSS, скрывающий override-warning баннер (оранжевую полосу сверху). +const HIDE_OVERRIDE_CSS = ` + [class*="bg-orange"], [class*="bg-amber"], [class*="bg-yellow-4"], + [class*="ENV"], header [class*="orange"], div[class*="режиме"], + div:has(> *:not(:empty):where(:scope:contains("СУПЕР-АДМИНА"))) { display: none !important; } +` + +for (const s of shots) { + console.log('shot', s.name, '←', s.path) + await page.setViewportSize(s.vp) + await page.goto(`${APP}${s.path}`, { waitUntil: 'networkidle' }) + await page.waitForTimeout(2000) + // Убираем оранжевый override-баннер по тексту. + await page.evaluate(() => { + document.querySelectorAll('div, header').forEach((el) => { + const t = el.textContent || '' + if (/В РЕЖИМЕ СУПЕР-АДМИНА/i.test(t) && el.children.length < 6 && el.offsetHeight < 80) { + el.style.display = 'none' + } + }) + }) + if (s.scrollY) { + await page.evaluate((y) => window.scrollTo(0, y), s.scrollY) + await page.waitForTimeout(500) + } + if (s.openFirst) { + const cellLink = await page.$('table tbody tr td a, table tbody tr td button') + if (cellLink) { + try { + await cellLink.click() + await page.waitForLoadState('networkidle', { timeout: 10000 }) + await page.waitForTimeout(2000) + } catch (e) { + console.warn(' openFirst click failed:', e.message) + } + } else { + // Fallback: клик в первую ячейку строки. + const firstCell = await page.$('table tbody tr') + if (firstCell) { + try { await firstCell.click(); await page.waitForTimeout(2000) } catch {} + } + } + } + await page.screenshot({ path: path.join(OUT, s.name), fullPage: false }) + console.log(' ok →', s.name, s.vp.width + 'x' + s.vp.height) +} + +await browser.close() +console.log('done') diff --git a/src/food-market.public/src/components/FAQ.tsx b/src/food-market.public/src/components/FAQ.tsx index c03f756..dedad7c 100644 --- a/src/food-market.public/src/components/FAQ.tsx +++ b/src/food-market.public/src/components/FAQ.tsx @@ -3,7 +3,7 @@ import { useState } from 'react' const ITEMS = [ { q: 'Чем Food Market подходит моему магазину?', - a: 'Food Market — облачная программа учёта розничной торговли, созданная под казахстанский рынок. Поддерживает все типы магазинов: продуктовые, аптеки, общепит, алкомаркеты, одежду, бытовые товары. Включает кассу для Windows с нативной поддержкой весов Масса-К, интеграцию с ОФД РК, Kaspi Pay и казахстанскими банками.', + a: 'Food Market — облачная программа учёта розничной торговли, созданная под казахстанский рынок. Поддерживает все типы магазинов: продуктовые, аптеки, общепит, алкомаркеты, одежду, бытовые товары. Включает кассу для Windows с нативной поддержкой торговых весов, интеграцию с ОФД РК, Kaspi Pay и казахстанскими банками.', }, { q: 'Сколько стоит подписка?', diff --git a/src/food-market.public/src/content/blog/cash-with-scales.md b/src/food-market.public/src/content/blog/cash-with-scales.md index bc7fbd8..18d30d8 100644 --- a/src/food-market.public/src/content/blog/cash-with-scales.md +++ b/src/food-market.public/src/content/blog/cash-with-scales.md @@ -1,51 +1,43 @@ --- -title: "Касса с весами Масса-К — почему это важно для магазина" +title: "Касса с поддержкой весов — почему это важно для магазина" date: 2026-05-02 author: Команда Food Market category: feature -description: "80% магазинов в Казахстане используют Масса-К. Как мы сделали поддержку нативной — без сторонних драйверов и подписок." -cover_image: /blog/scales.jpg +description: "Если вы продаёте на развес, работа с весами обычно — самое болезненное место при настройке кассы. Рассказываем, как мы сделали её простой." +cover_image: /photos/blog-scales.jpg --- -# Касса с весами Масса-К — почему это важно +# Касса с поддержкой весов — почему это важно -Если вы продаёте овощи, фрукты, мясо, сыр или орехи на развес — у вас 99% шанс используются весы **Масса-К**. Это казахстанско-российский стандарт. +Если вы продаёте овощи, фрукты, мясо, сыр или орехи на развес — без подключения торговых весов касса теряет смысл. Кассир вводит вес и цену вручную, делает ошибки, очередь стоит. Десять секунд на каждую позицию складываются в минуты. -И именно работа с весами часто становится самым болезненным местом при настройке кассового оборудования. +И именно работа с весами часто становится самым болезненным местом при настройке кассового оборудования: разные протоколы, COM-порты, драйверы под Windows, фирменные «модули интеграции» с подпиской. ## Как мы решили эту задачу -Мы написали свой парсер протокола Масса-К прямо в кассу. Это заняло около 2 недель разработки. Зато теперь весы работают нативно: +Мы написали обработку стандартных протоколов торговых весов прямо в кассу. Зато теперь весы работают нативно: - Установили Касса Food Market для Windows -- Подключили весы Масса-К через RS-232 или USB-COM кабель +- Подключили торговые весы через RS-232 или USB-COM кабель - Запустили кассу — **всё** Касса автоматически: - Опрашивает COM-порт каждые 200 мс -- Распознаёт модель Масса-К (МК-А, МК-В, MK-T, MK-D) +- Распознаёт подключённую модель - Считывает вес и штрихкод PLU - Подставляет позицию в открытый чек -Никаких сторонних драйверов. Никаких подписок на «модули интеграции». Никаких бубенов с COM-портами. +Никаких сторонних драйверов. Никаких подписок на «модули интеграции». Никаких бубнов с COM-портами. -## Какие модели поддерживаем +## Какие весы поддерживаем -Текущие версии: -- **МК-А** (механические с чеком) — все модели -- **МК-В** (электронные) — все модели -- **MK-T** (торговые) — все модели -- **MK-D** (для прилавочной торговли) — все модели - -Планируем в ближайшем апдейте поддержку других распространённых в Казахстане производителей весов — пишите, какая модель у вас стоит, и мы добавим её в очередь. - -Не уверены, что ваша модель подойдёт? [Напишите →](/contacts) — проверим за 5 минут. +Электронные торговые весы стандартных протоколов — основные варианты, встречающиеся в Казахстане. Не уверены, что ваша модель подойдёт? [Напишите →](/contacts) — проверим за 5 минут. ## Что это даёт магазину - **Скорость обслуживания вырастает на 30%** — кассир не вводит вес и цену вручную, всё автоматически - **Меньше ошибок** — нет человеческого фактора при пробивании веса -- **Дешевле в эксплуатации** — не платите за стороние модули интеграции +- **Дешевле в эксплуатации** — не платите за сторонние модули интеграции - **Проще обучение кассиров** — они работают как привыкли, никакой «сложной системы» [Скачать кассу →](/pos) diff --git a/src/food-market.public/src/content/blog/launch.md b/src/food-market.public/src/content/blog/launch.md index aa9e9a6..f4ab4ab 100644 --- a/src/food-market.public/src/content/blog/launch.md +++ b/src/food-market.public/src/content/blog/launch.md @@ -4,7 +4,7 @@ date: 2026-04-26 author: Команда Food Market category: news description: "Сегодня мы запускаем Food Market — программу учёта розничной торговли, созданную в Казахстане для казахстанских магазинов." -cover_image: /blog/launch.jpg +cover_image: /photos/blog-launch.jpg --- # Food Market запустился @@ -17,7 +17,7 @@ cover_image: /blog/launch.jpg - **работать с первого клика** — без долгой настройки и платных консультаций - **стоить честно** — без скрытых доплат за модули, которые должны быть в базе -- **поддерживать локальное железо** — Масса-К нативно, без переходников и сторонних драйверов +- **поддерживать локальное железо** — торговые весы нативно, без переходников и сторонних драйверов - **позволять попробовать без риска** — настоящий триал, а не «14 дней с привязкой карты» Мы воплотили эти принципы в Food Market. @@ -26,7 +26,7 @@ cover_image: /blog/launch.jpg - **5 000 тг/мес** за тариф «Старт» — 1 магазин, 1 касса, 1 склад, без лимита товаров - **90 дней триала** без карты, без обязательств, со всеми возможностями -- **Касса для Windows** с нативной поддержкой Масса-К +- **Касса для Windows** с нативной поддержкой торговых весов - **Импорт каталога** из Excel, CSV или API за один клик - **Все возможности на любом тарифе** — никаких доплат за CRM, лояльность, финансы или сценарии diff --git a/src/food-market.public/src/content/blog/quick-start.md b/src/food-market.public/src/content/blog/quick-start.md index f183d14..f396ec8 100644 --- a/src/food-market.public/src/content/blog/quick-start.md +++ b/src/food-market.public/src/content/blog/quick-start.md @@ -4,7 +4,7 @@ date: 2026-04-30 author: Команда Food Market category: guide description: "Пошаговая инструкция первого запуска: от регистрации до первой продажи." -cover_image: /blog/quickstart.jpg +cover_image: /photos/blog-quickstart.jpg --- # Запустите магазин в Food Market за 15 минут @@ -46,7 +46,7 @@ cover_image: /blog/quickstart.jpg 1. Запустите .msi файл — нажмите «Далее» три раза 2. Введите ключ организации (показан в админке) -3. Подключите весы Масса-К через USB-COM +3. Подключите торговые весы через USB-COM 4. Подключите сканер штрихкодов через USB 5. Подключите чековый принтер diff --git a/src/food-market.public/src/content/kb/faq.md b/src/food-market.public/src/content/kb/faq.md index 7ad86d7..e8682cb 100644 --- a/src/food-market.public/src/content/kb/faq.md +++ b/src/food-market.public/src/content/kb/faq.md @@ -44,7 +44,7 @@ order: 99 ## Возможности -### Поддерживаете весы Масса-К? +### Поддерживаете торговые весы? Да, нативно — без сторонних драйверов и переходников. ### Какие сканеры штрихкодов поддерживаете? diff --git a/src/food-market.public/src/content/kb/pos-setup.md b/src/food-market.public/src/content/kb/pos-setup.md index 74214ca..92d9580 100644 --- a/src/food-market.public/src/content/kb/pos-setup.md +++ b/src/food-market.public/src/content/kb/pos-setup.md @@ -49,14 +49,14 @@ order: 1 ## Подключение оборудования -### Весы Масса-К +### Торговые весы 1. Подключите весы к компьютеру через кабель RS-232 или USB-COM 2. В кассе откройте «Настройки» → «Оборудование» → «Весы» -3. Нажмите «Найти весы» — касса опросит COM-порты и распознает Масса-К автоматически +3. Нажмите «Найти весы» — касса опросит COM-порты и распознает подключённую модель автоматически 4. Поставьте на чашу любой груз — должна появиться цифра в нижней панели кассы -Поддерживаемые модели: МК-А, МК-В, MK-T, MK-D и совместимые. +Поддерживаются электронные весы стандартных протоколов. ### Сканер штрихкодов diff --git a/src/food-market.public/src/content/kb/quickstart.md b/src/food-market.public/src/content/kb/quickstart.md index cfe6dff..0fd8918 100644 --- a/src/food-market.public/src/content/kb/quickstart.md +++ b/src/food-market.public/src/content/kb/quickstart.md @@ -39,7 +39,7 @@ order: 1 «Касса» → «Скачать установщик». Запустите .msi файл, нажмите «Далее» три раза. После установки введите ключ организации (показан в разделе «Касса»). Подключите оборудование: -- Весы Масса-К — через RS-232 или USB-COM +- Электронные торговые весы — через RS-232 или USB-COM - Сканер штрихкодов — USB - Чековый принтер — USB или сетевой diff --git a/src/food-market.public/src/layouts/BaseLayout.astro b/src/food-market.public/src/layouts/BaseLayout.astro index 9821f65..1f5b558 100644 --- a/src/food-market.public/src/layouts/BaseLayout.astro +++ b/src/food-market.public/src/layouts/BaseLayout.astro @@ -8,7 +8,7 @@ interface Props { description?: string ogImage?: string } -const { title, description = 'Программа учёта и касса для розничных магазинов в Казахстане. Бесплатно 90 дней.', ogImage = '/og.png' } = Astro.props +const { title, description = 'Программа учёта и касса для розничных магазинов в Казахстане. Бесплатно 90 дней.', ogImage = '/og/home.png' } = Astro.props const canonical = new URL(Astro.url.pathname, Astro.site).toString() --- @@ -31,6 +31,7 @@ const canonical = new URL(Astro.url.pathname, Astro.site).toString() + diff --git a/src/food-market.public/src/pages/about.astro b/src/food-market.public/src/pages/about.astro index c3e20fc..802c09f 100644 --- a/src/food-market.public/src/pages/about.astro +++ b/src/food-market.public/src/pages/about.astro @@ -1,11 +1,13 @@ --- import BaseLayout from '@/layouts/BaseLayout.astro' --- - -
-
-

О Food Market

-

Программа учёта розничной торговли, созданная в Казахстане для казахстанских магазинов.

+ +
+ +
+
+

О Food Market

+

Программа учёта розничной торговли, созданная в Казахстане для казахстанских магазинов.

@@ -13,12 +15,12 @@ import BaseLayout from '@/layouts/BaseLayout.astro'

История

Food Market запустился в 2026 году как ответ на запрос рынка: розничные магазины в Казахстане заслуживают современный, быстрый и честный инструмент для ведения бизнеса.

Команда основателей — практики розницы и разработчики, которые три года изнутри наблюдали как магазины ведут учёт, какие проблемы решают каждый день, чего им не хватает в существующих инструментах.

-

Мы поставили перед собой задачу сделать продукт, который работает с первого клика — без долгой настройки и платных консультаций; нативно поддерживает локальное железо (Масса-К из коробки, без переходников); соответствует реалиям РК (Kaspi Pay, ОФД, законодательство, поддержка на русском); и который можно попробовать без риска — настоящий триал, без привязки карты.

+

Мы поставили перед собой задачу сделать продукт, который работает с первого клика — без долгой настройки и платных консультаций; нативно поддерживает локальное железо (торговые весы из коробки, без переходников); соответствует реалиям РК (Kaspi Pay, ОФД, законодательство, поддержка на русском); и который можно попробовать без риска — настоящий триал, без привязки карты.

Почему мы

Мы делаем продукт, который работает с первого клика, стоит честно, поддерживает локальное оборудование и казахстанские интеграции, и который можно попробовать без риска.

    -
  • Касса с весами Масса-К из коробки — без переходников и сторонних драйверов.
  • +
  • Касса с поддержкой торговых весов из коробки — без переходников и сторонних драйверов.
  • Импорт каталога одной кнопкой — старый учёт переносится автоматически.
  • 90 дней бесплатно без банковской карты — никаких автосписаний и сюрпризов.
  • Все модули в одном тарифе — CRM, лояльность, финансы, склад, аналитика включены.
  • diff --git a/src/food-market.public/src/pages/blog/[slug].astro b/src/food-market.public/src/pages/blog/[slug].astro index 9212723..af61353 100644 --- a/src/food-market.public/src/pages/blog/[slug].astro +++ b/src/food-market.public/src/pages/blog/[slug].astro @@ -11,6 +11,11 @@ const { Content } = await post.render() const fmt = post.data.date.toLocaleDateString('ru-KZ', { day: '2-digit', month: 'long', year: 'numeric' }) --- + {post.data.cover_image && ( +
    + +
    + )}
    ← Все посты

    {fmt}

    diff --git a/src/food-market.public/src/pages/features.astro b/src/food-market.public/src/pages/features.astro index 2a26cec..d73c746 100644 --- a/src/food-market.public/src/pages/features.astro +++ b/src/food-market.public/src/pages/features.astro @@ -2,7 +2,7 @@ import BaseLayout from '@/layouts/BaseLayout.astro' const sections = [ { id: 'catalog', icon: '📦', title: 'Товары и каталог', items: ['Иерархические группы и подгруппы','Штрихкоды EAN-13/EAN-8/Code128','Цены: розничная, оптовая, эталонная','Автогенерация артикула и штрихкода','Импорт из других систем','Картинки товаров','Атрибуты и характеристики'] }, - { id: 'sales', icon: '💳', title: 'Продажи и касса', items: ['Касса для Windows','Поддержка весов Масса-К','Сканер штрихкодов USB','Чековые принтеры ESC/POS','Kaspi Pay интеграция','Скидки и акции','Возвраты на кассе'] }, + { id: 'sales', icon: '💳', title: 'Продажи и касса', items: ['Касса для Windows','Поддержка торговых весов','Сканер штрихкодов USB','Чековые принтеры ESC/POS','Kaspi Pay интеграция','Скидки и акции','Возвраты на кассе'] }, { id: 'stock', icon: '🏬', title: 'Склад и остатки', items: ['Несколько складов','Приёмка со сканером','Автоматический расчёт себестоимости','Инвентаризация','Списание (брак/просрочка)','Оприходование','Перемещения между складами','История движений'] }, { id: 'purchase', icon: '🚚', title: 'Закупки и поставщики', items: ['База контрагентов','Заказы поставщикам','Документы приёмки','Скользящее среднее себестоимости','Эталонная цена'] }, { id: 'crm', icon: '👥', title: 'Клиенты и лояльность', items: ['База клиентов','Скидочные карты (скоро)','Программы лояльности (скоро)','Сегментация (скоро)','SMS-рассылки (скоро)'] }, diff --git a/src/food-market.public/src/pages/for-alcohol.astro b/src/food-market.public/src/pages/for-alcohol.astro index e519b1d..b364c67 100644 --- a/src/food-market.public/src/pages/for-alcohol.astro +++ b/src/food-market.public/src/pages/for-alcohol.astro @@ -7,13 +7,15 @@ const features = [ { icon: '🆔', title: 'Проверка возраста', text: 'Запрос подтверждения возраста на кассе перед продажей алкогольных позиций.' }, ] --- - -
    -
    + +
    + +
    +
    🍷 -

    Программа учёта для алкоголя

    -

    Акцизные марки, ЕГАИС-ready, контроль времени продаж и возраста.

    - Начать бесплатно +

    Программа учёта
    для алкоголя

    +

    Акцизные марки, ЕГАИС-ready, контроль времени продаж и возраста.

    + Начать бесплатно
    diff --git a/src/food-market.public/src/pages/for-cafe.astro b/src/food-market.public/src/pages/for-cafe.astro index 98e2707..4f1a018 100644 --- a/src/food-market.public/src/pages/for-cafe.astro +++ b/src/food-market.public/src/pages/for-cafe.astro @@ -7,13 +7,15 @@ const features = [ { icon: '📈', title: 'Анализ блюд', text: 'Какие блюда продаются, какие нет. Маржинальность по позиции.' }, ] --- - -
    -
    + +
    + +
    +
    -

    Программа учёта для кафе и общепита

    -

    Модификаторы, комбо, технологические карты, заказы по столикам. Списание ингредиентов автоматом.

    - Начать бесплатно +

    Программа учёта
    для кафе и общепита

    +

    Модификаторы, комбо, технологические карты, заказы по столикам. Списание ингредиентов автоматом.

    + Начать бесплатно
    diff --git a/src/food-market.public/src/pages/for-clothing.astro b/src/food-market.public/src/pages/for-clothing.astro index 9b710a7..dd6dcc1 100644 --- a/src/food-market.public/src/pages/for-clothing.astro +++ b/src/food-market.public/src/pages/for-clothing.astro @@ -7,13 +7,15 @@ const features = [ { icon: '🔄', title: 'Возвраты', text: 'Удобный возврат на кассе с возвратом денег или обменом на другой размер.' }, ] --- - -
    -
    + +
    + +
    +
    👔 -

    Программа учёта для магазина одежды

    -

    Размерные сетки, цвета, выгрузка на маркетплейсы, удобные возвраты.

    - Начать бесплатно +

    Программа учёта
    для магазина одежды

    +

    Размерные сетки, цвета, выгрузка на маркетплейсы, удобные возвраты.

    + Начать бесплатно
    diff --git a/src/food-market.public/src/pages/for-grocery.astro b/src/food-market.public/src/pages/for-grocery.astro index 2050049..333addb 100644 --- a/src/food-market.public/src/pages/for-grocery.astro +++ b/src/food-market.public/src/pages/for-grocery.astro @@ -1,19 +1,21 @@ --- import BaseLayout from '@/layouts/BaseLayout.astro' const features = [ - { icon: '⚖️', title: 'Весовой товар', text: 'Касса принимает вес с весов Масса-К напрямую — стоимость пересчитывается сразу.' }, + { icon: '⚖️', title: 'Весовой товар', text: 'Касса принимает вес с торговых весов напрямую — стоимость пересчитывается сразу.' }, { icon: '📅', title: 'Скоропорт и сроки', text: 'Контроль сроков годности, уведомление за N дней, списание просрочки одним кликом.' }, { icon: '🏷️', title: 'Печать ценников и штрихкодов', text: 'Внутренняя нумерация EAN-13 для весовых товаров, автогенерация при заведении.' }, { icon: '📊', title: 'ABC-анализ', text: 'Ходовые и неходовые позиции по сумме / марже / штукам. Решения по матрице за минуту.' }, ] --- - -
    -
    + +
    + +
    +
    🛒 -

    Программа учёта для продуктового магазина

    -

    Весовой товар, скоропорт, штрихкоды, касса с весами Масса-К из коробки. Импорт из другой системы.

    - Начать бесплатно +

    Программа учёта
    для продуктового магазина

    +

    Весовой товар, скоропорт, штрихкоды, касса с поддержкой торговых весов из коробки. Импорт из другой системы.

    + Начать бесплатно
    diff --git a/src/food-market.public/src/pages/for-household.astro b/src/food-market.public/src/pages/for-household.astro index 07677d3..49332d7 100644 --- a/src/food-market.public/src/pages/for-household.astro +++ b/src/food-market.public/src/pages/for-household.astro @@ -7,13 +7,15 @@ const features = [ { icon: '📤', title: 'Маркетплейсы', text: 'Выгрузка на Kaspi Magazin, синхронизация цен и остатков (скоро).' }, ] --- - -
    -
    + +
    + +
    +
    🏠 -

    Программа учёта для дома и быта

    -

    Гарантийные сроки, серийные номера, комплекты, выгрузка на маркетплейсы.

    - Начать бесплатно +

    Программа учёта
    для дома и быта

    +

    Гарантийные сроки, серийные номера, комплекты, выгрузка на маркетплейсы.

    + Начать бесплатно
    diff --git a/src/food-market.public/src/pages/for-pharmacy.astro b/src/food-market.public/src/pages/for-pharmacy.astro index fb987b3..0f94676 100644 --- a/src/food-market.public/src/pages/for-pharmacy.astro +++ b/src/food-market.public/src/pages/for-pharmacy.astro @@ -7,13 +7,15 @@ const features = [ { icon: '🔒', title: 'Контроль доступа', text: 'Роли «Фармацевт» и «Заведующий» с разными правами. Логирование всех операций.' }, ] --- - -
    -
    + +
    + +
    +
    💊 -

    Программа учёта для аптеки

    -

    Серии и сроки годности, рецептурный отпуск, группировка по МНН. Импорт из другой системы.

    - Начать бесплатно +

    Программа учёта
    для аптеки

    +

    Серии и сроки годности, рецептурный отпуск, группировка по МНН. Импорт из другой системы.

    + Начать бесплатно
    diff --git a/src/food-market.public/src/pages/import.astro b/src/food-market.public/src/pages/import.astro index b65eaa9..a856f65 100644 --- a/src/food-market.public/src/pages/import.astro +++ b/src/food-market.public/src/pages/import.astro @@ -35,17 +35,21 @@ const faq = [ { q: 'Что если возникли проблемы?', a: 'Напишите на support@food-market.kz — поможем разобраться и при необходимости настроим импорт вручную.' }, ] --- - -
    -
    - Импорт -

    Перенесите каталог
    за один клик

    -

    - Не перепечатывайте товары вручную. Импортируйте каталог из вашей текущей системы за минуты. -

    -
    - Начать импорт - Поддерживаемые форматы + +
    + +
    +
    +
    + Импорт +

    Перенесите каталог
    за один клик

    +

    + Не перепечатывайте товары вручную. Импортируйте каталог из вашей текущей системы за минуты. +

    +
    diff --git a/src/food-market.public/src/pages/index.astro b/src/food-market.public/src/pages/index.astro index 77355eb..5614a15 100644 --- a/src/food-market.public/src/pages/index.astro +++ b/src/food-market.public/src/pages/index.astro @@ -13,7 +13,7 @@ const verticals = [ const modules = [ { icon: '📦', title: 'Товары и каталог', text: 'Группы, штрихкоды, цены, остатки, импорт каталога одной кнопкой.' }, - { icon: '💳', title: 'Продажи и касса', text: 'Касса для Windows с поддержкой весов Масса-К, штрихкодов, чековых принтеров.' }, + { icon: '💳', title: 'Продажи и касса', text: 'Касса для Windows с поддержкой торговых весов, штрихкодов, чековых принтеров.' }, { icon: '🏬', title: 'Склад и приёмки', text: 'Несколько складов, приёмка со сканером, инвентаризация, списание, оприходование.' }, { icon: '🚚', title: 'Закупки и поставщики', text: 'Документы приёмки с автоматическим расчётом себестоимости (скользящее среднее).' }, { icon: '👥', title: 'Клиенты и лояльность', text: 'База контрагентов, скидки, акции, программы лояльности (скоро).' }, @@ -27,7 +27,7 @@ const integrations = [ {/* 1. Hero */}
    @@ -37,7 +37,7 @@ const integrations = [ Программа учёта и касса для розничных магазинов в Казахстане

    - Касса с весами Масса-К, импорт каталога одной кнопкой, интеграция с Kaspi и ОФД РК. + Касса с поддержкой торговых весов, импорт каталога одной кнопкой, интеграция с Kaspi и ОФД РК. Бесплатно 90 дней без карты.

    @@ -46,14 +46,13 @@ const integrations = [

    Без банковской карты · 90 дней триал · Подписка от 5 000 ₸/мес

    -
    - {/* Реальный скриншот админки. Пока placeholder с типографическим mock'ом дашборда. */} -
    -
    Организаций
    2
    -
    Товаров
    29 540
    -
    Приёмок / мес
    187
    -
    Чеков сегодня
    432
    +
    +
    + + +
    + Дашборд Food Market
    @@ -63,7 +62,7 @@ const integrations = [
    🛒

    Касса с весами из коробки

    -

    Прямая поддержка Масса-К без переходников и драйверов. Подключите весы — Food Market распознает их автоматически. Поддержка штрихкодов, скидок, акций, лояльности.

    +

    Прямая поддержка торговых весов без переходников и драйверов. Подключите весы — Food Market распознает их автоматически. Поддержка штрихкодов, скидок, акций, лояльности.

    ⬇️
    @@ -79,10 +78,16 @@ const integrations = [ {/* 3. Скриншот продукта */}
    -
    -
    - Скриншот админки · реальный экран /dashboard +

    Один экран — весь магазин

    +

    Дашборд показывает выручку, остатки, движения и топ-товары. Без переключения вкладок и Excel-экспорта.

    +
    +
    + + + + app.food-market.kz / catalog / products
    + Каталог товаров Food Market — 29 540 SKU
    @@ -124,7 +129,7 @@ const integrations = [
    Касса для Windows -

    Кассовая программа с поддержкой весов Масса-К

    +

    Кассовая программа с поддержкой торговых весов

    Установщик для Windows 10/11. Работает офлайн, синхронизируется с админкой, принимает Kaspi Pay, печатает фискальные чеки в ОФД РК. @@ -134,19 +139,24 @@ const integrations = [ Скачать установщик

    -
    - Видео работы кассы · скоро +
    +
    +
    + Касса для Windows · работает офлайн, поддерживает торговые весы и Kaspi Pay +
    {/* 7. Интеграции */} -
    -
    +
    + +
    +

    Интеграции

    Кассы, банки, ОФД, маркетплейсы. Подключаем по запросу.

    {integrations.map((label) => ( - {label} + {label} ))}
    @@ -216,11 +226,13 @@ const integrations = [
    {/* 11. Финальный CTA */} -
    -
    -

    Запустите магазин за 15 минут

    -

    Регистрация — минута. Импорт товаров — десять минут. Касса работает на следующий день.

    - Начать бесплатно — 90 дней +
    + +
    +
    +

    Запустите магазин за 15 минут

    +

    Регистрация — минута. Импорт товаров — десять минут. Касса работает на следующий день.

    + Начать бесплатно — 90 дней
    diff --git a/src/food-market.public/src/pages/integrations.astro b/src/food-market.public/src/pages/integrations.astro index 8496461..6bddc85 100644 --- a/src/food-market.public/src/pages/integrations.astro +++ b/src/food-market.public/src/pages/integrations.astro @@ -4,8 +4,8 @@ const groups = [ { title: 'Платёжные системы', items: ['Kaspi Pay', 'Halyk Bank', 'Jusan Bank', 'Forte Bank'] }, { title: 'Фискализация', items: ['ОФД РК (все операторы)', 'Чековые принтеры ESC/POS'] }, { title: 'Маркетплейсы (скоро)', items: ['Kaspi Magazin', 'Ozon', 'Wildberries'] }, - { title: 'Учётные системы', items: ['другие системы (импорт каталога)', 'Excel CSV-импорт'] }, - { title: 'Оборудование', items: ['Весы Масса-К (USB/COM)', 'Сканеры штрихкодов USB', 'Денежные ящики', 'Дисплей покупателя'] }, + { title: 'Учётные системы', items: ['Импорт из других систем по API', 'Excel/CSV-импорт', 'Выгрузка 1С (XML/Excel)'] }, + { title: 'Оборудование', items: ['Электронные торговые весы (USB/COM)', 'Сканеры штрихкодов USB', 'Денежные ящики', 'Дисплей покупателя'] }, ] --- diff --git a/src/food-market.public/src/pages/pos.astro b/src/food-market.public/src/pages/pos.astro index c521577..2b1d288 100644 --- a/src/food-market.public/src/pages/pos.astro +++ b/src/food-market.public/src/pages/pos.astro @@ -1,7 +1,7 @@ --- import BaseLayout from '@/layouts/BaseLayout.astro' const features = [ - { icon: '⚖️', title: 'Нативная поддержка весов Масса-К', text: 'Подключите весы к компьютеру кассира — Food Market распознаёт их автоматически. Поддерживаемые модели: МК-А, МК-В, MK-T, MK-D и совместимые. Подключение через RS-232 или USB-COM. Никаких сторонних драйверов.' }, + { icon: '⚖️', title: 'Нативная поддержка торговых весов', text: 'Подключите весы к компьютеру кассира — Food Market распознаёт их автоматически. Поддерживаются электронные весы стандартных протоколов через RS-232 или USB-COM. Никаких сторонних драйверов.' }, { icon: '📡', title: 'Офлайн-режим без потери данных', text: 'Интернет пропал — касса продолжает работать. Все чеки записываются локально. Когда связь вернётся — данные подтянутся в облако автоматически.' }, { icon: '🛒', title: 'Сканеры штрихкодов любых производителей', text: 'Поддерживаем все стандартные модели работающие как клавиатура (HID-эмуляция). Подключили — и работает. EAN-13/EAN-8/Code128/Datamatrix.' }, { icon: '🖨️', title: 'Печать чеков на ОКП-совместимом оборудовании', text: 'Любые ОКП РК совместимые принтеры. Драйверы устанавливаются автоматически.' }, @@ -11,7 +11,7 @@ const features = [ ] const hardware = [ ['Компьютер', 'Windows 10+ (32/64 bit), 4 GB RAM, 5 GB на диске'], - ['Весы', 'Масса-К: МК-А, МК-В, MK-T, MK-D (RS-232/USB)'], + ['Весы', 'Электронные торговые весы стандартных протоколов (RS-232/USB)'], ['Сканер штрихкодов', 'Любой HID-совместимый USB-сканер'], ['Чековый принтер', 'Любой ОКП РК совместимый принтер'], ['Денежный ящик', 'Подключение через принтер чеков (RJ-11)'], @@ -25,23 +25,34 @@ const steps = [ ['Откройте смену', 'И пробивайте первый чек'], ] --- - -
    -
    - Касса -

    Касса для Windows
    с поддержкой весов Масса-К

    -

    - Установите за 5 минут. Работайте офлайн. Подключайте стандартное оборудование без переходников и сторонних драйверов. -

    -
    - Скачать кассу (Windows 10+) - Тарифы + +
    + +
    +
    +
    + Касса +

    Касса для Windows
    с поддержкой торговых весов

    +

    + Установите за 5 минут. Работайте офлайн. Подключайте стандартное оборудование без переходников и сторонних драйверов. +

    +
    + Скачать кассу (Windows 10+) + Тарифы +
    -
    Видео работы кассы · скоро
    +
    +
    + + + +
    + Окно приёмки в Food Market +
    diff --git a/src/food-market.public/src/pages/pricing.astro b/src/food-market.public/src/pages/pricing.astro index a4af8d8..29edb6e 100644 --- a/src/food-market.public/src/pages/pricing.astro +++ b/src/food-market.public/src/pages/pricing.astro @@ -2,10 +2,15 @@ import BaseLayout from '@/layouts/BaseLayout.astro' import BusinessTariffBuilder from '@/components/BusinessTariffBuilder.tsx' --- - + +
    +
    +

    Прозрачные тарифы Food Market

    +

    Никаких скрытых доплат. CRM, финансы, лояльность — во всех тарифах.

    +

    90 дней бесплатно. Без банковской карты. Отмена в любой момент.

    +
    +
    -

    Тарифы Food Market

    -

    Никаких скрытых доплат. CRM, финансы, лояльность включены во все тарифы.

    @@ -16,8 +21,8 @@ import BusinessTariffBuilder from '@/components/BusinessTariffBuilder.tsx'
  • ✓ 1 магазин · 1 касса · 1 склад
  • ✓ 2 сотрудника
  • ✓ Без лимита товаров
  • -
  • ✓ Касса с весами Масса-К
  • -
  • ✓ Импорт из другие системы
  • +
  • ✓ Касса с поддержкой торговых весов
  • +
  • ✓ Импорт из других систем
  • ✓ Интеграции Kaspi / ОФД
  • — API
  • — SLA