Compare commits

...

15 Commits

Author SHA1 Message Date
8a36f5744d Merge pull request 'edit prekol ac dc' (#8) from fix into test
All checks were successful
CI/CD / test-backend (pull_request) Successful in 7s
CI/CD / test-frontend (pull_request) Successful in 11s
CI/CD Pipeline / Overall Status ✅ Все проверки прошли успешно
CI/CD / pr-status (pull_request) Successful in 1s
Reviewed-on: #8
2026-04-02 16:48:35 +03:00
867fcaa722 edit prekol ac dc
All checks were successful
CI/CD / test-backend (pull_request) Successful in 9s
CI/CD / test-frontend (pull_request) Successful in 10s
CI/CD Pipeline / Overall Status ✅ Все проверки прошли успешно
CI/CD / pr-status (pull_request) Successful in 1s
2026-04-02 16:47:23 +03:00
8378ec1b3e Merge pull request 'Refactor CI workflow to localize job names in Russian and remove deprecated multistep and test workflows. Update artifact upload step to ensure clarity in job descriptions.' (#6) from fix into test
All checks were successful
CI/CD / test-backend (pull_request) Successful in 6s
CI/CD / test-frontend (pull_request) Successful in 9s
CI/CD Pipeline / Overall Status ✅ Все проверки прошли успешно
CI/CD / pr-status (pull_request) Successful in 1s
Reviewed-on: http://5.129.221.254:3000/RLK/python-common-app/pulls/6
2026-03-24 14:05:16 +03:00
b3eaf03627 Add manual archiving workflow to Gitea CI
All checks were successful
CI/CD / test-backend (pull_request) Successful in 7s
CI/CD / test-frontend (pull_request) Successful in 9s
CI/CD Pipeline / Overall Status ✅ Все проверки прошли успешно
CI/CD / pr-status (pull_request) Successful in 1s
- Introduced a new workflow for manual archiving, allowing users to trigger the creation of archives for the api and web directories.
- The workflow includes steps for code checkout and artifact upload with a retention policy of 7 days.
2026-03-24 13:21:48 +03:00
288a2d81a1 Refactor CI workflow to localize job names in Russian and remove deprecated multistep and test workflows. Update artifact upload step to ensure clarity in job descriptions.
All checks were successful
CI/CD / test-backend (pull_request) Successful in 6s
CI/CD / test-frontend (pull_request) Successful in 9s
CI/CD Pipeline / Overall Status ✅ Все проверки прошли успешно
CI/CD / pr-status (pull_request) Successful in 1s
CI/CD / create-archives (pull_request) Has been skipped
2026-03-24 13:11:46 +03:00
9d4fc2cff5 Merge pull request 'Add initial setup for React and Vite application' (#4) from fix into test
All checks were successful
CI/CD / test-backend (pull_request) Successful in 6s
CI/CD / test-frontend (pull_request) Successful in 9s
CI/CD / create-archives (pull_request) Successful in 3s
CI/CD Pipeline / Overall Status ✅ All checks passed successfully
CI/CD / pr-status (pull_request) Successful in 1s
CI/CD / comment-on-failure (pull_request) Has been skipped
CI/CD / cleanup (pull_request) Successful in 1s
Reviewed-on: http://5.129.221.254:3000/RLK/python-common-app/pulls/4
2026-03-24 12:37:11 +03:00
38faec32f1 Comment out the full-build.zip creation step in CI workflow and update artifact upload to include api and web directories directly.
All checks were successful
CI/CD / test-backend (pull_request) Successful in 6s
CI/CD / test-frontend (pull_request) Successful in 9s
CI/CD / create-archives (pull_request) Successful in 3s
CI/CD Pipeline / Overall Status ✅ All checks passed successfully
CI/CD / pr-status (pull_request) Successful in 1s
CI/CD / comment-on-failure (pull_request) Has been skipped
CI/CD / cleanup (pull_request) Successful in 1s
2026-03-24 12:35:16 +03:00
71fdd9dcca Refactor CI workflow to create a single full-build.zip archive containing both api and web directories, with improved exclusion patterns. Update artifact upload step to use the new archive and maintain error handling for zip command.
All checks were successful
CI/CD / test-backend (pull_request) Successful in 7s
CI/CD / test-frontend (pull_request) Successful in 9s
CI/CD / create-archives (pull_request) Successful in 4s
CI/CD Pipeline / Overall Status ✅ All checks passed successfully
CI/CD / pr-status (pull_request) Successful in 1s
CI/CD / comment-on-failure (pull_request) Has been skipped
CI/CD / cleanup (pull_request) Successful in 1s
2026-03-24 12:29:01 +03:00
31afed45c0 Update CI workflow to use actions/upload-artifact@v3 for artifact uploads
All checks were successful
CI/CD / test-backend (pull_request) Successful in 7s
CI/CD / test-frontend (pull_request) Successful in 8s
CI/CD / create-archives (pull_request) Successful in 26s
CI/CD Pipeline / Overall Status ✅ All checks passed successfully
CI/CD / pr-status (pull_request) Successful in 1s
CI/CD / comment-on-failure (pull_request) Has been skipped
CI/CD / cleanup (pull_request) Successful in 1s
2026-03-24 12:23:44 +03:00
a06a9f585b Improve CI workflow by adding logging for zip creation and enforcing file presence. Added error handling for zip commands and a check to ensure artifacts are created before upload.
Some checks failed
CI/CD / test-backend (pull_request) Successful in 7s
CI/CD / test-frontend (pull_request) Successful in 9s
CI/CD / create-archives (pull_request) Failing after 3s
CI/CD Pipeline / Overall Status ✅ All checks passed successfully
CI/CD / pr-status (pull_request) Successful in 1s
CI/CD / comment-on-failure (pull_request) Has been skipped
CI/CD / cleanup (pull_request) Successful in 1s
2026-03-24 12:21:36 +03:00
0fe735ddf0 some shit
Some checks failed
CI/CD / test-backend (pull_request) Successful in 7s
CI/CD / test-frontend (pull_request) Successful in 55s
CI/CD / create-archives (pull_request) Failing after 4s
CI/CD Pipeline / Overall Status ✅ All checks passed successfully
CI/CD / pr-status (pull_request) Successful in 1s
CI/CD / comment-on-failure (pull_request) Has been skipped
CI/CD / cleanup (pull_request) Successful in 1s
2026-03-24 12:15:22 +03:00
20eb72a71d Add initial setup for React and Vite application
Some checks failed
CI/CD / test-backend (pull_request) Failing after 14s
CI/CD / test-frontend (pull_request) Has been skipped
CI/CD / create-archives (pull_request) Failing after 4s
CI/CD Pipeline / Overall Status ❌ Some checks failed
CI/CD / pr-status (pull_request) Failing after 1s
CI/CD / comment-on-failure (pull_request) Successful in 1s
CI/CD / cleanup (pull_request) Successful in 1s
- Created essential files including `package.json`, `vite.config.js`, and `index.html`.
- Added ESLint configuration for code quality.
- Included basic styles in `App.css` and `index.css`.
- Implemented main application component in `App.jsx` with a counter feature.
- Added necessary assets such as logos and icons.
- Established a `.gitignore` file to exclude unnecessary files.
2026-03-24 12:10:25 +03:00
6655811cc1 Merge pull request 'fix' (#3) from fix into test
Reviewed-on: http://5.129.221.254:3000/RLK/python-common-app/pulls/3
2026-03-24 11:59:51 +03:00
2962870dd3 Merge branch 'test' into fix
Some checks failed
CI/CD / test-backend (pull_request) Failing after 6s
CI/CD / test-frontend (pull_request) Has been skipped
CI/CD / create-archives (pull_request) Failing after 3s
CI/CD Pipeline / Overall Status ❌ Some checks failed
CI/CD / pr-status (pull_request) Failing after 1s
CI/CD / comment-on-failure (pull_request) Successful in 1s
CI/CD / cleanup (pull_request) Successful in 1s
2026-03-24 11:56:05 +03:00
84055cd389 Commented out the failing test_checker function in test_app.py
Some checks failed
CI/CD / test-backend (pull_request) Failing after 5s
CI/CD / create-archives (pull_request) Has been skipped
2026-03-24 11:38:09 +03:00
22 changed files with 3205 additions and 424 deletions

View File

@@ -0,0 +1,20 @@
name: Ручная архивация
on:
workflow_dispatch: # только ручной запуск
jobs:
create-archives:
runs-on: ubuntu-latest
steps:
- name: Проверка кода
uses: actions/checkout@v4
- name: Загрузка артифакта
uses: actions/upload-artifact@v3
with:
name: build-artifacts-${{ github.run_id }}
path: |
api/
web/
retention-days: 7

View File

@@ -12,80 +12,55 @@ jobs:
test-backend: test-backend:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout code - name: Проверка кода
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Set up Python - name: Настройка Python
uses: actions/setup-python@v5 uses: actions/setup-python@v5
with: with:
python-version: '3.11' python-version: '3.11'
- name: Install dependencies - name: Установка зависимостей
run: | run: |
cd api cd api
pip install -r requirements.txt pip install -r requirements.txt
- name: Verify build - name: Подтверждение сборки
run: | run: |
cd api python -c "from api.main import app"
python -c "from main import app"
- name: Run tests - name: Запуск тестов
run: | run: |
cd api pytest -q
pytest tests/
test-frontend: test-frontend:
needs: test-backend
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout code - name: Проверка кода
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Set up Node.js - name: Настройка Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: '20' node-version: '20'
- name: Install dependencies - name: Установка зависимостей
run: | run: |
cd web cd web
npm ci npm ci
- name: Build frontend - name: Сборка фронта
run: | run: |
cd web cd web
npm run build npm run build
create-archives:
needs: [test-backend, test-frontend]
runs-on: ubuntu-latest
if: always() && !cancelled()
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Create archives
run: |
zip -r api.zip api/ -x "*.pyc" "*__pycache__*" "*.git*" "*.pytest_cache*"
zip -r web.zip web/ -x "node_modules/*" ".git*" "dist/*" "*.log"
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: build-artifacts-${{ github.run_id }}
path: |
api.zip
web.zip
retention-days: 7
# Явный статус для PR # Явный статус для PR
pr-status: pr-status:
needs: [test-backend, test-frontend] needs: [test-backend, test-frontend]
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: always() && github.event_name == 'pull_request' if: always() && github.event_name == 'pull_request'
steps: steps:
- name: Check status and update PR - name: Проверка статуса и обновление PR
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: | run: |
@@ -93,11 +68,11 @@ jobs:
if [[ "${{ needs.test-backend.result }}" == "success" ]] && \ if [[ "${{ needs.test-backend.result }}" == "success" ]] && \
[[ "${{ needs.test-frontend.result }}" == "success" ]]; then [[ "${{ needs.test-frontend.result }}" == "success" ]]; then
STATE="success" STATE="success"
DESCRIPTION="✅ All checks passed successfully" DESCRIPTION="✅ Все проверки прошли успешно"
EXIT_CODE=0 EXIT_CODE=0
else else
STATE="failure" STATE="failure"
DESCRIPTION="❌ Some checks failed" DESCRIPTION="❌ Некоторые проверки сломались"
EXIT_CODE=1 EXIT_CODE=1
fi fi
@@ -121,54 +96,3 @@ jobs:
# Выходим с соответствующим кодом, чтобы блокировать PR при неудаче # Выходим с соответствующим кодом, чтобы блокировать PR при неудаче
exit $EXIT_CODE exit $EXIT_CODE
# Опционально: добавляем комментарий в PR при неудаче
comment-on-failure:
needs: [test-backend, test-frontend, pr-status]
runs-on: ubuntu-latest
if: failure() && github.event_name == 'pull_request'
steps:
- name: Add failure comment to PR
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Определяем какие проверки не прошли
BACKEND_STATUS="${{ needs.test-backend.result }}"
FRONTEND_STATUS="${{ needs.test-frontend.result }}"
COMMENT="## ❌ Проверки не пройдены!
### Результаты проверок:
| Проверка | Статус |
|----------|--------|
| **Backend tests** | $( [ "$BACKEND_STATUS" = "success" ] && echo "✅ Успешно" || echo "❌ Ошибка" ) |
| **Frontend build** | $( [ "$FRONTEND_STATUS" = "success" ] && echo "✅ Успешно" || echo "❌ Ошибка" ) |
### Детали:
- **Ветка**: ${{ github.head_ref }}
- **Коммит**: \`${{ github.event.pull_request.head.sha }}\`
- **Запуск**: [Смотреть детали](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
Пожалуйста, исправьте ошибки перед слиянием. 🚨"
# Находим PR номер
PR_NUMBER=$(jq --raw-output .number "$GITHUB_EVENT_PATH")
# Добавляем комментарий
curl -X POST "${{ github.api_url }}/repos/${{ github.repository }}/issues/${PR_NUMBER}/comments" \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"body\": $(echo "$COMMENT" | jq -Rs .)}"
echo "Comment added to PR #$PR_NUMBER"
# Опционально: удаляем старые артефакты
cleanup:
needs: [create-archives, pr-status]
runs-on: ubuntu-latest
if: always()
steps:
- name: Clean up old artifacts
run: |
echo "Cleaning up temporary files"
# Здесь можно добавить логику очистки, если нужно

View File

@@ -1,314 +0,0 @@
# name: Release pipeline
# on:
# workflow_dispatch:
# env:
# WEB_IMAGE_NAME: ${{ secrets.DOCKERHUB_USERNAME }}/tatikoma-web
# WORKER_IMAGE_NAME: ${{ secrets.DOCKERHUB_USERNAME }}/tatikoma-worker
# PROJECT_DIR: /home/${{ secrets.USER }}/tatikoma
# jobs:
# build-and-push:
# runs-on: ubuntu-latest
# steps:
# - name: Checkout code
# uses: actions/checkout@v4
# - name: Set up Docker Buildx
# uses: docker/setup-buildx-action@v3
# - name: Log in to Docker Hub
# uses: docker/login-action@v3
# with:
# username: ${{ secrets.DOCKERHUB_USERNAME }}
# password: ${{ secrets.DOCKERHUB_PASSWORD }}
# - name: Build and push tatikoma-web image
# uses: docker/build-push-action@v5
# with:
# context: .
# file: ./Dockerfile.web
# push: true
# tags: |
# ${{ secrets.DOCKERHUB_USERNAME }}/tatikoma-web:latest
# cache-from: type=registry,ref=${{ secrets.DOCKERHUB_USERNAME }}/tatikoma-web:latest
# cache-to: type=inline
# - name: Build and push tatikoma-worker image
# uses: docker/build-push-action@v5
# with:
# context: .
# file: ./Dockerfile.worker
# push: true
# tags: |
# ${{ secrets.DOCKERHUB_USERNAME }}/tatikoma-worker:latest
# cache-from: type=registry,ref=${{ secrets.DOCKERHUB_USERNAME }}/tatikoma-worker:latest
# cache-to: type=inline
# - name: Verify push
# run: |
# echo "Docker images successfully built and pushed to Docker Hub"
# echo "Images:"
# echo "- ${{ secrets.DOCKERHUB_USERNAME }}/tatikoma-web:latest"
# echo "- ${{ secrets.DOCKERHUB_USERNAME }}/tatikoma-worker:latest"
# build-and-push-send-success-message:
# runs-on: ubuntu-latest
# needs: build-and-push
# if: success()
# steps:
# - name: Send success message
# uses: appleboy/telegram-action@master
# with:
# to: ${{ secrets.TELEGRAM_TO }}
# token: ${{ secrets.TELEGRAM_TOKEN }}
# format: markdown
# message: |
# *${{ github.workflow }}*
# ✅ New images pushed to Dockerhub 🐳
# Images:
# - `${{ secrets.DOCKERHUB_USERNAME }}/tatikoma-web:latest`
# - `${{ secrets.DOCKERHUB_USERNAME }}/tatikoma-worker:latest`
# Status: Success
# build-and-push-send-failure-message:
# runs-on: ubuntu-latest
# needs: build-and-push
# if: failure()
# steps:
# - name: Send failure message
# uses: appleboy/telegram-action@master
# with:
# to: ${{ secrets.TELEGRAM_TO }}
# token: ${{ secrets.TELEGRAM_TOKEN }}
# format: markdown
# message: |
# *${{ github.workflow }}*
# ❌ Error creating and pushing docker images
# [View failed workflow](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
# deploy:
# name: Deploy to server
# runs-on: ubuntu-latest
# needs: build-and-push
# if: success()
# outputs:
# container_status: ${{ steps.get_status.outputs.status }}
# steps:
# - name: Checkout code
# uses: actions/checkout@v4
# - name: Create project directory
# uses: appleboy/ssh-action@master
# with:
# host: ${{ secrets.HOST }}
# username: ${{ secrets.USER }}
# password: ${{ secrets.SSH_PASSWORD }}
# script: |
# set -e
# echo "Creating project directory..."
# mkdir -p tatikoma/liquibase
# mkdir -p tatikoma/liquibase/changelog
# - name: Copy project files
# shell: bash
# run: |
# # Копируем docker-compose.yml
# sshpass -p "${{ secrets.SSH_PASSWORD }}" scp -o StrictHostKeyChecking=no \
# docker-compose.yml \
# ${{ secrets.USER }}@${{ secrets.HOST }}:tatikoma/
# # Копируем liquibase файлы
# sshpass -p "${{ secrets.SSH_PASSWORD }}" scp -o StrictHostKeyChecking=no \
# -r ./liquibase/changelog/ \
# ${{ secrets.USER }}@${{ secrets.HOST }}:tatikoma/liquibase/
# # Копируем nginx конфиги
# sshpass -p "${{ secrets.SSH_PASSWORD }}" scp -o StrictHostKeyChecking=no \
# -r ./nginx/ \
# ${{ secrets.USER }}@${{ secrets.HOST }}:tatikoma/
# - name: Create or update environment file
# uses: appleboy/ssh-action@master
# with:
# host: ${{ secrets.HOST }}
# username: ${{ secrets.USER }}
# password: ${{ secrets.SSH_PASSWORD }}
# script: |
# set -e
# cd tatikoma
# rm -f .env
# touch .env
# echo "${{ secrets.ENV_FILE }}" >> .env
# echo "Environment file created/updated"
# - name: Prepare directories
# uses: appleboy/ssh-action@master
# with:
# host: ${{ secrets.HOST }}
# username: ${{ secrets.USER }}
# password: ${{ secrets.SSH_PASSWORD }}
# script: |
# set -e
# cd tatikoma
# mkdir -p {nginx/ssl,nginx/htpasswd,uptime-kuma-data}
# - name: Setup authentication
# uses: appleboy/ssh-action@master
# with:
# host: ${{ secrets.HOST }}
# username: ${{ secrets.USER }}
# password: ${{ secrets.SSH_PASSWORD }}
# script: |
# set -e
# cd tatikoma
# echo "Setting up authentication..."
# mkdir -p nginx/htpasswd
# if ! command -v htpasswd &> /dev/null; then
# echo "Installing apache2-utils..."
# apt-get update && apt-get install -y apache2-utils
# fi
# # Используем echo для передачи пароля через stdin
# # Это безопаснее, чем передавать как аргумент
# htpasswd -b -c nginx/htpasswd/.htpasswd "${{ secrets.UPTIME_KUMA_USER }}" "${{ secrets.UPTIME_KUMA_PASSWORD }}"
# echo "Authentication setup complete"
# - name: Setup SSL certificates (if not exists)
# uses: appleboy/ssh-action@master
# with:
# host: ${{ secrets.HOST }}
# username: ${{ secrets.USER }}
# password: ${{ secrets.SSH_PASSWORD }}
# script: |
# set -e
# cd tatikoma
# echo "Checking SSL certificates..."
# # Проверяем существование SSL сертификатов
# if [ ! -f "nginx/ssl/live/${{ secrets.HOST }}/privkey.pem" ]; then
# echo "ERROR: SSL certificates not found!"
# echo "Please generate SSL certificates manually first:"
# echo "mkdir -p nginx/ssl/live/${{ secrets.HOST }}/"
# echo "Then place privkey.pem and fullchain.pem in that directory"
# exit 1
# else
# echo "SSL certificates found, continuing..."
# fi
# - name: Log in to Docker Hub
# uses: docker/login-action@v3
# with:
# username: ${{ secrets.DOCKERHUB_USERNAME }}
# password: ${{ secrets.DOCKERHUB_PASSWORD }}
# - name: Clean up old images and containers
# uses: appleboy/ssh-action@master
# with:
# host: ${{ secrets.HOST }}
# username: ${{ secrets.USER }}
# password: ${{ secrets.SSH_PASSWORD }}
# script: |
# set -e
# echo "Stopping and removing Tatikoma containers..."
# docker stop tatikoma_web tatikoma_liquibase tatikoma_worker tatikoma_nginx tatikoma_uptime_kuma 2>/dev/null || true
# docker rm tatikoma_web tatikoma_liquibase tatikoma_worker tatikoma_nginx tatikoma_uptime_kuma 2>/dev/null || true
# echo "Cleaning up old Docker images..."
# docker images lulufox/tatikoma-web --format "table {{.ID}}\t{{.Repository}}\t{{.Tag}}\t{{.CreatedAt}}" || true
# docker images lulufox/tatikoma-worker --format "table {{.ID}}\t{{.Repository}}\t{{.Tag}}\t{{.CreatedAt}}" || true
# docker rmi $(docker images lulufox/tatikoma-web -q) 2>/dev/null || true
# docker rmi $(docker images lulufox/tatikoma-worker -q) 2>/dev/null || true
# docker image prune -f
# - name: Pull latest images
# uses: appleboy/ssh-action@master
# with:
# host: ${{ secrets.HOST }}
# username: ${{ secrets.USER }}
# password: ${{ secrets.SSH_PASSWORD }}
# script: |
# set -e
# echo "Pulling latest Docker images..."
# docker pull lulufox/tatikoma-web:latest
# docker pull lulufox/tatikoma-worker:latest
# - name: Run migrations
# uses: appleboy/ssh-action@master
# with:
# host: ${{ secrets.HOST }}
# username: ${{ secrets.USER }}
# password: ${{ secrets.SSH_PASSWORD }}
# script: |
# set -e
# cd tatikoma
# echo "Running migrations..."
# docker compose up -d liquibase
# - name: Start application services
# uses: appleboy/ssh-action@master
# with:
# host: ${{ secrets.HOST }}
# username: ${{ secrets.USER }}
# password: ${{ secrets.SSH_PASSWORD }}
# script: |
# set -e
# cd tatikoma
# echo "Starting all services..."
# docker compose up -d
# echo "Waiting for services to start..."
# sleep 30
# echo "Current Tatikoma containers status:"
# docker ps --filter "name=tatikoma" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
# echo "Nginx configuration test:"
# docker exec tatikoma_nginx nginx -t || true
# - name: Get container status
# id: get_status
# run: |
# sleep 15
# status=$(sshpass -p "${{ secrets.SSH_PASSWORD }}" ssh -o StrictHostKeyChecking=no \
# ${{ secrets.USER }}@${{ secrets.HOST }} \
# "docker ps -a --filter "name=tatikoma" --format 'table {{.Names}}\t{{.Status}}'")
# echo "status<<EOF" >> $GITHUB_OUTPUT
# echo "$status" >> $GITHUB_OUTPUT
# echo "EOF" >> $GITHUB_OUTPUT
# send_message:
# runs-on: ubuntu-latest
# needs: deploy
# if: always()
# steps:
# - name: send message
# uses: appleboy/telegram-action@master
# with:
# to: ${{ secrets.TELEGRAM_TO }}
# token: ${{ secrets.TELEGRAM_TOKEN }}
# format: markdown
# message: |
# *${{ github.workflow }}*
# Репозиторий: \`${{ github.repository }}\`
# Статус контейнеров:
# ```
# ${{ needs.deploy.outputs.container_status || 'Не удалось получить статус' }}
# ```
# Uptime Kuma доступен по: https://${{ secrets.HOST }}

View File

@@ -1,17 +0,0 @@
# name: Test Workflow
# on:
# push:
# jobs:
# test:
# runs-on: ubuntu-latest
# steps:
# - name: Print environment variables
# run: |
# echo "GITHUB_REPOSITORY: $GITHUB_REPOSITORY"
# echo "GITHUB_SHA: $GITHUB_SHA"
# echo "GITHUB_REF: $GITHUB_REF"
# echo "GITHUB_ACTOR: $GITHUB_ACTOR"
# echo "PATH: $PATH"

View File

@@ -18,7 +18,7 @@ def test_root() -> None:
assert resp.json() == {"message": "FastAPI is running"} assert resp.json() == {"message": "FastAPI is running"}
def test_checker() -> None: # def test_checker() -> None:
a = 1 # a = 1
assert a == 2 # assert a == 2

24
web/.gitignore vendored Normal file
View File

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

16
web/README.md Normal file
View File

@@ -0,0 +1,16 @@
# React + Vite
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
Currently, two official plugins are available:
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Oxc](https://oxc.rs)
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/)
## React Compiler
The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
## Expanding the ESLint configuration
If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project.

29
web/eslint.config.js Normal file
View File

@@ -0,0 +1,29 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import { defineConfig, globalIgnores } from 'eslint/config'
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{js,jsx}'],
extends: [
js.configs.recommended,
reactHooks.configs.flat.recommended,
reactRefresh.configs.vite,
],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
parserOptions: {
ecmaVersion: 'latest',
ecmaFeatures: { jsx: true },
sourceType: 'module',
},
},
rules: {
'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
},
},
])

