299 lines
9.3 KiB
Markdown
299 lines
9.3 KiB
Markdown
|
|
# 📚 Структура проекта Umbrix VPN (для обучения)
|
|||
|
|
|
|||
|
|
## 🗂️ Основные папки
|
|||
|
|
|
|||
|
|
### `app/` - Страницы и API (Next.js 13 App Router)
|
|||
|
|
Главная папка приложения. Каждая подпапка = страница сайта.
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
app/
|
|||
|
|
├── page.tsx → Главная страница (/)
|
|||
|
|
├── layout.tsx → Общий шаблон для всех страниц (header, footer)
|
|||
|
|
├── globals.css → Глобальные стили CSS
|
|||
|
|
├── favicon.ico → Иконка сайта
|
|||
|
|
│
|
|||
|
|
├── plans/
|
|||
|
|
│ └── page.tsx → Страница тарифов (/plans)
|
|||
|
|
│
|
|||
|
|
├── setup/
|
|||
|
|
│ └── page.tsx → Страница настройки VPN (/setup)
|
|||
|
|
│
|
|||
|
|
├── help/
|
|||
|
|
│ └── page.tsx → Страница помощи (/help)
|
|||
|
|
│
|
|||
|
|
├── subscription/
|
|||
|
|
│ └── [token]/
|
|||
|
|
│ └── page.tsx → Страница подписки (/subscription/abc123)
|
|||
|
|
│ [token] = динамический параметр URL
|
|||
|
|
│
|
|||
|
|
└── api/ → Backend API (серверные функции)
|
|||
|
|
├── create-user/
|
|||
|
|
│ └── route.ts → POST /api/create-user
|
|||
|
|
│ Создает нового пользователя в Marzban
|
|||
|
|
│
|
|||
|
|
├── user-subscription/
|
|||
|
|
│ └── route.ts → GET /api/user-subscription?telegramId=123
|
|||
|
|
│ Получает информацию о подписке
|
|||
|
|
│
|
|||
|
|
└── proxy/
|
|||
|
|
└── [...path]/
|
|||
|
|
└── route.ts → GET /api/proxy/*
|
|||
|
|
Проксирует запросы к Marzban панели
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Как это работает:**
|
|||
|
|
- `page.tsx` = React компонент, который рендерит HTML страницу
|
|||
|
|
- `route.ts` = API endpoint (backend функция)
|
|||
|
|
- `[token]` = динамическая часть URL (можно получить через `params.token`)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### `lib/` - Утилиты (переиспользуемые функции)
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
lib/
|
|||
|
|
├── logger.ts → Логирование (debug, info, warn, error)
|
|||
|
|
│ Автоматически отключает debug в production
|
|||
|
|
│
|
|||
|
|
├── constants.ts → Константы (URL Marzban, подписки)
|
|||
|
|
│ Чтобы не хардкодить URL в разных местах
|
|||
|
|
│
|
|||
|
|
├── telegram-utils.ts → Работа с Telegram WebApp API
|
|||
|
|
│ getTelegramData() - получить данные пользователя
|
|||
|
|
│
|
|||
|
|
└── marzban-api.ts → Функции для работы с Marzban API
|
|||
|
|
(получение пользователей, создание и т.д.)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Зачем это нужно:**
|
|||
|
|
- **Не дублировать код** - одна функция используется везде
|
|||
|
|
- **Легко менять** - изменил в одном месте, работает везде
|
|||
|
|
- **Читабельность** - понятно что делает функция по имени
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### `types/` - TypeScript типы
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
types/
|
|||
|
|
├── marzban.ts → Типы для Marzban API
|
|||
|
|
│ interface MarzbanUser { username, status, expire, ... }
|
|||
|
|
│ interface CreateUserRequest { ... }
|
|||
|
|
│
|
|||
|
|
└── telegram.ts → Типы для Telegram WebApp
|
|||
|
|
interface TelegramUser { id, username, ... }
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Зачем:**
|
|||
|
|
- **Автодополнение** - VS Code подсказывает поля объектов
|
|||
|
|
- **Проверка ошибок** - TypeScript не даст передать неправильные данные
|
|||
|
|
- **Документация** - видно какие поля должны быть в объекте
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### `components/` - React компоненты
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
components/
|
|||
|
|
├── QRCodeModal.tsx → Модальное окно с QR кодом
|
|||
|
|
└── ReferralModal.tsx → Модальное окно с реферальной ссылкой
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Что такое компонент:**
|
|||
|
|
- Переиспользуемая часть UI (кнопка, модалка, форма)
|
|||
|
|
- Можно использовать в разных страницах
|
|||
|
|
- Пример: `<QRCodeModal url="..." />`
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### `hooks/` - React хуки
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
hooks/
|
|||
|
|
└── useTelegramWebApp.ts → Хук для работы с Telegram WebApp API
|
|||
|
|
const { webApp } = useTelegramWebApp()
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Что такое хук:**
|
|||
|
|
- Функция для переиспользования логики
|
|||
|
|
- Начинается с `use`
|
|||
|
|
- Используется внутри компонентов
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### `public/` - Статические файлы
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
public/
|
|||
|
|
├── next.svg → Картинки, доступные по URL
|
|||
|
|
└── vercel.svg → /next.svg → public/next.svg
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📄 Конфигурационные файлы
|
|||
|
|
|
|||
|
|
### `.env.local` - Секретные переменные
|
|||
|
|
```bash
|
|||
|
|
MARZBAN_ADMIN_USERNAME=admin
|
|||
|
|
MARZBAN_ADMIN_PASSWORD=секрет
|
|||
|
|
```
|
|||
|
|
**НЕ КОММИТИТСЯ В GIT!** (в `.gitignore`)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### `package.json` - Зависимости проекта
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"dependencies": {
|
|||
|
|
"next": "13.5.1", // Фреймворк
|
|||
|
|
"react": "18.2.0", // Библиотека UI
|
|||
|
|
"tailwindcss": "3.3.3" // CSS фреймворк
|
|||
|
|
},
|
|||
|
|
"scripts": {
|
|||
|
|
"dev": "next dev", // npm run dev - локальная разработка
|
|||
|
|
"build": "next build", // npm run build - сборка для production
|
|||
|
|
"start": "next start" // npm start - запуск production
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### `tsconfig.json` - Настройки TypeScript
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"compilerOptions": {
|
|||
|
|
"paths": {
|
|||
|
|
"@/*": ["./*"] // Позволяет писать import '@/lib/logger'
|
|||
|
|
} // вместо import '../../lib/logger'
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### `tailwind.config.ts` - Настройки Tailwind CSS
|
|||
|
|
```typescript
|
|||
|
|
module.exports = {
|
|||
|
|
content: ["./app/**/*.{js,ts,jsx,tsx}"], // Где искать классы
|
|||
|
|
theme: {
|
|||
|
|
extend: {
|
|||
|
|
colors: {
|
|||
|
|
primary: "#3b82f6" // Свои цвета
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### `next.config.js` - Настройки Next.js
|
|||
|
|
```javascript
|
|||
|
|
module.exports = {
|
|||
|
|
reactStrictMode: true, // Строгий режим React
|
|||
|
|
images: {
|
|||
|
|
domains: ['example.com'] // Разрешенные домены для картинок
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔄 Как работает проект
|
|||
|
|
|
|||
|
|
### 1. Пользователь открывает сайт
|
|||
|
|
```
|
|||
|
|
app.umbrix.net → app/page.tsx
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. Компонент запрашивает данные Telegram
|
|||
|
|
```typescript
|
|||
|
|
import { getTelegramData } from '@/lib/telegram-utils';
|
|||
|
|
|
|||
|
|
const { telegramId, telegramUsername } = getTelegramData();
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. Делает запрос к API
|
|||
|
|
```typescript
|
|||
|
|
const response = await fetch('/api/user-subscription?telegramId=' + telegramId);
|
|||
|
|
const data = await response.json();
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4. API обращается к Marzban
|
|||
|
|
```typescript
|
|||
|
|
// app/api/user-subscription/route.ts
|
|||
|
|
const marzbanResponse = await fetch('https://panel.umbrix.net/api/users');
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5. Возвращает данные пользователю
|
|||
|
|
```typescript
|
|||
|
|
return NextResponse.json({ success: true, data: userData });
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🎨 Где что менять
|
|||
|
|
|
|||
|
|
### Изменить текст на главной странице
|
|||
|
|
→ `app/page.tsx`
|
|||
|
|
|
|||
|
|
### Добавить новую страницу
|
|||
|
|
→ Создать `app/новая-страница/page.tsx`
|
|||
|
|
|
|||
|
|
### Изменить логику API
|
|||
|
|
→ `app/api/*/route.ts`
|
|||
|
|
|
|||
|
|
### Добавить новую утилиту
|
|||
|
|
→ Создать `lib/моя-утилита.ts`
|
|||
|
|
|
|||
|
|
### Изменить стили
|
|||
|
|
→ `app/globals.css` или Tailwind классы в JSX
|
|||
|
|
|
|||
|
|
### Добавить переменные окружения
|
|||
|
|
→ `.env.local` (не забудь в `.env.example`)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🛠️ Полезные команды
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# Установить зависимости
|
|||
|
|
npm install
|
|||
|
|
|
|||
|
|
# Запустить локально (http://localhost:3000)
|
|||
|
|
npm run dev
|
|||
|
|
|
|||
|
|
# Собрать для production
|
|||
|
|
npm run build
|
|||
|
|
|
|||
|
|
# Запустить production версию
|
|||
|
|
npm start
|
|||
|
|
|
|||
|
|
# Проверить TypeScript ошибки
|
|||
|
|
npx tsc --noEmit
|
|||
|
|
|
|||
|
|
# Проверить Git статус
|
|||
|
|
git status
|
|||
|
|
|
|||
|
|
# Закоммитить изменения
|
|||
|
|
git add .
|
|||
|
|
git commit -m "Описание изменений"
|
|||
|
|
git push
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📖 Полезные ссылки
|
|||
|
|
|
|||
|
|
- **Next.js документация**: https://nextjs.org/docs
|
|||
|
|
- **React документация**: https://react.dev
|
|||
|
|
- **TypeScript**: https://www.typescriptlang.org/docs
|
|||
|
|
- **Tailwind CSS**: https://tailwindcss.com/docs
|
|||
|
|
- **Telegram WebApp**: https://core.telegram.org/bots/webapps
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
**Совет**: Начни с изменения текстов в `app/page.tsx`, потом постепенно переходи к более сложным вещам!
|