Merge branch 'main' of https://github.com/devaine/CodeRED-Astra
This commit is contained in:
commit
5a9da85f07
31 changed files with 2831 additions and 54 deletions
39
.dockerignore
Normal file
39
.dockerignore
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
# Node modules
|
||||||
|
node_modules
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# Build outputs
|
||||||
|
dist
|
||||||
|
build
|
||||||
|
target
|
||||||
|
|
||||||
|
# Environment files
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.vscode
|
||||||
|
.idea
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Git
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
|
||||||
|
# Documentation
|
||||||
|
README.md
|
||||||
|
DEVELOPMENT.md
|
||||||
|
*.md
|
||||||
|
|
||||||
|
# Scripts
|
||||||
|
setup-check.ps1
|
||||||
14
.env.example
Normal file
14
.env.example
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
# .env.example
|
||||||
|
|
||||||
|
# --- PLEASE FILL THIS OUT WITH THE SECURELY PROVIDED CREDENTIALS ---
|
||||||
|
|
||||||
|
# Application Database Credentials
|
||||||
|
MYSQL_DATABASE=astra
|
||||||
|
MYSQL_USER=astraadmin
|
||||||
|
MYSQL_PASSWORD=
|
||||||
|
|
||||||
|
# MySQL Container Root Password (for first-time setup only, not used by the app)
|
||||||
|
MYSQL_ROOT_PASSWORD=
|
||||||
|
|
||||||
|
# API Keys
|
||||||
|
GEMINI_API_KEY=
|
||||||
88
.github/workflows/build-and-deploy.yml
vendored
88
.github/workflows/build-and-deploy.yml
vendored
|
|
@ -1,56 +1,80 @@
|
||||||
# For information on GITHUB_TOKEN: https://docs.github.com/en/actions/concepts/security/github_token
|
# .github/workflows/build-and-deploy.yml
|
||||||
# For information on github.actor: https://github.com/orgs/community/discussions/62108
|
|
||||||
|
|
||||||
name: Build and Deploy
|
name: Build and Deploy
|
||||||
|
|
||||||
|
# This workflow runs only on pushes to the 'main' branch
|
||||||
on:
|
on:
|
||||||
pull_request:
|
|
||||||
branches: ["main"]
|
|
||||||
push:
|
push:
|
||||||
branches: ["main"]
|
branches: ["main"]
|
||||||
|
|
||||||
env:
|
|
||||||
CONTAINER_NAME: codered-astra
|
|
||||||
CONTAINER_TAG: ghcr.io/${{ github.repository_owner }}/codered-astra:latest
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
# Set permissions for the job
|
build-and-deploy:
|
||||||
build:
|
# Set permissions for the job to read contents and write to GitHub Packages
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
packages: write
|
packages: write
|
||||||
attestations: write
|
|
||||||
id-token: write
|
|
||||||
|
|
||||||
name: Build Docker Image
|
name: Build Images and Deploy to Server
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Login to Docker Hub
|
- name: Log in to GitHub Container Registry
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.actor }} # User that commits
|
username: ${{ github.actor }}
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
# --- NEW STEP TO FIX THE CACHING ERROR ---
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
- name: Build and push
|
- name: Extract metadata (tags, labels) for Docker
|
||||||
uses: docker/build-push-action@v6
|
id: meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
with:
|
with:
|
||||||
context: .
|
images: |
|
||||||
platforms: linux/amd64
|
ghcr.io/${{ github.repository }}/web-app
|
||||||
push: true
|
ghcr.io/${{ github.repository }}/rust-engine
|
||||||
tags: ${{ env.CONTAINER_TAG }}
|
|
||||||
|
|
||||||
# WIP: For deployment
|
# --- Build and push one image for each service ---
|
||||||
deploy:
|
- name: Build and push web-app image 🚀
|
||||||
name: Deploy Docker Image to Server
|
uses: docker/build-push-action@v6
|
||||||
runs-on: self-hosted
|
with:
|
||||||
needs: build
|
context: ./web-app
|
||||||
steps:
|
push: true
|
||||||
|
tags: ${{ steps.meta.outputs.tags_web-app }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels_web-app }}
|
||||||
|
cache-from: type=gha
|
||||||
|
cache-to: type=gha,mode=max
|
||||||
|
|
||||||
|
- name: Build and push Rust engine image ⚙️
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: ./rust-engine
|
||||||
|
push: true
|
||||||
|
tags: ${{ steps.meta.outputs.tags_rust-engine }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels_rust-engine }}
|
||||||
|
cache-from: type=gha
|
||||||
|
cache-to: type=gha,mode=max
|
||||||
|
|
||||||
|
# --- Deploy the new images to your server ---
|
||||||
|
- name: Deploy to server via SSH ☁️
|
||||||
|
uses: appleboy/ssh-action@v1.0.3
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.SERVER_HOST }}
|
||||||
|
username: ${{ secrets.SERVER_USERNAME }}
|
||||||
|
key: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||||
|
script: |
|
||||||
|
cd /var/www/codered-astra
|
||||||
|
export GEMINI_API_KEY='${{ secrets.GEMINI_API_KEY }}'
|
||||||
|
export MYSQL_DATABASE='${{ secrets.MYSQL_DATABASE }}'
|
||||||
|
export MYSQL_USER='${{ secrets.MYSQL_USER }}'
|
||||||
|
export MYSQL_PASSWORD='${{ secrets.MYSQL_PASSWORD }}'
|
||||||
|
export MYSQL_ROOT_PASSWORD='${{ secrets.MYSQL_ROOT_PASSWORD }}'
|
||||||
|
export IMAGE_TAG=${{ github.sha }}
|
||||||
|
docker-compose pull
|
||||||
|
docker-compose up -d --force-recreate
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -21,6 +21,9 @@ dist
|
||||||
turbo-build.log
|
turbo-build.log
|
||||||
turbo-host.log
|
turbo-host.log
|
||||||
|
|
||||||
|
# rust
|
||||||
|
rust-engine/target
|
||||||
|
|
||||||
# debug
|
# debug
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
yarn-debug.log*
|
yarn-debug.log*
|
||||||
|
|
|
||||||
77
README.md
77
README.md
|
|
@ -1,16 +1,75 @@
|
||||||
# React + Vite
|
# CodeRED-Astra 🚀
|
||||||
|
|
||||||
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
|
A hackathon-ready project with React frontend and Rust backend engine.
|
||||||
|
|
||||||
Currently, two official plugins are available:
|
## Quick Start
|
||||||
|
|
||||||
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh
|
```bash
|
||||||
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
|
# 1. Setup environment
|
||||||
|
cp .env.example .env
|
||||||
|
# Edit .env with your credentials
|
||||||
|
|
||||||
## React Compiler
|
# 2. Start everything with Docker
|
||||||
|
docker-compose up --build
|
||||||
|
|
||||||
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).
|
# 3. Access your app
|
||||||
|
# Frontend: http://localhost
|
||||||
|
# API: http://localhost:8000
|
||||||
|
# Database Admin: http://127.0.0.1:8080
|
||||||
|
```
|
||||||
|
|
||||||
## Expanding the ESLint configuration
|
## Development
|
||||||
|
|
||||||
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.
|
**Frontend (React + Vite)**:
|
||||||
|
```bash
|
||||||
|
cd web-app
|
||||||
|
npm install
|
||||||
|
npm run dev # http://localhost:5173
|
||||||
|
```
|
||||||
|
|
||||||
|
**Backend (Rust)**:
|
||||||
|
```bash
|
||||||
|
cd rust-engine
|
||||||
|
cargo run # http://localhost:8000
|
||||||
|
```
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
- **Frontend**: React 18 + Vite + Tailwind CSS
|
||||||
|
- **Backend**: Rust + Warp + SQLx
|
||||||
|
- **Database**: MySQL 8.0 + phpMyAdmin
|
||||||
|
- **API**: RESTful endpoints with CORS enabled
|
||||||
|
- **Docker**: Full containerization for easy deployment
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
├── web-app/ # React frontend
|
||||||
|
│ ├── src/
|
||||||
|
│ │ ├── App.jsx # Main component
|
||||||
|
│ │ └── main.jsx # Entry point
|
||||||
|
│ └── Dockerfile
|
||||||
|
├── rust-engine/ # Rust backend
|
||||||
|
│ ├── src/
|
||||||
|
│ │ └── main.rs # API server
|
||||||
|
│ └── Dockerfile
|
||||||
|
├── docker-compose.yml # Full stack orchestration
|
||||||
|
└── .env.example # Environment template
|
||||||
|
```
|
||||||
|
|
||||||
|
## Team Workflow
|
||||||
|
|
||||||
|
- **Frontend devs**: Work in `web-app/src/`, use `/api/*` for backend calls
|
||||||
|
- **Backend devs**: Work in `rust-engine/src/`, add endpoints to main.rs
|
||||||
|
- **Database**: Access phpMyAdmin at http://127.0.0.1:8080
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
✅ Hot reload for both frontend and backend
|
||||||
|
✅ Automatic API proxying from React to Rust
|
||||||
|
✅ Database connection with graceful fallback
|
||||||
|
✅ CORS configured for cross-origin requests
|
||||||
|
✅ Production-ready Docker containers
|
||||||
|
✅ Health monitoring and status dashboard
|
||||||
|
|
||||||
|
Ready for your hackathon! See `DEVELOPMENT.md` for detailed setup instructions.
|
||||||
|
|
|
||||||
53
docker-compose.yml
Normal file
53
docker-compose.yml
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
# docker-compose.yml
|
||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
web-app:
|
||||||
|
build:
|
||||||
|
context: ./web-app
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "80:3000"
|
||||||
|
environment:
|
||||||
|
# The connection string remains the same, but points to the 'mysql' service
|
||||||
|
- DATABASE_URL=mysql://${MYSQL_USER}:${MYSQL_PASSWORD}@mysql:3306/${MYSQL_DATABASE}
|
||||||
|
- RUST_ENGINE_URL=http://rust-engine:8000
|
||||||
|
- GEMINI_API_KEY=${GEMINI_API_KEY}
|
||||||
|
depends_on:
|
||||||
|
- mysql # <-- Updated dependency
|
||||||
|
- rust-engine
|
||||||
|
|
||||||
|
rust-engine:
|
||||||
|
build:
|
||||||
|
context: ./rust-engine
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
- DATABASE_URL=mysql://${MYSQL_USER}:${MYSQL_PASSWORD}@mysql:3306/${MYSQL_DATABASE}
|
||||||
|
depends_on:
|
||||||
|
- mysql # <-- Updated dependency
|
||||||
|
|
||||||
|
# --- Key Changes are in this section ---
|
||||||
|
mysql: # <-- Renamed service for clarity
|
||||||
|
image: mysql:8.0 # <-- CHANGED: Using the official MySQL 8.0 image
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
|
||||||
|
- MYSQL_DATABASE=${MYSQL_DATABASE}
|
||||||
|
- MYSQL_USER=${MYSQL_USER}
|
||||||
|
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
|
||||||
|
volumes:
|
||||||
|
- mysql-data:/var/lib/mysql
|
||||||
|
|
||||||
|
phpmyadmin:
|
||||||
|
image: phpmyadmin/phpmyadmin
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
# CHANGED: Binds port 8080 to localhost ONLY.
|
||||||
|
- "127.0.0.1:8080:80"
|
||||||
|
environment:
|
||||||
|
- PMA_HOST=mysql
|
||||||
|
depends_on:
|
||||||
|
- mysql
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
mysql-data: # Renamed volume for clarity (optional but good practice)
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"baseUrl": "src"
|
|
||||||
},
|
|
||||||
"include": [
|
|
||||||
"src"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
2390
rust-engine/Cargo.lock
generated
Normal file
2390
rust-engine/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
17
rust-engine/Cargo.toml
Normal file
17
rust-engine/Cargo.toml
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
[package]
|
||||||
|
name = "rust-engine"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
tokio = { version = "1.0", features = ["full"] }
|
||||||
|
warp = { version = "0.4.2", features = ["server"] }
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde_json = "1.0"
|
||||||
|
sqlx = { version = "0.8.6", features = ["runtime-tokio-rustls", "mysql", "chrono"] }
|
||||||
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
|
tracing = "0.1"
|
||||||
|
tracing-subscriber = "0.3"
|
||||||
|
dotenv = "0.15"
|
||||||
|
cors = "0.1.0"
|
||||||
|
anyhow = "1.0"
|
||||||
30
rust-engine/Dockerfile
Normal file
30
rust-engine/Dockerfile
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
# rust-engine/Dockerfile
|
||||||
|
# --- Stage 1: Builder ---
|
||||||
|
FROM rust:1.82-slim AS builder
|
||||||
|
WORKDIR /usr/src/app
|
||||||
|
|
||||||
|
# Install build dependencies
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
pkg-config \
|
||||||
|
libssl-dev \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Copy Cargo files for dependency caching
|
||||||
|
COPY Cargo.toml Cargo.lock ./
|
||||||
|
# Create a dummy src/main.rs for dependency build
|
||||||
|
RUN mkdir src && echo "fn main() {}" > src/main.rs
|
||||||
|
RUN cargo build --release && rm src/main.rs
|
||||||
|
|
||||||
|
# Copy source code and build
|
||||||
|
COPY src ./src
|
||||||
|
RUN cargo build --release
|
||||||
|
|
||||||
|
# --- Stage 2: Final Image ---
|
||||||
|
FROM debian:bookworm-slim
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
ca-certificates \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
COPY --from=builder /usr/src/app/target/release/rust-engine /usr/local/bin/rust-engine
|
||||||
|
EXPOSE 8000
|
||||||
|
CMD ["rust-engine"]
|
||||||
132
rust-engine/src/main.rs
Normal file
132
rust-engine/src/main.rs
Normal file
|
|
@ -0,0 +1,132 @@
|
||||||
|
use std::env;
|
||||||
|
use warp::Filter;
|
||||||
|
use sqlx::mysql::MySqlPool;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use tracing::{info, warn};
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct HealthResponse {
|
||||||
|
status: String,
|
||||||
|
timestamp: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct ApiResponse<T> {
|
||||||
|
success: bool,
|
||||||
|
data: Option<T>,
|
||||||
|
message: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
// Initialize tracing
|
||||||
|
tracing_subscriber::fmt::init();
|
||||||
|
|
||||||
|
// Load environment variables
|
||||||
|
dotenv::dotenv().ok();
|
||||||
|
|
||||||
|
let database_url = env::var("DATABASE_URL")
|
||||||
|
.unwrap_or_else(|_| "mysql://astraadmin:password@mysql:3306/astra".to_string());
|
||||||
|
|
||||||
|
info!("Starting Rust Engine...");
|
||||||
|
info!("Connecting to database: {}", database_url);
|
||||||
|
|
||||||
|
// Connect to database
|
||||||
|
let pool = match MySqlPool::connect(&database_url).await {
|
||||||
|
Ok(pool) => {
|
||||||
|
info!("Successfully connected to database");
|
||||||
|
pool
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
warn!("Failed to connect to database: {}. Starting without DB connection.", e);
|
||||||
|
// In a hackathon setting, we might want to continue without DB for initial testing
|
||||||
|
return start_server_without_db().await;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// CORS configuration
|
||||||
|
let cors = warp::cors()
|
||||||
|
.allow_any_origin()
|
||||||
|
.allow_headers(vec!["content-type", "authorization"])
|
||||||
|
.allow_methods(vec!["GET", "POST", "PUT", "DELETE", "OPTIONS"]);
|
||||||
|
|
||||||
|
// Health check endpoint
|
||||||
|
let health = warp::path("health")
|
||||||
|
.and(warp::get())
|
||||||
|
.map(|| {
|
||||||
|
let response = HealthResponse {
|
||||||
|
status: "healthy".to_string(),
|
||||||
|
timestamp: chrono::Utc::now().to_rfc3339(),
|
||||||
|
};
|
||||||
|
warp::reply::json(&ApiResponse {
|
||||||
|
success: true,
|
||||||
|
data: Some(response),
|
||||||
|
message: None,
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// API routes - you'll expand these for your hackathon needs
|
||||||
|
let api = warp::path("api")
|
||||||
|
.and(
|
||||||
|
health.or(
|
||||||
|
// Add more routes here as needed
|
||||||
|
warp::path("version")
|
||||||
|
.and(warp::get())
|
||||||
|
.map(|| {
|
||||||
|
warp::reply::json(&ApiResponse {
|
||||||
|
success: true,
|
||||||
|
data: Some("1.0.0"),
|
||||||
|
message: Some("Rust Engine API".to_string()),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
let routes = api
|
||||||
|
.with(cors)
|
||||||
|
.with(warp::log("rust_engine"));
|
||||||
|
|
||||||
|
info!("Rust Engine started on http://0.0.0.0:8000");
|
||||||
|
|
||||||
|
warp::serve(routes)
|
||||||
|
.run(([0, 0, 0, 0], 8000))
|
||||||
|
.await;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn start_server_without_db() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
info!("Starting server in DB-less mode for development");
|
||||||
|
|
||||||
|
let cors = warp::cors()
|
||||||
|
.allow_any_origin()
|
||||||
|
.allow_headers(vec!["content-type", "authorization"])
|
||||||
|
.allow_methods(vec!["GET", "POST", "PUT", "DELETE", "OPTIONS"]);
|
||||||
|
|
||||||
|
let health = warp::path("health")
|
||||||
|
.and(warp::get())
|
||||||
|
.map(|| {
|
||||||
|
let response = HealthResponse {
|
||||||
|
status: "healthy (no db)".to_string(),
|
||||||
|
timestamp: chrono::Utc::now().to_rfc3339(),
|
||||||
|
};
|
||||||
|
warp::reply::json(&ApiResponse {
|
||||||
|
success: true,
|
||||||
|
data: Some(response),
|
||||||
|
message: Some("Running without database connection".to_string()),
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
let routes = warp::path("api")
|
||||||
|
.and(health)
|
||||||
|
.with(cors)
|
||||||
|
.with(warp::log("rust_engine"));
|
||||||
|
|
||||||
|
info!("Rust Engine started on http://0.0.0.0:8000 (DB-less mode)");
|
||||||
|
|
||||||
|
warp::serve(routes)
|
||||||
|
.run(([0, 0, 0, 0], 8000))
|
||||||
|
.await;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
16
web-app/README.md
Normal file
16
web-app/README.md
Normal 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 [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh
|
||||||
|
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
import js from "@eslint/js";
|
import js from "@eslint/js";
|
||||||
import globals from "globals";
|
import globals from "globals";
|
||||||
import reactHooks from "eslint-plugin-react-hooks";
|
|
||||||
import reactRefresh from "eslint-plugin-react-refresh";
|
|
||||||
import { defineConfig, globalIgnores } from "eslint/config";
|
import { defineConfig, globalIgnores } from "eslint/config";
|
||||||
|
|
||||||
export default defineConfig([
|
export default defineConfig([
|
||||||
6
web-app/jsconfig.json
Normal file
6
web-app/jsconfig.json
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": "./"
|
||||||
|
},
|
||||||
|
"include": ["src"]
|
||||||
|
}
|
||||||
0
package-lock.json → web-app/package-lock.json
generated
0
package-lock.json → web-app/package-lock.json
generated
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
|
@ -1,5 +1,9 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
<<<<<<< HEAD:src/app/index.jsx
|
||||||
import ChatLayout from "../components/ui/ChatLayout";
|
import ChatLayout from "../components/ui/ChatLayout";
|
||||||
|
=======
|
||||||
|
import ChatLayout from "src/components/layouts/chat-layout";
|
||||||
|
>>>>>>> cb9cff44215b6de81ed81ef2a1c6abe090fbf1b1:web-app/src/app/index.jsx
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import ChatHeader from "./ChatHeader";
|
import ChatHeader from "src/components/ui/chat/chat-header";
|
||||||
import ChatWindow from "./ChatWindow";
|
import ChatWindow from "src/components/ui/chat/chat-window";
|
||||||
import MessageInput from "./MessageInput";
|
import MessageInput from "src/components/ui/chat/message-input";
|
||||||
|
|
||||||
export default function ChatLayout() {
|
export default function ChatLayout() {
|
||||||
const [messages, setMessages] = useState([
|
const [messages, setMessages] = useState([
|
||||||
Loading…
Add table
Add a link
Reference in a new issue