13
web/index.html Normal file
View File

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

2599
web/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

27
web/package.json Normal file
View File

@@ -0,0 +1,27 @@
{
"name": "web",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"start": "vite",
"build": "vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"react": "^19.2.4",
"react-dom": "^19.2.4"
},
"devDependencies": {
"@eslint/js": "^9.39.4",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^6.0.1",
"eslint": "^9.39.4",
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.5.2",
"globals": "^17.4.0",
"vite": "^8.0.1"
}
}

1
web/public/favicon.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.3 KiB

24
web/public/icons.svg Normal file
View File

@@ -0,0 +1,24 @@
<svg xmlns="http://www.w3.org/2000/svg">
<symbol id="bluesky-icon" viewBox="0 0 16 17">
<g clip-path="url(#bluesky-clip)"><path fill="#08060d" d="M7.75 7.735c-.693-1.348-2.58-3.86-4.334-5.097-1.68-1.187-2.32-.981-2.74-.79C.188 2.065.1 2.812.1 3.251s.241 3.602.398 4.13c.52 1.744 2.367 2.333 4.07 2.145-2.495.37-4.71 1.278-1.805 4.512 3.196 3.309 4.38-.71 4.987-2.746.608 2.036 1.307 5.91 4.93 2.746 2.72-2.746.747-4.143-1.747-4.512 1.702.189 3.55-.4 4.07-2.145.156-.528.397-3.691.397-4.13s-.088-1.186-.575-1.406c-.42-.19-1.06-.395-2.741.79-1.755 1.24-3.64 3.752-4.334 5.099"/></g>
<defs><clipPath id="bluesky-clip"><path fill="#fff" d="M.1.85h15.3v15.3H.1z"/></clipPath></defs>
</symbol>
<symbol id="discord-icon" viewBox="0 0 20 19">
<path fill="#08060d" d="M16.224 3.768a14.5 14.5 0 0 0-3.67-1.153c-.158.286-.343.67-.47.976a13.5 13.5 0 0 0-4.067 0c-.128-.306-.317-.69-.476-.976A14.4 14.4 0 0 0 3.868 3.77C1.546 7.28.916 10.703 1.231 14.077a14.7 14.7 0 0 0 4.5 2.306q.545-.748.965-1.587a9.5 9.5 0 0 1-1.518-.74q.191-.14.372-.293c2.927 1.369 6.107 1.369 8.999 0q.183.152.372.294-.723.437-1.52.74.418.838.963 1.588a14.6 14.6 0 0 0 4.504-2.308c.37-3.911-.63-7.302-2.644-10.309m-9.13 8.234c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.894 0 1.614.82 1.599 1.82.001 1-.705 1.82-1.6 1.82m5.91 0c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.893 0 1.614.82 1.599 1.82 0 1-.706 1.82-1.6 1.82"/>
</symbol>
<symbol id="documentation-icon" viewBox="0 0 21 20">
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="m15.5 13.333 1.533 1.322c.645.555.967.833.967 1.178s-.322.623-.967 1.179L15.5 18.333m-3.333-5-1.534 1.322c-.644.555-.966.833-.966 1.178s.322.623.966 1.179l1.534 1.321"/>
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M17.167 10.836v-4.32c0-1.41 0-2.117-.224-2.68-.359-.906-1.118-1.621-2.08-1.96-.599-.21-1.349-.21-2.848-.21-2.623 0-3.935 0-4.983.369-1.684.591-3.013 1.842-3.641 3.428C3 6.449 3 7.684 3 10.154v2.122c0 2.558 0 3.838.706 4.726q.306.383.713.671c.76.536 1.79.64 3.581.66"/>
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M3 10a2.78 2.78 0 0 1 2.778-2.778c.555 0 1.209.097 1.748-.047.48-.129.854-.503.982-.982.145-.54.048-1.194.048-1.749a2.78 2.78 0 0 1 2.777-2.777"/>
</symbol>
<symbol id="github-icon" viewBox="0 0 19 19">
<path fill="#08060d" fill-rule="evenodd" d="M9.356 1.85C5.05 1.85 1.57 5.356 1.57 9.694a7.84 7.84 0 0 0 5.324 7.44c.387.079.528-.168.528-.376 0-.182-.013-.805-.013-1.454-2.165.467-2.616-.935-2.616-.935-.349-.91-.864-1.143-.864-1.143-.71-.48.051-.48.051-.48.787.051 1.2.805 1.2.805.695 1.194 1.817.857 2.268.649.064-.507.27-.857.49-1.052-1.728-.182-3.545-.857-3.545-3.87 0-.857.31-1.558.8-2.104-.078-.195-.349-1 .077-2.078 0 0 .657-.208 2.14.805a7.5 7.5 0 0 1 1.946-.26c.657 0 1.328.092 1.946.26 1.483-1.013 2.14-.805 2.14-.805.426 1.078.155 1.883.078 2.078.502.546.799 1.247.799 2.104 0 3.013-1.818 3.675-3.558 3.87.284.247.528.714.528 1.454 0 1.052-.012 1.896-.012 2.156 0 .208.142.455.528.377a7.84 7.84 0 0 0 5.324-7.441c.013-4.338-3.48-7.844-7.773-7.844" clip-rule="evenodd"/>
</symbol>
<symbol id="social-icon" viewBox="0 0 20 20">
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M12.5 6.667a4.167 4.167 0 1 0-8.334 0 4.167 4.167 0 0 0 8.334 0"/>
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M2.5 16.667a5.833 5.833 0 0 1 8.75-5.053m3.837.474.513 1.035c.07.144.257.282.414.309l.93.155c.596.1.736.536.307.965l-.723.73a.64.64 0 0 0-.152.531l.207.903c.164.715-.213.991-.84.618l-.872-.52a.63.63 0 0 0-.577 0l-.872.52c-.624.373-1.003.094-.84-.618l.207-.903a.64.64 0 0 0-.152-.532l-.723-.729c-.426-.43-.289-.864.306-.964l.93-.156a.64.64 0 0 0 .412-.31l.513-1.034c.28-.562.735-.562 1.012 0"/>
</symbol>
<symbol id="x-icon" viewBox="0 0 19 19">
<path fill="#08060d" fill-rule="evenodd" d="M1.893 1.98c.052.072 1.245 1.769 2.653 3.77l2.892 4.114c.183.261.333.48.333.486s-.068.089-.152.183l-.522.593-.765.867-3.597 4.087c-.375.426-.734.834-.798.905a1 1 0 0 0-.118.148c0 .01.236.017.664.017h.663l.729-.83c.4-.457.796-.906.879-.999a692 692 0 0 0 1.794-2.038c.034-.037.301-.34.594-.675l.551-.624.345-.392a7 7 0 0 1 .34-.374c.006 0 .93 1.306 2.052 2.903l2.084 2.965.045.063h2.275c1.87 0 2.273-.003 2.266-.021-.008-.02-1.098-1.572-3.894-5.547-2.013-2.862-2.28-3.246-2.273-3.266.008-.019.282-.332 2.085-2.38l2-2.274 1.567-1.782c.022-.028-.016-.03-.65-.03h-.674l-.3.342a871 871 0 0 1-1.782 2.025c-.067.075-.405.458-.75.852a100 100 0 0 1-.803.91c-.148.172-.299.344-.99 1.127-.304.343-.32.358-.345.327-.015-.019-.904-1.282-1.976-2.808L6.365 1.85H1.8zm1.782.91 8.078 11.294c.772 1.08 1.413 1.973 1.425 1.984.016.017.241.02 1.05.017l1.03-.004-2.694-3.766L7.796 5.75 5.722 2.852l-1.039-.004-1.039-.004z" clip-rule="evenodd"/>
</symbol>
</svg>

