From 05d472189c59b6b81c68a971bcc27cd65a55eea9 Mon Sep 17 00:00:00 2001 From: Zimeng Xiong Date: Sat, 22 Nov 2025 09:45:20 -0800 Subject: [PATCH] New Icon/Logo --- AGENTS.md | 428 ++++++++++++++++++++++++++ DOCKER.md | 115 +------ PUBLISHING.md | 102 ------ README.md | 0 frontend/public/favicon-dark.svg | 66 ++++ frontend/public/favicon-light.svg | 66 ++++ frontend/public/favicon.svg | 99 ++++-- frontend/src/components/Logo.tsx | 155 ++++++++++ frontend/src/components/Sidebar.tsx | 6 +- frontend/src/context/ThemeContext.tsx | 7 + publish-docker.sh | 9 +- 11 files changed, 806 insertions(+), 247 deletions(-) create mode 100644 AGENTS.md delete mode 100644 PUBLISHING.md create mode 100644 README.md create mode 100644 frontend/public/favicon-dark.svg create mode 100644 frontend/public/favicon-light.svg create mode 100644 frontend/src/components/Logo.tsx diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..8658582 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,428 @@ +# ExcaliDash Developer Guide + +## What is ExcaliDash? + +ExcaliDash is a full-stack dashboard application for managing and organizing [Excalidraw](https://excalidraw.com) drawings. It provides a interface for creating, organizing, and collaborating on diagrams with features like collections, real-time collaboration, file import/export, and bulk operations. + +## Project Overview + +### Core Features + +- **Drawing Management**: Create, edit, and organize Excalidraw drawings +- **Collections**: Organize drawings into folders/categories +- **Real-time Collaboration**: Multiple users can edit drawings simultaneously +- **Import/Export**: Support for .excalidraw and .json file formats +- **Bulk Operations**: Multi-select drawings for delete, duplicate, and move operations +- **Search & Sort**: Find drawings by name with sorting by name, created date, or modified date +- **Trash System**: Soft delete with permanent delete option +- **Drag & Drop**: Intuitive file dragging and drawing reordering +- **Dark/Light Theme**: Automatic theme detection with manual toggle + +### Tech Stack + +**Frontend:** + +- React 18 + TypeScript +- Vite (build tool) +- Tailwind CSS (styling) +- Excalidraw (drawing canvas) +- Socket.io Client (real-time features) +- React Router (navigation) +- Lucide React (icons) + +**Backend:** + +- Node.js + Express +- TypeScript +- Prisma ORM +- SQLite database +- Socket.io (real-time server) + +**Infrastructure:** + +- Docker (containerization) +- Docker Compose (multi-container orchestration) + +## Project Structure + +``` +ExcaliDash/ +├── README.md # Project overview +├── AGENTS.md # This file - developer guide +├── DOCKER.md # Docker documentation +├── .gitignore # Git ignore rules +├── .dockerignore # Docker ignore rules +├── docker-compose.yml # Production Docker setup +├── docker-compose.prod.yml # Additional production config +├── publish-docker.sh # Docker deployment script +│ +├── backend/ # Node.js/Express backend +│ ├── src/ +│ │ ├── index.ts # Main server file +│ │ └── generated/ # Prisma generated client +│ ├── prisma/ +│ │ ├── schema.prisma # Database schema +│ │ ├── migrations/ # Database migrations +│ │ └── dev.db # SQLite database (development) +│ ├── package.json # Backend dependencies +│ ├── Dockerfile # Backend container config +│ ├── .env.example # Environment variables template +│ └── docker-entrypoint.sh # Container startup script +│ +└── frontend/ # React frontend application + ├── src/ + │ ├── components/ # Reusable UI components + │ ├── pages/ # Route components + │ ├── hooks/ # Custom React hooks + │ ├── context/ # React context providers + │ ├── types/ # TypeScript type definitions + │ ├── utils/ # Utility functions + │ ├── api/ # API client functions + │ └── assets/ # Static assets + ├── public/ # Public assets + ├── package.json # Frontend dependencies + ├── Dockerfile # Frontend container config + ├── vite.config.ts # Vite configuration + ├── tailwind.config.js # Tailwind CSS configuration + └── nginx.conf # Nginx configuration for production +``` + +## Getting Started + +### Prerequisites + +- Node.js 18+ and npm +- Docker and Docker Compose (for containerized development) +- Git + +### Development Setup + +#### Option 1: Local Development (Recommended) + +1. **Install Backend Dependencies** + + ```bash + cd backend + npm install + ``` + +2. **Install Frontend Dependencies** + + ```bash + cd ../frontend + npm install + ``` + +3. **Setup Environment Variables** + + ```bash + cd ../backend + cp .env.example .env + # Edit .env if needed + ``` + +4. **Initialize Database** + + ```bash + npx prisma generate + npx prisma db push + ``` + +5. **Start Backend Development Server** + + ```bash + cd backend + npm run dev + # Server runs on http://localhost:8000 + ``` + +6. **Start Frontend Development Server** (in a new terminal) + ```bash + cd frontend + npm run dev + # Frontend runs on http://localhost:5173 + ``` + +### Environment Variables + +**Backend (.env):** + +```bash +DATABASE_URL="file:./prisma/dev.db" +PORT=8000 +NODE_ENV=development +``` + +**Frontend (.env.example):** + +```bash +VITE_API_URL=http://localhost:8000 +``` + +## Making Changes + +### Development Workflow + +1. **Create a Feature Branch** + + ```bash + git checkout -b feature/your-feature-name + ``` + +2. **Make Your Changes** + + - Follow the existing code style and patterns + - Add TypeScript types for new features + - Update database schema if needed (see Database section) + +3. **Test Your Changes** + + - Test both locally and with Docker + - Check that existing functionality still works + +4. **Commit and Push** + ```bash + git add . + git commit -m "feat: add your feature description" + git push origin feature/your-feature-name + ``` + +### Code Style and Standards + +- **TypeScript**: Use strict TypeScript typing +- **Component Structure**: Follow the existing component patterns in `frontend/src/components/` +- **API Design**: RESTful endpoints in `backend/src/index.ts` +- **Database**: Use Prisma migrations for schema changes +- **Styling**: Tailwind CSS classes with the existing design system + +### File Organization Guidelines + +- **Frontend Components**: Keep related components together +- **Custom Hooks**: Place in `frontend/src/hooks/` +- **Utilities**: Place in `frontend/src/utils/` +- **API Routes**: Add to `backend/src/index.ts` +- **Database Models**: Update `backend/prisma/schema.prisma` + +## Database + +### Schema Overview + +The application uses two main models: + +**Collection:** + +- `id` (String, UUID) - Primary key +- `name` (String) - Collection name +- `drawings` (Relation) - Related drawings +- `createdAt`, `updatedAt` (DateTime) - Timestamps + +**Drawing:** + +- `id` (String, UUID) - Primary key +- `name` (String) - Drawing name +- `elements` (String, JSON) - Excalidraw elements +- `appState` (String, JSON) - Excalidraw application state +- `files` (String, JSON) - Associated files +- `preview` (String, SVG) - Thumbnail preview +- `version` (Int) - Version number for conflict detection +- `collectionId` (String, nullable) - Foreign key to Collection +- `createdAt`, `updatedAt` (DateTime) - Timestamps + +### Making Database Changes + +1. **Modify the Schema** + Edit `backend/prisma/schema.prisma` + +2. **Create a Migration** + + ```bash + cd backend + npx prisma migrate dev --name your_migration_name + ``` + +3. **Update TypeScript Types** + + ```bash + npx prisma generate + ``` + +4. **Test the Changes** + ```bash + npx prisma db push # Apply to development database + ``` + +### Database Commands + +```bash +# Generate Prisma client +npx prisma generate + +# Create and apply migration +npx prisma migrate dev --name migration_name + +# Reset database (development only) +npx prisma migrate reset + +# View database in Prisma Studio +npx prisma studio + +# Deploy migrations to production +npx prisma migrate deploy +``` + +## API Documentation + +### Base URL + +- Development: `http://localhost:8000` +- Production: Configured via environment variables + +### Endpoints + +#### Drawings + +- `GET /drawings` - List drawings (supports search and collection filtering) +- `GET /drawings/:id` - Get single drawing +- `POST /drawings` - Create new drawing +- `PUT /drawings/:id` - Update drawing +- `DELETE /drawings/:id` - Delete drawing permanently +- `POST /drawings/:id/duplicate` - Duplicate drawing + +#### Collections + +- `GET /collections` - List all collections +- `POST /collections` - Create new collection +- `PUT /collections/:id` - Update collection +- `DELETE /collections/:id` - Delete collection (moves drawings to unorganized) + +#### System + +- `GET /health` - Health check endpoint + +### Real-time Events (Socket.io) + +#### Client → Server + +- `join-room` - Join drawing room for collaboration +- `cursor-move` - Broadcast cursor position +- `element-update` - Broadcast drawing changes +- `user-activity` - Update user active status + +#### Server → Client + +- `presence-update` - User presence in room +- `cursor-move` - Other user's cursor position +- `element-update` - Other user's drawing changes + +### Environment Setup + +**Production Environment Variables:** + +- `DATABASE_URL` - SQLite database path +- `PORT` - Backend server port +- `NODE_ENV` - Set to "production" + +## Troubleshooting + +### Common Issues + +1. **Database Connection Error** + + - Check that the database file exists in `backend/prisma/dev.db` + - Ensure proper permissions on the database file + - Verify DATABASE_URL in .env + +2. **Prisma Client Issues** + + - Run `npx prisma generate` to regenerate client + - Clear `node_modules` and reinstall dependencies + +3. **Port Already in Use** + + - Change PORT in backend/.env + - Update frontend API URL accordingly + +4. **Docker Build Failures** + + - Check Dockerfile syntax + - Ensure all dependencies are listed in package.json + - Verify build context in docker-compose.yml + +5. **Frontend Not Loading** + - Check browser console for errors + - Verify API_URL in frontend environment + - Check network connectivity to backend + +## Architecture Details + +### Frontend Architecture + +The frontend follows a component-based architecture with: + +- **Pages**: Route-level components (`src/pages/`) +- **Components**: Reusable UI components (`src/components/`) +- **Hooks**: Custom React hooks for state management (`src/hooks/`) +- **Context**: Global state providers (`src/context/`) +- **Utils**: Utility functions (`src/utils/`) + +Key patterns: + +- State management using React hooks and context +- API calls centralized in `src/api/` +- TypeScript for type safety throughout +- Tailwind CSS for styling with custom design tokens + +### Backend Architecture + +The backend follows a traditional MVC pattern: + +- **Routes**: API endpoints in `src/index.ts` +- **Models**: Prisma schema definitions +- **Services**: Business logic (can be extracted to separate files) +- **Middleware**: CORS, JSON parsing, etc. + +Real-time features: + +- Socket.io for WebSocket connections +- Room-based collaboration +- Presence tracking +- Cursor position broadcasting + +### Data Flow + +1. **Drawing Creation**: Frontend → API → Database +2. **Real-time Updates**: Frontend → Socket.io → Other Frontends +3. **Data Persistence**: Regular API calls for saving state +4. **File Management**: Frontend → API → Database (as JSON) + +## Contributing + +### Pull Request Process + +1. **Ensure all tests pass** +2. **Update documentation** if needed +3. **Add commit messages** following conventional commits +4. **Request review** from maintainers + +### Commit Message Format + +``` +type(scope): description + +feat(auth): add user authentication +fix(editor): resolve drawing save issue +docs(api): update endpoint documentation +``` + +Types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore` + +## Resources + +- [Excalidraw Documentation](https://docs.excalidraw.com/) +- [Prisma Documentation](https://www.prisma.io/docs/) +- [React Documentation](https://react.dev/) +- [Socket.io Documentation](https://socket.io/docs/) +- [Tailwind CSS Documentation](https://tailwindcss.com/docs) +- [Vite Documentation](https://vitejs.dev/guide/) + +_This documentation is maintained alongside the codebase. Please update it when making significant architectural changes._ diff --git a/DOCKER.md b/DOCKER.md index 8d4c540..c2d9ec2 100644 --- a/DOCKER.md +++ b/DOCKER.md @@ -37,7 +37,7 @@ docker compose up -d --build ### Access the application: -Open your browser to `http://localhost:6767` +[http://localhost:6767](http://localhost:6767) ## Publishing to Docker Hub @@ -53,80 +53,6 @@ The `publish-docker.sh` script builds images for multiple platforms (amd64, arm6 ./publish-docker.sh v1.0.0 ``` -**Prerequisites:** - -- Docker Buildx enabled -- Logged in to Docker Hub: `docker login` - -**Platforms supported:** - -- `linux/amd64` (Intel/AMD x86_64) -- `linux/arm64` (Apple Silicon, ARM servers) - -The script will: - -1. Create a buildx builder if needed -2. Build both frontend and backend images for all platforms -3. Push to `zimengxiong/excalidash-backend` and `zimengxiong/excalidash-frontend` -4. Tag with both the specified version and `latest` - -## Management Commands - -### View logs: - -```bash -# All services -docker compose logs -f - -# Specific service -docker compose logs -f backend -docker compose logs -f frontend -``` - -### Stop services: - -```bash -docker compose down -``` - -### Stop and remove volumes (clean slate): - -```bash -docker compose down -v -``` - -### Restart services: - -```bash -docker compose restart -``` - -### Check service status: - -```bash -docker compose ps -``` - -## Development - -For local development outside Docker, use the existing npm scripts: - -**Backend:** - -```bash -cd backend -npm install -npm run dev -``` - -**Frontend:** - -```bash -cd frontend -npm install -npm run dev -``` - ## Database The SQLite database is stored in a Docker volume named `backend-data` which persists data across container restarts. Database migrations run automatically when the backend container starts. @@ -150,45 +76,6 @@ NODE_ENV=production VITE_API_URL=/api ``` -## Troubleshooting - -### Check health status: - -```bash -docker-compose ps -``` - -Both services should show "healthy" status. - -### Reset database: - -```bash -docker-compose down -v -docker-compose up -d -``` - -### View detailed backend logs: - -```bash -docker-compose logs backend -``` - -### Rebuild specific service: - -```bash -docker-compose up -d --build backend -``` - -## Production Deployment - -For production deployment: - -1. Use proper environment variables -2. Configure proper CORS settings in the backend -3. Add HTTPS/TLS termination (e.g., via reverse proxy like Traefik or nginx) -4. Consider using PostgreSQL instead of SQLite for better concurrency -5. Set up proper backup strategy for the `backend-data` volume - ## Port Mapping - **6767** (external) → **80** (frontend nginx) → Routes to backend on internal network diff --git a/PUBLISHING.md b/PUBLISHING.md deleted file mode 100644 index 9ad9b8a..0000000 --- a/PUBLISHING.md +++ /dev/null @@ -1,102 +0,0 @@ -# Publishing Docker Images - -This document explains how to build and publish multi-platform Docker images for ExcaliDash. - -## Quick Start - -```bash -# Login to Docker Hub (if not already logged in) -docker login - -# Build and push images -./publish-docker.sh -``` - -## Usage - -```bash -./publish-docker.sh [VERSION] -``` - -**Arguments:** - -- `VERSION` (optional): The version tag for the images. Defaults to `latest`. - -**Examples:** - -```bash -# Build and push with 'latest' tag -./publish-docker.sh - -# Build and push with version tag -./publish-docker.sh v1.0.0 -./publish-docker.sh 2024.11.21 -``` - -## What It Does - -1. **Checks Docker Hub authentication** - Ensures you're logged in -2. **Sets up buildx builder** - Creates or uses existing multi-platform builder -3. **Builds backend image** - For linux/amd64 and linux/arm64 platforms -4. **Builds frontend image** - For linux/amd64 and linux/arm64 platforms -5. **Pushes to Docker Hub** - Uploads to `zimengxiong/excalidash-backend` and `zimengxiong/excalidash-frontend` - -## Supported Platforms - -- **linux/amd64** - Intel/AMD x86_64 processors (most servers, PCs) -- **linux/arm64** - ARM 64-bit processors (Apple Silicon, ARM servers, Raspberry Pi 4+) - -## Requirements - -- Docker with buildx support (Docker Desktop or Docker Engine 19.03+) -- Docker Hub account credentials -- Internet connection for pushing images - -## Troubleshooting - -### "buildx" is not a docker command - -Update Docker to a newer version that includes buildx, or install the buildx plugin. - -### Authentication error - -Run `docker login` and enter your Docker Hub credentials. - -### Build fails on specific platform - -You can modify the script to build for only one platform: - -```bash -# In publish-docker.sh, change: ---platform linux/amd64,linux/arm64 -# to: ---platform linux/amd64 -``` - -## Using Published Images - -After publishing, users can run ExcaliDash using the pre-built images: - -```bash -# Using production compose file (no build step needed) -docker compose -f docker-compose.prod.yml up -d - -# Or using regular compose file (will pull if not building) -docker compose pull -docker compose up -d -``` - -## CI/CD Integration - -You can integrate this script into your CI/CD pipeline: - -```yaml -# Example GitHub Actions workflow -- name: Build and Push Docker Images - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - run: | - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin - ./publish-docker.sh ${{ github.ref_name }} -``` diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/frontend/public/favicon-dark.svg b/frontend/public/favicon-dark.svg new file mode 100644 index 0000000..bd94660 --- /dev/null +++ b/frontend/public/favicon-dark.svg @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/frontend/public/favicon-light.svg b/frontend/public/favicon-light.svg new file mode 100644 index 0000000..1dcfcc2 --- /dev/null +++ b/frontend/public/favicon-light.svg @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/frontend/public/favicon.svg b/frontend/public/favicon.svg index ed907de..6de26af 100644 --- a/frontend/public/favicon.svg +++ b/frontend/public/favicon.svg @@ -1,20 +1,81 @@ - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/frontend/src/components/Logo.tsx b/frontend/src/components/Logo.tsx new file mode 100644 index 0000000..3832311 --- /dev/null +++ b/frontend/src/components/Logo.tsx @@ -0,0 +1,155 @@ +import React from 'react'; + +export const Logo: React.FC<{ className?: string }> = ({ className }) => { + return ( + + + + + + + + + + + + + + + {/* Group: The Dashboard Grid (2x2) */} + + {/* Top Left: Bar Chart */} + + + + + {/* Top Right: Pie Chart */} + + + {/* Slice */} + + {/* Bottom Left: List/Text */} + + + + + {/* Bottom Right: The "Creation" Zone */} + {/* Dashed placeholder for the item being created */} + + + {/* The Pencil (Floating over the bottom right) */} + + {/* Body */} + + {/* Eraser */} + + {/* Collar */} + + {/* Tip Lead */} + + + + ); +}; diff --git a/frontend/src/components/Sidebar.tsx b/frontend/src/components/Sidebar.tsx index c63ce0a..c8662c2 100644 --- a/frontend/src/components/Sidebar.tsx +++ b/frontend/src/components/Sidebar.tsx @@ -1,10 +1,10 @@ - import React, { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { LayoutGrid, Folder, Plus, Trash2, Edit2, Archive, FolderOpen, Settings as SettingsIcon } from 'lucide-react'; import type { Collection } from '../types'; import clsx from 'clsx'; import { ConfirmModal } from './ConfirmModal'; +import { Logo } from './Logo'; interface SidebarProps { collections: Collection[]; @@ -169,9 +169,7 @@ export const Sidebar: React.FC = ({

