Fix clipboard copy on HTTP (non-secure) contexts, update docs

navigator.clipboard is undefined on non-HTTPS origins — add
execCommand fallback. Also sync CLAUDE.md with actual project
structure (Dockerfiles, nginx, CI, correct API/button descriptions).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mikhail Kilin
2026-03-18 00:09:54 +03:00
parent b2c799f429
commit 7467206a5c
2 changed files with 19 additions and 4 deletions

View File

@@ -20,13 +20,17 @@ blood-brain-barrier/
│ │ ├── App.tsx # Основной компонент: textarea + список записей │ │ ├── App.tsx # Основной компонент: textarea + список записей
│ │ ├── api.ts # Функции для запросов к API │ │ ├── api.ts # Функции для запросов к API
│ │ └── main.tsx │ │ └── main.tsx
│ ├── Dockerfile # Сборка фронтенда + nginx
│ ├── nginx.conf # Конфиг nginx для раздачи SPA и проксирования API
│ └── package.json │ └── package.json
├── backend/ # Rust API (Axum) ├── backend/ # Rust API (Axum)
│ ├── src/ │ ├── src/
│ │ ├── main.rs # Точка входа, подключение к БД, CORS, запуск сервера │ │ ├── main.rs # Точка входа, подключение к БД, CORS, запуск сервера
│ │ ├── db.rs # Подключение к PostgreSQL, init_db │ │ ├── db.rs # Подключение к PostgreSQL, init_db
│ │ └── routes.rs # Хендлеры API │ │ └── routes.rs # Хендлеры API
│ ├── Dockerfile # Сборка бэкенда
│ └── Cargo.toml │ └── Cargo.toml
├── .woodpecker.yml # CI pipeline
├── docker-compose.yml # PostgreSQL ├── docker-compose.yml # PostgreSQL
└── CLAUDE.md └── CLAUDE.md
``` ```
@@ -47,15 +51,15 @@ CREATE TABLE entries (
| Метод | Путь | Описание | | Метод | Путь | Описание |
|--------|------------------|-------------------------| |--------|------------------|-------------------------|
| GET | /api/entries | Получить все записи | | GET | /api/entries | Список записей (id, created_at — без content) |
| POST | /api/entries | Создать запись | | POST | /api/entries | Создать запись |
| DELETE | /api/entries/:id | Удалить запись по id | | DELETE | /api/entries/:id | Удалить запись по id |
| GET | /api/entries/:id/content | Получить контент записи (plain text) | | GET | /api/entries/:id/content | Получить контент записи (plain text) |
## Frontend ## Frontend
- Сверху: большая `<textarea>` + кнопка "Создать" - Сверху: большая `<textarea>` + кнопка "Create"
- Ниже: список всех записей (новые сверху), у каждой кнопки "Удалить" и "Копировать" - Ниже: список всех записей (новые сверху), у каждой кнопки "Delete" и "Copy"
- Копирование — через `navigator.clipboard.writeText()` - Копирование — через `navigator.clipboard.writeText()`
## Команды ## Команды

View File

@@ -29,7 +29,18 @@ function App() {
const handleCopy = async (id: number) => { const handleCopy = async (id: number) => {
const text = await getEntryContent(id); const text = await getEntryContent(id);
navigator.clipboard.writeText(text); if (navigator.clipboard) {
await navigator.clipboard.writeText(text);
} else {
const textarea = document.createElement("textarea");
textarea.value = text;
textarea.style.position = "fixed";
textarea.style.opacity = "0";
document.body.appendChild(textarea);
textarea.select();
document.execCommand("copy");
document.body.removeChild(textarea);
}
}; };
return ( return (