After

Width:  |  Height:  |  Size: 4.9 KiB

184
web/src/App.css Normal file
View File

@@ -0,0 +1,184 @@
.counter {
font-size: 16px;
padding: 5px 10px;
border-radius: 5px;
color: var(--accent);
background: var(--accent-bg);
border: 2px solid transparent;
transition: border-color 0.3s;
margin-bottom: 24px;
&:hover {
border-color: var(--accent-border);
}
&:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
}
.hero {
position: relative;
.base,
.framework,
.vite {
inset-inline: 0;
margin: 0 auto;
}
.base {
width: 170px;
position: relative;
z-index: 0;
}
.framework,
.vite {
position: absolute;
}
.framework {
z-index: 1;
top: 34px;
height: 28px;
transform: perspective(2000px) rotateZ(300deg) rotateX(44deg) rotateY(39deg)
scale(1.4);
}
.vite {
z-index: 0;
top: 107px;
height: 26px;
width: auto;
transform: perspective(2000px) rotateZ(300deg) rotateX(40deg) rotateY(39deg)
scale(0.8);
}
}
#center {
display: flex;
flex-direction: column;
gap: 25px;
place-content: center;
place-items: center;
flex-grow: 1;
@media (max-width: 1024px) {
padding: 32px 20px 24px;
gap: 18px;
}
}
#next-steps {
display: flex;
border-top: 1px solid var(--border);
text-align: left;
& > div {
flex: 1 1 0;
padding: 32px;
@media (max-width: 1024px) {
padding: 24px 20px;
}
}
.icon {
margin-bottom: 16px;
width: 22px;
height: 22px;
}
@media (max-width: 1024px) {
flex-direction: column;
text-align: center;
}
}
#docs {
border-right: 1px solid var(--border);
@media (max-width: 1024px) {
border-right: none;
border-bottom: 1px solid var(--border);
}
}
#next-steps ul {
list-style: none;
padding: 0;
display: flex;
gap: 8px;
margin: 32px 0 0;
.logo {
height: 18px;
}
a {
color: var(--text-h);
font-size: 16px;
border-radius: 6px;
background: var(--social-bg);
display: flex;
padding: 6px 12px;
align-items: center;
gap: 8px;
text-decoration: none;
transition: box-shadow 0.3s;
&:hover {
box-shadow: var(--shadow);
}
.button-icon {
height: 18px;
width: 18px;
}
}
@media (max-width: 1024px) {
margin-top: 20px;
flex-wrap: wrap;
justify-content: center;
li {
flex: 1 1 calc(50% - 8px);
}
a {
width: 100%;
justify-content: center;
box-sizing: border-box;
}
}
}
#spacer {
height: 88px;
border-top: 1px solid var(--border);
@media (max-width: 1024px) {
height: 48px;
}
}
.ticks {
position: relative;
width: 100%;
&::before,
&::after {
content: '';
position: absolute;
top: -4.5px;
border: 5px solid transparent;
}
&::before {
left: 0;
border-left-color: var(--border);
}
&::after {
right: 0;
border-right-color: var(--border);
}
}