-
- -
+ ExcaliDash

diff --git a/frontend/src/context/ThemeContext.tsx b/frontend/src/context/ThemeContext.tsx index a4d610d..71bb076 100644 --- a/frontend/src/context/ThemeContext.tsx +++ b/frontend/src/context/ThemeContext.tsx @@ -18,6 +18,13 @@ export const ThemeProvider: React.FC<{ children: React.ReactNode }> = ({ childre useEffect(() => { console.log('Theme changed to:', theme); localStorage.setItem('theme', theme); + + // Update favicon + const link = document.querySelector("link[rel~='icon']") as HTMLLinkElement; + if (link) { + link.href = theme === 'dark' ? '/favicon-dark.svg' : '/favicon-light.svg'; + } + if (theme === 'dark') { document.documentElement.classList.add('dark'); console.log('Added dark class, classList:', document.documentElement.classList.toString()); diff --git a/publish-docker.sh b/publish-docker.sh index 8990bac..2ada6ef 100755 --- a/publish-docker.sh +++ b/publish-docker.sh @@ -62,16 +62,9 @@ docker buildx build \ echo -e "${GREEN}✓ Frontend image pushed successfully${NC}" -# Summary + echo "" echo -e "${GREEN}===========================================${NC}" echo -e "${GREEN}✓ All images published successfully!${NC}" echo -e "${GREEN}===========================================${NC}" echo "" -echo -e "Published images:" -echo -e " Backend: ${YELLOW}$DOCKER_USERNAME/$IMAGE_NAME-backend:$VERSION${NC}" -echo -e " Frontend: ${YELLOW}$DOCKER_USERNAME/$IMAGE_NAME-frontend:$VERSION${NC}" -echo "" -echo -e "To use these images:" -echo -e " ${YELLOW}docker compose -f docker-compose.prod.yml up -d${NC}" -echo ""