feat: add tg api
All checks were successful
Deploy to VPS (dist) / deploy (push) Successful in 1m35s
All checks were successful
Deploy to VPS (dist) / deploy (push) Successful in 1m35s
This commit is contained in:
3
.env.example
Normal file
3
.env.example
Normal file
@@ -0,0 +1,3 @@
|
||||
VITE_API_BASE_URL=http://localhost:5004/api/v1/
|
||||
VITE_APP_URL=http://localhost:5173
|
||||
VITE_APP_NAME=Honey
|
||||
@@ -0,0 +1,3 @@
|
||||
VITE_API_BASE_URL=http://localhost:5004/api/v1/
|
||||
VITE_APP_URL=http://localhost:5173
|
||||
VITE_APP_NAME=Honey
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -25,3 +25,5 @@ dist-ssr
|
||||
|
||||
.vite
|
||||
.tanstack
|
||||
|
||||
.env
|
||||
|
||||
83
README.md
83
README.md
@@ -1 +1,82 @@
|
||||
# TODO: update readme
|
||||
# Honey Frontend
|
||||
|
||||
Telegram mini-app game frontend with a bee/honey theme. Built as a single-page application targeting mobile-first layout.
|
||||
|
||||
## Tech Stack
|
||||
|
||||
- **React 19** + **TypeScript 5.9** (strict mode)
|
||||
- **Vite 7** with SWC (`@vitejs/plugin-react-swc`)
|
||||
- **TanStack Router** (file-based routing, auto code-splitting) + **React Query**
|
||||
- **Tailwind CSS v4** (`@tailwindcss/vite` plugin)
|
||||
- **i18next** + react-i18next (EN, RU — loaded via HTTP backend from `public/locales/`)
|
||||
- **axios** for HTTP requests
|
||||
- **arktype** for runtime validation
|
||||
- **motion** (Framer Motion) for animations
|
||||
- **oxlint** / **oxfmt** for linting and formatting
|
||||
- **pnpm** package manager
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Node.js (see `.nvmrc` for a version) / NVM
|
||||
- pnpm
|
||||
|
||||
### Setup
|
||||
|
||||
```bash
|
||||
nvm use
|
||||
pnpm install
|
||||
cp .env.example .env # fill in required variables
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
| ------------------- | -------------------- |
|
||||
| `VITE_APP_NAME` | Application name |
|
||||
| `VITE_APP_URL` | Application URL |
|
||||
| `VITE_API_BASE_URL` | Backend API base URL |
|
||||
|
||||
## Scripts
|
||||
|
||||
| Command | Description |
|
||||
| -------------------- | -------------------------------- |
|
||||
| `pnpm dev` | Start dev server |
|
||||
| `pnpm build` | Typecheck + production build |
|
||||
| `pnpm build:staging` | Typecheck + staging build |
|
||||
| `pnpm lint` | Run oxlint |
|
||||
| `pnpm lint:fix` | Run oxlint with auto-fix |
|
||||
| `pnpm fmt` | Format code with oxfmt |
|
||||
| `pnpm fmt:check` | Check formatting without writing |
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
src/
|
||||
api/ — Axios instance and API utilities
|
||||
components/
|
||||
atoms/ — Generic reusable components
|
||||
form/ — Components for user inputs
|
||||
icons/ — SVG icon components
|
||||
modals/ — Application modals with shared interface
|
||||
surface/ — Themed containers
|
||||
i18n/ — i18n runtime setup
|
||||
routes/ — TanStack file-based routes
|
||||
styles/ — Global CSS, fonts
|
||||
main.tsx — App entry point
|
||||
public/
|
||||
locales/ — Translation JSON files
|
||||
plugins/ — Custom Vite plugins
|
||||
dynamic-json.ts — JSON templating with env var interpolation
|
||||
```
|
||||
|
||||
### Path Aliases
|
||||
|
||||
- `@/*` → `src/*`
|
||||
- `@components/*` → `src/components/*`
|
||||
|
||||
## Pre-commit Hooks
|
||||
|
||||
Husky + lint-staged run `oxfmt` and `oxlint` on staged files before each commit.
|
||||
|
||||
@@ -21,7 +21,9 @@
|
||||
"@tanstack/react-query-devtools": "^5.91.3",
|
||||
"@tanstack/react-router": "^1.166.3",
|
||||
"@tanstack/react-router-devtools": "^1.166.3",
|
||||
"@telegram-apps/sdk-react": "^3.3.9",
|
||||
"arktype": "^2.2.0",
|
||||
"axios": "^1.13.6",
|
||||
"clsx": "^2.1.1",
|
||||
"i18next": "^25.8.17",
|
||||
"i18next-http-backend": "^3.0.2",
|
||||
@@ -43,6 +45,7 @@
|
||||
"lint-staged": "^16.3.2",
|
||||
"oxfmt": "^0.36.0",
|
||||
"oxlint": "^1.51.0",
|
||||
"rollup": "^4.59.0",
|
||||
"typescript": "~5.9.3",
|
||||
"vite": "^7.3.1"
|
||||
},
|
||||
|
||||
322
pnpm-lock.yaml
generated
322
pnpm-lock.yaml
generated
@@ -29,9 +29,15 @@ importers:
|
||||
'@tanstack/react-router-devtools':
|
||||
specifier: ^1.166.3
|
||||
version: 1.166.3(@tanstack/react-router@1.166.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(@tanstack/router-core@1.166.2)(csstype@3.2.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||
'@telegram-apps/sdk-react':
|
||||
specifier: ^3.3.9
|
||||
version: 3.3.9(@types/react@19.2.14)(react@19.2.4)(typescript@5.9.3)
|
||||
arktype:
|
||||
specifier: ^2.2.0
|
||||
version: 2.2.0
|
||||
axios:
|
||||
specifier: ^1.13.6
|
||||
version: 1.13.6
|
||||
clsx:
|
||||
specifier: ^2.1.1
|
||||
version: 2.1.1
|
||||
@@ -90,6 +96,9 @@ importers:
|
||||
oxlint:
|
||||
specifier: ^1.51.0
|
||||
version: 1.51.0
|
||||
rollup:
|
||||
specifier: ^4.59.0
|
||||
version: 4.59.0
|
||||
typescript:
|
||||
specifier: ~5.9.3
|
||||
version: 5.9.3
|
||||
@@ -1183,6 +1192,39 @@ packages:
|
||||
resolution: {integrity: sha512-42WoRePf8v690qG8yGRe/YOh+oHni9vUaUUfoqlS91U2scd3a5rkLtVsc6b7z60w3RogH0I00vdrC5AaeiZ18w==}
|
||||
engines: {node: '>=20.19'}
|
||||
|
||||
'@telegram-apps/bridge@2.11.0':
|
||||
resolution: {integrity: sha512-kBZjWRRp/lxKeQ8r8cDWUY9EjxUtyeh/9xTQjsjuGRsCR5XTO1cyVbvcvqzHn53csGx3aBs+fOR3Pk3b6w2JHg==}
|
||||
deprecated: This package is not supported anymore. Use @tma.js/bridge instead
|
||||
|
||||
'@telegram-apps/navigation@1.0.14':
|
||||
resolution: {integrity: sha512-bqNgF/J8Po7ZtsELm3E1a6aPr7awwxO3sIqD8J6u12urOlGoW5+1KxKKbkPa58mgXuQdsltd8apI+OVy0IYiUA==}
|
||||
|
||||
'@telegram-apps/sdk-react@3.3.9':
|
||||
resolution: {integrity: sha512-85jF1ICT8sYCNzXu19SqJrfrS8XslsvV14KUcToiyL7H5ZMXHt0JQKM+QJgULjnLjEswweQ4/7Bd7mNULf/BIg==}
|
||||
peerDependencies:
|
||||
'@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
react: ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
|
||||
'@telegram-apps/sdk@3.11.8':
|
||||
resolution: {integrity: sha512-vlpkYzMJCV9Cadsn9Q+/hbHNR39j5o96N9z4CjZ6AFHkkxOeOqVRrq9zRBw0gmffROkF2bU0WQxhRj8KZ/bPhw==}
|
||||
|
||||
'@telegram-apps/signals@1.1.2':
|
||||
resolution: {integrity: sha512-1P1kdCLX7MfETGPxH7f3UZKIsdE7Tz5S7QmN4Km1sbYQMakD5Bi1NecSMR7/wnHp50gWMI1JzENcMtCEmouhSg==}
|
||||
|
||||
'@telegram-apps/toolkit@2.1.3':
|
||||
resolution: {integrity: sha512-LPUBL7hxQTOr+Dowyk9a1O82nQS4ja4+OYiYWtvqq5nNUHC6Gbbus0zGWCbFcj9CLnIzaeb5HWOg5iSnhoRcyg==}
|
||||
|
||||
'@telegram-apps/transformers@2.2.6':
|
||||
resolution: {integrity: sha512-MMBRs3demeBT9Cd614KKZmak7eEyNdEbfu99a0SwEEJe2oIODjJLrUxrhUcAOc5wvTRfrKka27VXVgruauLhdg==}
|
||||
deprecated: This package is not supported anymore. Use @tma.js/transfomers instead
|
||||
|
||||
'@telegram-apps/types@2.0.3':
|
||||
resolution: {integrity: sha512-pXh9BdnLZF3e2BGc4WL+RTRMAUpqKpaSP3Rs8rB4WyRwIoRSGWFKE4gtT/9m42LGixB8YVwdo/pJ+9XO765XEA==}
|
||||
deprecated: This package is not supported anymore. Use @tma.js/types instead
|
||||
|
||||
'@traversable/json@0.0.26':
|
||||
resolution: {integrity: sha512-oXKX0eNxbbHGLjLV27nTuV0uyR6uSoWi0BF+FYJu4jXRcSsWqCHOqNjIb2x/0usKd70rnKLGyHxurlTBTpQVOw==}
|
||||
peerDependencies:
|
||||
@@ -1253,6 +1295,12 @@ packages:
|
||||
resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
asynckit@0.4.0:
|
||||
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
||||
|
||||
axios@1.13.6:
|
||||
resolution: {integrity: sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==}
|
||||
|
||||
babel-dead-code-elimination@1.0.12:
|
||||
resolution: {integrity: sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig==}
|
||||
|
||||
@@ -1261,6 +1309,9 @@ packages:
|
||||
engines: {node: '>=6.0.0'}
|
||||
hasBin: true
|
||||
|
||||
better-promises@0.4.1:
|
||||
resolution: {integrity: sha512-cDW7eMvhvCoWzSih5o/OxsAgTUfP05yGMq77xNZUTmcZoNU9vEeFZJ+yJJi4lnocvxFrVFKsG0Yxt7ZnuYJEig==}
|
||||
|
||||
binary-extensions@2.3.0:
|
||||
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -1274,6 +1325,10 @@ packages:
|
||||
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
|
||||
hasBin: true
|
||||
|
||||
call-bind-apply-helpers@1.0.2:
|
||||
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
caniuse-lite@1.0.30001777:
|
||||
resolution: {integrity: sha512-tmN+fJxroPndC74efCdp12j+0rk0RHwV5Jwa1zWaFVyw2ZxAuPeG8ZgWC3Wz7uSjT3qMRQ5XHZ4COgQmsCMJAQ==}
|
||||
|
||||
@@ -1307,6 +1362,10 @@ packages:
|
||||
colorjs.io@0.5.2:
|
||||
resolution: {integrity: sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw==}
|
||||
|
||||
combined-stream@1.0.8:
|
||||
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
commander@14.0.3:
|
||||
resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==}
|
||||
engines: {node: '>=20'}
|
||||
@@ -1335,6 +1394,10 @@ packages:
|
||||
supports-color:
|
||||
optional: true
|
||||
|
||||
delayed-stream@1.0.0:
|
||||
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
|
||||
detect-libc@2.1.2:
|
||||
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -1343,6 +1406,10 @@ packages:
|
||||
resolution: {integrity: sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==}
|
||||
engines: {node: '>=0.3.1'}
|
||||
|
||||
dunder-proto@1.0.1:
|
||||
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
electron-to-chromium@1.5.307:
|
||||
resolution: {integrity: sha512-5z3uFKBWjiNR44nFcYdkcXjKMbg5KXNdciu7mhTPo9tB7NbqSNP2sSnGR+fqknZSCwKkBN+oxiiajWs4dT6ORg==}
|
||||
|
||||
@@ -1357,6 +1424,25 @@ packages:
|
||||
resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
error-kid@0.0.7:
|
||||
resolution: {integrity: sha512-8mFs7ZaDWlBFgjOy4lHLMCe2+KZfZXGx5GOgh2VQ/M1CCIvSWzbl2OMl+5fdZgrgoUfhTeF+NPhmqfEvUhN8yw==}
|
||||
|
||||
es-define-property@1.0.1:
|
||||
resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
es-errors@1.3.0:
|
||||
resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
es-object-atoms@1.1.1:
|
||||
resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
es-set-tostringtag@2.1.0:
|
||||
resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
esbuild@0.27.3:
|
||||
resolution: {integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==}
|
||||
engines: {node: '>=18'}
|
||||
@@ -1387,6 +1473,19 @@ packages:
|
||||
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
follow-redirects@1.15.11:
|
||||
resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==}
|
||||
engines: {node: '>=4.0'}
|
||||
peerDependencies:
|
||||
debug: '*'
|
||||
peerDependenciesMeta:
|
||||
debug:
|
||||
optional: true
|
||||
|
||||
form-data@4.0.5:
|
||||
resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
framer-motion@12.35.1:
|
||||
resolution: {integrity: sha512-rL8cLrjYZNShZqKV3U0Qj6Y5WDiZXYEM5giiTLfEqsIZxtspzMDCkKmrO5po76jWfvOg04+Vk+sfBvTD0iMmLw==}
|
||||
peerDependencies:
|
||||
@@ -1406,6 +1505,9 @@ packages:
|
||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||
os: [darwin]
|
||||
|
||||
function-bind@1.1.2:
|
||||
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
|
||||
|
||||
gensync@1.0.0-beta.2:
|
||||
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
@@ -1414,6 +1516,14 @@ packages:
|
||||
resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
get-intrinsic@1.3.0:
|
||||
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
get-proto@1.0.1:
|
||||
resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
get-tsconfig@4.13.6:
|
||||
resolution: {integrity: sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==}
|
||||
|
||||
@@ -1430,6 +1540,10 @@ packages:
|
||||
peerDependencies:
|
||||
csstype: ^3.0.10
|
||||
|
||||
gopd@1.2.0:
|
||||
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
graceful-fs@4.2.11:
|
||||
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
|
||||
|
||||
@@ -1437,6 +1551,18 @@ packages:
|
||||
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
has-symbols@1.1.0:
|
||||
resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
has-tostringtag@1.0.2:
|
||||
resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
hasown@2.0.2:
|
||||
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
html-parse-stringify@3.0.1:
|
||||
resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==}
|
||||
|
||||
@@ -1600,14 +1726,29 @@ packages:
|
||||
magic-string@0.30.21:
|
||||
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
|
||||
|
||||
math-intrinsics@1.1.0:
|
||||
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
micromatch@4.0.8:
|
||||
resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
|
||||
engines: {node: '>=8.6'}
|
||||
|
||||
mime-db@1.52.0:
|
||||
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
mime-types@2.1.35:
|
||||
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
mimic-function@5.0.1:
|
||||
resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
mitt@3.0.1:
|
||||
resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==}
|
||||
|
||||
motion-dom@12.35.1:
|
||||
resolution: {integrity: sha512-7n6r7TtNOsH2UFSAXzTkfzOeO5616v9B178qBIjmu/WgEyJK0uqwytCEhwKBTuM/HJA40ptAw7hLFpxtPAMRZQ==}
|
||||
|
||||
@@ -1697,6 +1838,9 @@ packages:
|
||||
engines: {node: '>=14'}
|
||||
hasBin: true
|
||||
|
||||
proxy-from-env@1.1.0:
|
||||
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
||||
|
||||
react-dom@19.2.4:
|
||||
resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==}
|
||||
peerDependencies:
|
||||
@@ -2013,6 +2157,22 @@ packages:
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
|
||||
valibot@1.0.0:
|
||||
resolution: {integrity: sha512-1Hc0ihzWxBar6NGeZv7fPLY0QuxFMyxwYR2sF1Blu7Wq7EnremwY2W02tit2ij2VJT8HcSkHAQqmFfl77f73Yw==}
|
||||
peerDependencies:
|
||||
typescript: '>=5'
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
valibot@1.0.0-beta.14:
|
||||
resolution: {integrity: sha512-tLyV2rE5QL6U29MFy3xt4AqMrn+/HErcp2ZThASnQvPMwfSozjV1uBGKIGiegtZIGjinJqn0SlBdannf18wENA==}
|
||||
peerDependencies:
|
||||
typescript: '>=5'
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
varint@6.0.0:
|
||||
resolution: {integrity: sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==}
|
||||
|
||||
@@ -2919,6 +3079,58 @@ snapshots:
|
||||
|
||||
'@tanstack/virtual-file-routes@1.161.4': {}
|
||||
|
||||
'@telegram-apps/bridge@2.11.0(typescript@5.9.3)':
|
||||
dependencies:
|
||||
'@telegram-apps/signals': 1.1.2
|
||||
'@telegram-apps/toolkit': 2.1.3
|
||||
'@telegram-apps/transformers': 2.2.6(typescript@5.9.3)
|
||||
'@telegram-apps/types': 2.0.3
|
||||
better-promises: 0.4.1
|
||||
error-kid: 0.0.7
|
||||
mitt: 3.0.1
|
||||
valibot: 1.0.0(typescript@5.9.3)
|
||||
transitivePeerDependencies:
|
||||
- typescript
|
||||
|
||||
'@telegram-apps/navigation@1.0.14': {}
|
||||
|
||||
'@telegram-apps/sdk-react@3.3.9(@types/react@19.2.14)(react@19.2.4)(typescript@5.9.3)':
|
||||
dependencies:
|
||||
'@telegram-apps/sdk': 3.11.8(typescript@5.9.3)
|
||||
react: 19.2.4
|
||||
optionalDependencies:
|
||||
'@types/react': 19.2.14
|
||||
transitivePeerDependencies:
|
||||
- typescript
|
||||
|
||||
'@telegram-apps/sdk@3.11.8(typescript@5.9.3)':
|
||||
dependencies:
|
||||
'@telegram-apps/bridge': 2.11.0(typescript@5.9.3)
|
||||
'@telegram-apps/navigation': 1.0.14
|
||||
'@telegram-apps/signals': 1.1.2
|
||||
'@telegram-apps/toolkit': 2.1.3
|
||||
'@telegram-apps/transformers': 2.2.6(typescript@5.9.3)
|
||||
'@telegram-apps/types': 2.0.3
|
||||
better-promises: 0.4.1
|
||||
error-kid: 0.0.7
|
||||
valibot: 1.0.0(typescript@5.9.3)
|
||||
transitivePeerDependencies:
|
||||
- typescript
|
||||
|
||||
'@telegram-apps/signals@1.1.2': {}
|
||||
|
||||
'@telegram-apps/toolkit@2.1.3': {}
|
||||
|
||||
'@telegram-apps/transformers@2.2.6(typescript@5.9.3)':
|
||||
dependencies:
|
||||
'@telegram-apps/toolkit': 2.1.3
|
||||
'@telegram-apps/types': 2.0.3
|
||||
valibot: 1.0.0-beta.14(typescript@5.9.3)
|
||||
transitivePeerDependencies:
|
||||
- typescript
|
||||
|
||||
'@telegram-apps/types@2.0.3': {}
|
||||
|
||||
'@traversable/json@0.0.26(@traversable/registry@0.0.25)':
|
||||
dependencies:
|
||||
'@traversable/registry': 0.0.25
|
||||
@@ -2980,6 +3192,16 @@ snapshots:
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
|
||||
asynckit@0.4.0: {}
|
||||
|
||||
axios@1.13.6:
|
||||
dependencies:
|
||||
follow-redirects: 1.15.11
|
||||
form-data: 4.0.5
|
||||
proxy-from-env: 1.1.0
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
|
||||
babel-dead-code-elimination@1.0.12:
|
||||
dependencies:
|
||||
'@babel/core': 7.29.0
|
||||
@@ -2991,6 +3213,10 @@ snapshots:
|
||||
|
||||
baseline-browser-mapping@2.10.0: {}
|
||||
|
||||
better-promises@0.4.1:
|
||||
dependencies:
|
||||
error-kid: 0.0.7
|
||||
|
||||
binary-extensions@2.3.0: {}
|
||||
|
||||
braces@3.0.3:
|
||||
@@ -3005,6 +3231,11 @@ snapshots:
|
||||
node-releases: 2.0.36
|
||||
update-browserslist-db: 1.2.3(browserslist@4.28.1)
|
||||
|
||||
call-bind-apply-helpers@1.0.2:
|
||||
dependencies:
|
||||
es-errors: 1.3.0
|
||||
function-bind: 1.1.2
|
||||
|
||||
caniuse-lite@1.0.30001777: {}
|
||||
|
||||
chalk@5.6.2: {}
|
||||
@@ -3042,6 +3273,10 @@ snapshots:
|
||||
colorjs.io@0.5.2:
|
||||
optional: true
|
||||
|
||||
combined-stream@1.0.8:
|
||||
dependencies:
|
||||
delayed-stream: 1.0.0
|
||||
|
||||
commander@14.0.3: {}
|
||||
|
||||
convert-source-map@2.0.0: {}
|
||||
@@ -3062,10 +3297,18 @@ snapshots:
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
|
||||
delayed-stream@1.0.0: {}
|
||||
|
||||
detect-libc@2.1.2: {}
|
||||
|
||||
diff@8.0.3: {}
|
||||
|
||||
dunder-proto@1.0.1:
|
||||
dependencies:
|
||||
call-bind-apply-helpers: 1.0.2
|
||||
es-errors: 1.3.0
|
||||
gopd: 1.2.0
|
||||
|
||||
electron-to-chromium@1.5.307: {}
|
||||
|
||||
emoji-regex@10.6.0: {}
|
||||
@@ -3077,6 +3320,23 @@ snapshots:
|
||||
|
||||
environment@1.1.0: {}
|
||||
|
||||
error-kid@0.0.7: {}
|
||||
|
||||
es-define-property@1.0.1: {}
|
||||
|
||||
es-errors@1.3.0: {}
|
||||
|
||||
es-object-atoms@1.1.1:
|
||||
dependencies:
|
||||
es-errors: 1.3.0
|
||||
|
||||
es-set-tostringtag@2.1.0:
|
||||
dependencies:
|
||||
es-errors: 1.3.0
|
||||
get-intrinsic: 1.3.0
|
||||
has-tostringtag: 1.0.2
|
||||
hasown: 2.0.2
|
||||
|
||||
esbuild@0.27.3:
|
||||
optionalDependencies:
|
||||
'@esbuild/aix-ppc64': 0.27.3
|
||||
@@ -3120,6 +3380,16 @@ snapshots:
|
||||
dependencies:
|
||||
to-regex-range: 5.0.1
|
||||
|
||||
follow-redirects@1.15.11: {}
|
||||
|
||||
form-data@4.0.5:
|
||||
dependencies:
|
||||
asynckit: 0.4.0
|
||||
combined-stream: 1.0.8
|
||||
es-set-tostringtag: 2.1.0
|
||||
hasown: 2.0.2
|
||||
mime-types: 2.1.35
|
||||
|
||||
framer-motion@12.35.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
|
||||
dependencies:
|
||||
motion-dom: 12.35.1
|
||||
@@ -3132,10 +3402,30 @@ snapshots:
|
||||
fsevents@2.3.3:
|
||||
optional: true
|
||||
|
||||
function-bind@1.1.2: {}
|
||||
|
||||
gensync@1.0.0-beta.2: {}
|
||||
|
||||
get-east-asian-width@1.5.0: {}
|
||||
|
||||
get-intrinsic@1.3.0:
|
||||
dependencies:
|
||||
call-bind-apply-helpers: 1.0.2
|
||||
es-define-property: 1.0.1
|
||||
es-errors: 1.3.0
|
||||
es-object-atoms: 1.1.1
|
||||
function-bind: 1.1.2
|
||||
get-proto: 1.0.1
|
||||
gopd: 1.2.0
|
||||
has-symbols: 1.1.0
|
||||
hasown: 2.0.2
|
||||
math-intrinsics: 1.1.0
|
||||
|
||||
get-proto@1.0.1:
|
||||
dependencies:
|
||||
dunder-proto: 1.0.1
|
||||
es-object-atoms: 1.1.1
|
||||
|
||||
get-tsconfig@4.13.6:
|
||||
dependencies:
|
||||
resolve-pkg-maps: 1.0.0
|
||||
@@ -3150,11 +3440,23 @@ snapshots:
|
||||
dependencies:
|
||||
csstype: 3.2.3
|
||||
|
||||
gopd@1.2.0: {}
|
||||
|
||||
graceful-fs@4.2.11: {}
|
||||
|
||||
has-flag@4.0.0:
|
||||
optional: true
|
||||
|
||||
has-symbols@1.1.0: {}
|
||||
|
||||
has-tostringtag@1.0.2:
|
||||
dependencies:
|
||||
has-symbols: 1.1.0
|
||||
|
||||
hasown@2.0.2:
|
||||
dependencies:
|
||||
function-bind: 1.1.2
|
||||
|
||||
html-parse-stringify@3.0.1:
|
||||
dependencies:
|
||||
void-elements: 3.1.0
|
||||
@@ -3294,13 +3596,23 @@ snapshots:
|
||||
dependencies:
|
||||
'@jridgewell/sourcemap-codec': 1.5.5
|
||||
|
||||
math-intrinsics@1.1.0: {}
|
||||
|
||||
micromatch@4.0.8:
|
||||
dependencies:
|
||||
braces: 3.0.3
|
||||
picomatch: 2.3.1
|
||||
|
||||
mime-db@1.52.0: {}
|
||||
|
||||
mime-types@2.1.35:
|
||||
dependencies:
|
||||
mime-db: 1.52.0
|
||||
|
||||
mimic-function@5.0.1: {}
|
||||
|
||||
mitt@3.0.1: {}
|
||||
|
||||
motion-dom@12.35.1:
|
||||
dependencies:
|
||||
motion-utils: 12.29.2
|
||||
@@ -3396,6 +3708,8 @@ snapshots:
|
||||
|
||||
prettier@3.8.1: {}
|
||||
|
||||
proxy-from-env@1.1.0: {}
|
||||
|
||||
react-dom@19.2.4(react@19.2.4):
|
||||
dependencies:
|
||||
react: 19.2.4
|
||||
@@ -3690,6 +4004,14 @@ snapshots:
|
||||
dependencies:
|
||||
react: 19.2.4
|
||||
|
||||
valibot@1.0.0(typescript@5.9.3):
|
||||
optionalDependencies:
|
||||
typescript: 5.9.3
|
||||
|
||||
valibot@1.0.0-beta.14(typescript@5.9.3):
|
||||
optionalDependencies:
|
||||
typescript: 5.9.3
|
||||
|
||||
varint@6.0.0:
|
||||
optional: true
|
||||
|
||||
|
||||
18
src/api/api.ts
Normal file
18
src/api/api.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import axios from "axios";
|
||||
import tg, { STORAGE_KEYS } from "@/tg";
|
||||
|
||||
const api = axios.create({
|
||||
baseURL: import.meta.env.VITE_API_BASE_URL,
|
||||
headers: {
|
||||
...(import.meta.env.DEV && {
|
||||
"ngrok-skip-browser-warning": "true",
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
api.interceptors.request.use(async (config) => {
|
||||
config.headers.Authorization = `Bearer ${await tg.storage.getItem(STORAGE_KEYS.authToken)}`;
|
||||
return config;
|
||||
});
|
||||
|
||||
export default api;
|
||||
1
src/api/index.ts
Normal file
1
src/api/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { default as api } from "./api";
|
||||
@@ -1,6 +1,8 @@
|
||||
import { motion, type HTMLMotionProps } from "motion/react";
|
||||
import clsx, { type ClassValue } from "clsx";
|
||||
|
||||
import tg from "@/tg";
|
||||
|
||||
import classes from "./Button.module.css";
|
||||
|
||||
type Props = Omit<HTMLMotionProps<"button">, "className"> & {
|
||||
@@ -15,10 +17,14 @@ const VARIANTS_MAP = {
|
||||
yellow: classes.yellowButton,
|
||||
} satisfies Record<Exclude<Props["variant"], undefined>, string>;
|
||||
|
||||
export default function Button({ className, variant = "blue", ...props }: Props) {
|
||||
export default function Button({ className, variant = "blue", onClick, ...props }: Props) {
|
||||
return (
|
||||
<motion.button
|
||||
{...props}
|
||||
onClick={(e) => {
|
||||
tg.hapticFeedback.click();
|
||||
onClick?.(e);
|
||||
}}
|
||||
initial={{ scale: 0.5 }}
|
||||
animate={{ scale: 1 }}
|
||||
whileTap={{ scale: 0.95 }}
|
||||
|
||||
2
src/i18next.d.ts → src/i18n/index.d.ts
vendored
2
src/i18next.d.ts → src/i18n/index.d.ts
vendored
@@ -1,6 +1,6 @@
|
||||
import "i18next";
|
||||
|
||||
import type { resources } from "../public/locales/en.d.ts";
|
||||
import type { resources } from "../../public/locales/en.d.ts";
|
||||
|
||||
declare module "i18next" {
|
||||
interface CustomTypeOptions {
|
||||
31
src/i18n/index.ts
Normal file
31
src/i18n/index.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import i18next from "i18next";
|
||||
import Backend, { type HttpBackendOptions } from "i18next-http-backend";
|
||||
import { initReactI18next } from "react-i18next";
|
||||
|
||||
declare const __LANGS__: string[];
|
||||
declare const __LOCALES_PATH__: string;
|
||||
declare const __DEFAULT_LANG__: string;
|
||||
|
||||
export const languages = __LANGS__.map((key) => ({
|
||||
key,
|
||||
label: key.toUpperCase(),
|
||||
}));
|
||||
|
||||
export default {
|
||||
init() {
|
||||
i18next
|
||||
.use(Backend)
|
||||
.use(initReactI18next)
|
||||
.init<HttpBackendOptions>({
|
||||
backend: {
|
||||
loadPath: `/${__LOCALES_PATH__}/{{lng}}.json`,
|
||||
},
|
||||
fallbackLng: __DEFAULT_LANG__,
|
||||
supportedLngs: __LANGS__,
|
||||
debug: import.meta.env.DEV,
|
||||
interpolation: {
|
||||
escapeValue: false,
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
@@ -1,27 +0,0 @@
|
||||
import i18next from "i18next";
|
||||
import Backend, { type HttpBackendOptions } from "i18next-http-backend";
|
||||
import { initReactI18next } from "react-i18next";
|
||||
|
||||
declare const __LANGS__: string[];
|
||||
declare const __LOCALES_PATH__: string;
|
||||
declare const __DEFAULT_LANG__: string;
|
||||
|
||||
export const languages = __LANGS__.map((key) => ({
|
||||
key,
|
||||
label: key.toUpperCase(),
|
||||
}));
|
||||
|
||||
i18next
|
||||
.use(Backend)
|
||||
.use(initReactI18next)
|
||||
.init<HttpBackendOptions>({
|
||||
backend: {
|
||||
loadPath: `/${__LOCALES_PATH__}/{{lng}}.json`,
|
||||
},
|
||||
fallbackLng: __DEFAULT_LANG__,
|
||||
supportedLngs: __LANGS__,
|
||||
debug: import.meta.env.DEV,
|
||||
interpolation: {
|
||||
escapeValue: false,
|
||||
},
|
||||
});
|
||||
@@ -3,9 +3,11 @@ import ReactDOM from "react-dom/client";
|
||||
import { RouterProvider, createRouter } from "@tanstack/react-router";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
|
||||
import "./styles/index.css";
|
||||
import i18n from "@/i18n";
|
||||
import tg from "@/tg";
|
||||
import { routeTree } from "./routeTree.gen";
|
||||
import "./i18next";
|
||||
|
||||
import "./styles/index.css";
|
||||
|
||||
const router = createRouter({ routeTree });
|
||||
|
||||
@@ -16,6 +18,9 @@ declare module "@tanstack/react-router" {
|
||||
}
|
||||
}
|
||||
|
||||
tg.init();
|
||||
i18n.init();
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root")!).render(
|
||||
<StrictMode>
|
||||
<QueryClientProvider client={new QueryClient()}>
|
||||
|
||||
@@ -15,7 +15,7 @@ import SwitchInput from "@components/form/SwitchInput";
|
||||
import TextInput from "@components/form/TextInput";
|
||||
import NumberInput from "@components/form/NumberInput";
|
||||
import TextAreaInput from "@components/form/TextAreaInput";
|
||||
import ActionModal from "@components/modal/ActionModal";
|
||||
import ActionModal from "@components/modals/ActionModal";
|
||||
|
||||
const TABS = [
|
||||
{ key: "tab1", title: "Tab 1" },
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@font-face {
|
||||
font-family: "BalsamiqSans";
|
||||
src: url("/fonts/BalsamicSans/BalsamiqSans-Regular.ttf") format("truetype");
|
||||
src: url("./BalsamiqSans-Regular.ttf") format("truetype");
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
@font-face {
|
||||
font-family: "BalsamiqSans";
|
||||
src: url("/fonts/BalsamicSans/BalsamiqSans-Italic.ttf") format("truetype");
|
||||
src: url("./BalsamiqSans-Italic.ttf") format("truetype");
|
||||
font-weight: 400;
|
||||
font-style: italic;
|
||||
font-display: swap;
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
@font-face {
|
||||
font-family: "BalsamiqSans";
|
||||
src: url("/fonts/BalsamicSans/BalsamiqSans-Bold.ttf") format("truetype");
|
||||
src: url("./BalsamiqSans-Bold.ttf") format("truetype");
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
@font-face {
|
||||
font-family: "BalsamiqSans";
|
||||
src: url("/fonts/BalsamicSans/BalsamiqSans-BoldItalic.ttf") format("truetype");
|
||||
src: url("./BalsamiqSans-BoldItalic.ttf") format("truetype");
|
||||
font-weight: 700;
|
||||
font-style: italic;
|
||||
font-display: swap;
|
||||
@@ -1,6 +1,6 @@
|
||||
@import "tailwindcss";
|
||||
|
||||
@import "./fonts/BalsamiqSans.css";
|
||||
@import "./fonts/BalsamiqSans";
|
||||
|
||||
@theme {
|
||||
}
|
||||
|
||||
52
src/tg/index.ts
Normal file
52
src/tg/index.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import * as tg from "@telegram-apps/sdk-react";
|
||||
|
||||
export const STORAGE_KEYS = {
|
||||
authToken: "authToken",
|
||||
} as const;
|
||||
export type StorageKey = (typeof STORAGE_KEYS)[keyof typeof STORAGE_KEYS];
|
||||
|
||||
export default {
|
||||
init: () => {
|
||||
try {
|
||||
tg.setDebug(import.meta.env.DEV);
|
||||
tg.init({ acceptCustomStyles: true });
|
||||
tg.requestFullscreen();
|
||||
tg.disableVerticalSwipes();
|
||||
tg.expandViewport();
|
||||
tg.setMiniAppHeaderColor("#000000");
|
||||
} catch {
|
||||
console.warn("Telegram SDK not available in browser.");
|
||||
}
|
||||
},
|
||||
openLink(url: string | URL, options?: tg.OpenLinkOptions) {
|
||||
tg.openLink.ifAvailable(url, options);
|
||||
},
|
||||
hapticFeedback: {
|
||||
click() {
|
||||
tg.hapticFeedback.impactOccurred.ifAvailable("light");
|
||||
},
|
||||
},
|
||||
initData: tg.initData,
|
||||
storage: {
|
||||
clear() {
|
||||
localStorage.clear();
|
||||
tg.cloudStorage.clear.ifAvailable();
|
||||
},
|
||||
getItem(key: StorageKey, options?: tg.InvokeCustomMethodOptions) {
|
||||
return tg.cloudStorage
|
||||
.getItem(key, options)
|
||||
.catch(
|
||||
() =>
|
||||
localStorage.getItem(key) ?? tg.AbortablePromise.reject(new Error("Item not found")),
|
||||
);
|
||||
},
|
||||
setItem(key: StorageKey, value: string, options?: tg.InvokeCustomMethodOptions) {
|
||||
localStorage.setItem(key, value);
|
||||
tg.cloudStorage.setItem.ifAvailable(key, value, options);
|
||||
},
|
||||
deleteItem(key: StorageKey, options?: tg.InvokeCustomMethodOptions) {
|
||||
tg.cloudStorage.deleteItem.ifAvailable(key, options);
|
||||
localStorage.removeItem(key);
|
||||
},
|
||||
},
|
||||
};
|
||||
3
src/vite-env.d.ts
vendored
3
src/vite-env.d.ts
vendored
@@ -4,6 +4,9 @@ interface ViteTypeOptions {
|
||||
|
||||
interface ImportMetaEnv {
|
||||
MODE: "development" | "production" | "staging";
|
||||
VITE_APP_NAME: string;
|
||||
VITE_APP_URL: string;
|
||||
VITE_API_BASE_URL: string;
|
||||
}
|
||||
|
||||
interface ImportMeta {
|
||||
|
||||
@@ -21,5 +21,5 @@
|
||||
"erasableSyntaxOnly": true,
|
||||
"noUncheckedSideEffectImports": true
|
||||
},
|
||||
"include": ["vite.config.ts"]
|
||||
"include": ["vite.config.ts", "plugins/**/*.ts"]
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import path from "node:path";
|
||||
|
||||
import { defineConfig } from "vite";
|
||||
import react from "@vitejs/plugin-react-swc";
|
||||
import tailwindcss from "@tailwindcss/vite";
|
||||
@@ -9,7 +11,6 @@ import i18nextConfig, {
|
||||
LOCALES_PATH,
|
||||
LOCAL_LOCALES_PATH,
|
||||
} from "./i18next.config";
|
||||
import path from "node:path";
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
|
||||
Reference in New Issue
Block a user