121
web/src/App.jsx Normal file
View File

@@ -0,0 +1,121 @@
import { useState } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from './assets/vite.svg'
import heroImg from './assets/hero.png'
import './App.css'
function App() {
const [count, setCount] = useState(0)
return (
<>
<section id="center">
<div className="hero">
<img src={heroImg} className="base" width="170" height="179" alt="" />
<img src={reactLogo} className="framework" alt="React logo" />
<img src={viteLogo} className="vite" alt="Vite logo" />
</div>
<div>
<h1>Get started</h1>
<p>
Edit <code>src/App.jsx</code> and save to test <code>HMR</code>
</p>
</div>
<button
className="counter"
onClick={() => setCount((count) => count + 1)}
>
Count is {count}
</button>
</section>
<div className="ticks"></div>
<section id="next-steps">
<div id="docs">
<svg className="icon" role="presentation" aria-hidden="true">
<use href="/icons.svg#documentation-icon"></use>
</svg>
<h2>Documentation</h2>
<p>Your questions, answered</p>
<ul>
<li>
<a href="https://vite.dev/" target="_blank">
<img className="logo" src={viteLogo} alt="" />
Explore Vite
</a>
</li>
<li>
<a href="https://react.dev/" target="_blank">
<img className="button-icon" src={reactLogo} alt="" />
Learn more
</a>
</li>
</ul>
</div>
<div id="social">
<svg className="icon" role="presentation" aria-hidden="true">
<use href="/icons.svg#social-icon"></use>
</svg>
<h2>Connect with us</h2>
<p>Join the Vite community</p>
<ul>
<li>
<a href="https://github.com/vitejs/vite" target="_blank">
<svg
className="button-icon"
role="presentation"
aria-hidden="true"
>
<use href="/icons.svg#github-icon"></use>
</svg>
GitHub
</a>
</li>
<li>
<a href="https://chat.vite.dev/" target="_blank">
<svg
className="button-icon"
role="presentation"
aria-hidden="true"
>
<use href="/icons.svg#discord-icon"></use>
</svg>
Discord
</a>
</li>
<li>
<a href="https://x.com/vite_js" target="_blank">
<svg
className="button-icon"
role="presentation"
aria-hidden="true"
>
<use href="/icons.svg#x-icon"></use>
</svg>
X.com
</a>
</li>
<li>
<a href="https://bsky.app/profile/vite.dev" target="_blank">
<svg
className="button-icon"
role="presentation"
aria-hidden="true"
>
<use href="/icons.svg#bluesky-icon"></use>
</svg>
Bluesky
</a>
</li>
</ul>
</div>
</section>
<div className="ticks"></div>
<section id="spacer"></section>
</>
)
}
export default App

BIN
web/src/assets/hero.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

1
web/src/assets/react.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="35.93" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 228"><path fill="#00D8FF" d="M210.483 73.824a171.49 171.49 0 0 0-8.24-2.597c.465-1.9.893-3.777 1.273-5.621c6.238-30.281 2.16-54.676-11.769-62.708c-13.355-7.7-35.196.329-57.254 19.526a171.23 171.23 0 0 0-6.375 5.848a155.866 155.866 0 0 0-4.241-3.917C100.759 3.829 77.587-4.822 63.673 3.233C50.33 10.957 46.379 33.89 51.995 62.588a170.974 170.974 0 0 0 1.892 8.48c-3.28.932-6.445 1.924-9.474 2.98C17.309 83.498 0 98.307 0 113.668c0 15.865 18.582 31.778 46.812 41.427a145.52 145.52 0 0 0 6.921 2.165a167.467 167.467 0 0 0-2.01 9.138c-5.354 28.2-1.173 50.591 12.134 58.266c13.744 7.926 36.812-.22 59.273-19.855a145.567 145.567 0 0 0 5.342-4.923a168.064 168.064 0 0 0 6.92 6.314c21.758 18.722 43.246 26.282 56.54 18.586c13.731-7.949 18.194-32.003 12.4-61.268a145.016 145.016 0 0 0-1.535-6.842c1.62-.48 3.21-.974 4.76-1.488c29.348-9.723 48.443-25.443 48.443-41.52c0-15.417-17.868-30.326-45.517-39.844Zm-6.365 70.984c-1.4.463-2.836.91-4.3 1.345c-3.24-10.257-7.612-21.163-12.963-32.432c5.106-11 9.31-21.767 12.459-31.957c2.619.758 5.16 1.557 7.61 2.4c23.69 8.156 38.14 20.213 38.14 29.504c0 9.896-15.606 22.743-40.946 31.14Zm-10.514 20.834c2.562 12.94 2.927 24.64 1.23 33.787c-1.524 8.219-4.59 13.698-8.382 15.893c-8.067 4.67-25.32-1.4-43.927-17.412a156.726 156.726 0 0 1-6.437-5.87c7.214-7.889 14.423-17.06 21.459-27.246c12.376-1.098 24.068-2.894 34.671-5.345a134.17 134.17 0 0 1 1.386 6.193ZM87.276 214.515c-7.882 2.783-14.16 2.863-17.955.675c-8.075-4.657-11.432-22.636-6.853-46.752a156.923 156.923 0 0 1 1.869-8.499c10.486 2.32 22.093 3.988 34.498 4.994c7.084 9.967 14.501 19.128 21.976 27.15a134.668 134.668 0 0 1-4.877 4.492c-9.933 8.682-19.886 14.842-28.658 17.94ZM50.35 144.747c-12.483-4.267-22.792-9.812-29.858-15.863c-6.35-5.437-9.555-10.836-9.555-15.216c0-9.322 13.897-21.212 37.076-29.293c2.813-.98 5.757-1.905 8.812-2.773c3.204 10.42 7.406 21.315 12.477 32.332c-5.137 11.18-9.399 22.249-12.634 32.792a134.718 134.718 0 0 1-6.318-1.979Zm12.378-84.26c-4.811-24.587-1.616-43.134 6.425-47.789c8.564-4.958 27.502 2.111 47.463 19.835a144.318 144.318 0 0 1 3.841 3.545c-7.438 7.987-14.787 17.08-21.808 26.988c-12.04 1.116-23.565 2.908-34.161 5.309a160.342 160.342 0 0 1-1.76-7.887Zm110.427 27.268a347.8 347.8 0 0 0-7.785-12.803c8.168 1.033 15.994 2.404 23.343 4.08c-2.206 7.072-4.956 14.465-8.193 22.045a381.151 381.151 0 0 0-7.365-13.322Zm-45.032-43.861c5.044 5.465 10.096 11.566 15.065 18.186a322.04 322.04 0 0 0-30.257-.006c4.974-6.559 10.069-12.652 15.192-18.18ZM82.802 87.83a323.167 323.167 0 0 0-7.227 13.238c-3.184-7.553-5.909-14.98-8.134-22.152c7.304-1.634 15.093-2.97 23.209-3.984a321.524 321.524 0 0 0-7.848 12.897Zm8.081 65.352c-8.385-.936-16.291-2.203-23.593-3.793c2.26-7.3 5.045-14.885 8.298-22.6a321.187 321.187 0 0 0 7.257 13.246c2.594 4.48 5.28 8.868 8.038 13.147Zm37.542 31.03c-5.184-5.592-10.354-11.779-15.403-18.433c4.902.192 9.899.29 14.978.29c5.218 0 10.376-.117 15.453-.343c-4.985 6.774-10.018 12.97-15.028 18.486Zm52.198-57.817c3.422 7.8 6.306 15.345 8.596 22.52c-7.422 1.694-15.436 3.058-23.88 4.071a382.417 382.417 0 0 0 7.859-13.026a347.403 347.403 0 0 0 7.425-13.565Zm-16.898 8.101a358.557 358.557 0 0 1-12.281 19.815a329.4 329.4 0 0 1-23.444.823c-7.967 0-15.716-.248-23.178-.732a310.202 310.202 0 0 1-12.513-19.846h.001a307.41 307.41 0 0 1-10.923-20.627a310.278 310.278 0 0 1 10.89-20.637l-.001.001a307.318 307.318 0 0 1 12.413-19.761c7.613-.576 15.42-.876 23.31-.876H128c7.926 0 15.743.303 23.354.883a329.357 329.357 0 0 1 12.335 19.695a358.489 358.489 0 0 1 11.036 20.54a329.472 329.472 0 0 1-11 20.722Zm22.56-122.124c8.572 4.944 11.906 24.881 6.52 51.026c-.344 1.668-.73 3.367-1.15 5.09c-10.622-2.452-22.155-4.275-34.23-5.408c-7.034-10.017-14.323-19.124-21.64-27.008a160.789 160.789 0 0 1 5.888-5.4c18.9-16.447 36.564-22.941 44.612-18.3ZM128 90.808c12.625 0 22.86 10.235 22.86 22.86s-10.235 22.86-22.86 22.86s-22.86-10.235-22.86-22.86s10.235-22.86 22.86-22.86Z"></path></svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

1
web/src/assets/vite.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.5 KiB

111
web/src/index.css Normal file
View File

@@ -0,0 +1,111 @@
:root {
--text: #6b6375;
--text-h: #08060d;
--bg: #fff;
--border: #e5e4e7;
--code-bg: #f4f3ec;
--accent: #aa3bff;
--accent-bg: rgba(170, 59, 255, 0.1);
--accent-border: rgba(170, 59, 255, 0.5);
--social-bg: rgba(244, 243, 236, 0.5);
--shadow:
rgba(0, 0, 0, 0.1) 0 10px 15px -3px, rgba(0, 0, 0, 0.05) 0 4px 6px -2px;
--sans: system-ui, 'Segoe UI', Roboto, sans-serif;
--heading: system-ui, 'Segoe UI', Roboto, sans-serif;
--mono: ui-monospace, Consolas, monospace;
font: 18px/145% var(--sans);
letter-spacing: 0.18px;
color-scheme: light dark;
color: var(--text);
background: var(--bg);
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
@media (max-width: 1024px) {
font-size: 16px;
}
}
@media (prefers-color-scheme: dark) {
:root {
--text: #9ca3af;
--text-h: #f3f4f6;
--bg: #16171d;
--border: #2e303a;
--code-bg: #1f2028;
--accent: #c084fc;
--accent-bg: rgba(192, 132, 252, 0.15);
--accent-border: rgba(192, 132, 252, 0.5);
--social-bg: rgba(47, 48, 58, 0.5);
--shadow:
rgba(0, 0, 0, 0.4) 0 10px 15px -3px, rgba(0, 0, 0, 0.25) 0 4px 6px -2px;
}
#social .button-icon {
filter: invert(1) brightness(2);
}
}
body {
margin: 0;
}
#root {
width: 1126px;
max-width: 100%;
margin: 0 auto;
text-align: center;
border-inline: 1px solid var(--border);
min-height: 100svh;
display: flex;
flex-direction: column;
box-sizing: border-box;
}
h1,
h2 {
font-family: var(--heading);
font-weight: 500;
color: var(--text-h);
}
h1 {
font-size: 56px;
letter-spacing: -1.68px;
margin: 32px 0;
@media (max-width: 1024px) {
font-size: 36px;
margin: 20px 0;
}
}
h2 {
font-size: 24px;
line-height: 118%;
letter-spacing: -0.24px;
margin: 0 0 8px;
@media (max-width: 1024px) {
font-size: 20px;
}
}
p {
margin: 0;
}
code,
.counter {
font-family: var(--mono);
display: inline-flex;
border-radius: 4px;
color: var(--text-h);
}
code {
font-size: 15px;
line-height: 135%;
padding: 4px 8px;
background: var(--code-bg);
}

10
web/src/main.jsx Normal file
View File

@@ -0,0 +1,10 @@
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.jsx'
createRoot(document.getElementById('root')).render(
<StrictMode>
<App />
</StrictMode>,
)

7
web/vite.config.js Normal file
View File

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