# Calink **Calink** lets you create and share calendar events with custom reminders using downloadable .ics files. ## Features - πŸ“… Generate valid iCalendar (.ics) files - πŸ”” Customizable reminders (minutes, hours, days, weeks) - πŸ“‹ Event history for quick reuse - ⚑ Reminder templates for common setups - 🌍 Timezone support - 🐳 Docker & Docker Compose ready - ☸️ Kubernetes Helm chart included - 🎨 Modern, responsive UI ## Quick Start ### Local Development #### Backend ```bash cd backend pip install -r requirements.txt python main.py ``` Backend will run on: http://localhost:8000 - API docs: http://localhost:8000/docs - Health check: http://localhost:8000/health #### Frontend ```bash cd frontend npm install npm run dev ``` Frontend will run on: http://localhost:5173 ## Docker Usage ### Build Images ```bash # Build backend docker build -t calink-backend:latest ./backend # Build frontend docker build -t calink-frontend:latest ./frontend ``` ### Run with Docker Compose ```bash docker-compose up -d ``` This will start: - Backend on port 8000 - Frontend on port 80 - Persistent storage volume for SQLite database Access the application at: http://localhost To stop: ```bash docker-compose down ``` To view logs: ```bash docker-compose logs -f ``` ## Kubernetes Deployment ### Using Helm 1. **Install the chart:** ```bash helm install calink ./helm/calink ``` 2. **With custom values:** ```bash helm install calink ./helm/calink -f custom-values.yaml ``` 3. **Upgrade release:** ```bash helm upgrade calink ./helm/calink ``` 4. **Uninstall:** ```bash helm uninstall calink ``` ### Configuration Edit `helm/calink/values.yaml` to customize: - **Images**: Change repository and tags - **Resources**: CPU/memory limits - **Persistence**: Storage size and class - **Ingress**: Domain and TLS settings - **Replicas**: Scale deployments Example custom values: ```yaml backend: image: repository: your-registry/calink-backend tag: v1.0.0 replicas: 2 persistence: size: 5Gi frontend: image: repository: your-registry/calink-frontend tag: v1.0.0 replicas: 3 ingress: enabled: true hosts: - host: calink.yourdomain.com paths: - path: / pathType: Prefix tls: - secretName: calink-tls hosts: - calink.yourdomain.com ``` ## API Endpoints ### Backend API #### Health Check ``` GET /health ``` #### Generate ICS File ``` POST /api/ics Content-Type: application/json { "title": "Team Meeting", "description": "Monthly sync", "location": "Conference Room A", "start_dt": "2026-03-01T10:00:00Z", "end_dt": "2026-03-01T11:00:00Z", "timezone": "UTC", "reminders": [ {"amount": 10, "unit": "minutes"}, {"amount": 1, "unit": "hours"} ] } ``` #### Preview ICS Content ``` POST /api/preview Content-Type: application/json ``` (Same body as `/api/ics`) #### Get History ``` GET /api/history?limit=20 ``` #### Get Specific Event ``` GET /api/history/{event_id} ``` #### Delete Event ``` DELETE /api/history/{event_id} ``` #### Get Templates ``` GET /api/templates ``` #### Create Template ``` POST /api/templates Content-Type: application/json { "name": "Quick Reminders", "reminders": [ {"amount": 10, "unit": "minutes"}, {"amount": 1, "unit": "hours"} ] } ``` #### Delete Template ``` DELETE /api/templates/{template_id} ``` ## Architecture ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Frontend β”‚ β”‚ (React + TypeScript + Tailwind CSS) β”‚ β”‚ Nginx (Port 80) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ /api/* β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Backend β”‚ β”‚ (FastAPI + Python + SQLite) β”‚ β”‚ Port 8000 β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ SQLite Database β”‚ β”‚ /data/app.db (Persistent) β”‚ β”‚ β”‚ β”‚ Tables: β”‚ β”‚ - events_history β”‚ β”‚ - reminder_templates β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ## Environment Variables ### Backend | Variable | Default | Description | |----------|---------|-------------| | `DATABASE_PATH` | `./data/app.db` | Path to SQLite database | ### Frontend | Variable | Default | Description | |----------|---------|-------------| | `VITE_API_BASE_URL` | `/api` | Backend API base URL | For local development, create `frontend/.env.development`: ``` VITE_API_BASE_URL=http://localhost:8000 ``` ## Development ### Backend ```bash cd backend # Install dependencies pip install -r requirements.txt # Run with auto-reload python main.py # Or use uvicorn directly uvicorn main:app --reload --port 8000 ``` ### Frontend ```bash cd frontend # Install dependencies npm install # Run development server npm run dev # Build for production npm run build # Preview production build npm run preview ``` ## Features Guide ### Event Creation 1. Fill in event details (title, description, location) 2. Set start and end date/time 3. Select timezone 4. Add custom reminders or use quick-add buttons 5. Click "Download .ics" to save the calendar file ### History Management - All created events are automatically saved to history - Click "Load" to reuse an event - Click "Delete" to remove from history - View up to 20 recent events ### Template Management - Save current reminder setup as a template - Name your template for easy identification - Apply templates to quickly set reminders - Delete templates you no longer need ## Database Schema ### events_history ```sql CREATE TABLE events_history ( id INTEGER PRIMARY KEY AUTOINCREMENT, created_at TEXT NOT NULL, title TEXT NOT NULL, description TEXT, location TEXT, start_dt TEXT NOT NULL, end_dt TEXT, timezone TEXT NOT NULL, reminders_json TEXT, last_downloaded_at TEXT ); ``` ### reminder_templates ```sql CREATE TABLE reminder_templates ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT UNIQUE NOT NULL, reminders_json TEXT NOT NULL, created_at TEXT NOT NULL ); ``` ## Troubleshooting ### Backend Issues **Port 8000 already in use:** ```bash # Find and kill the process lsof -ti:8000 | xargs kill -9 # Or use a different port uvicorn main:app --port 8001 ``` **Database not found:** - Check DATABASE_PATH environment variable - Ensure /data directory has write permissions - Database is auto-created on first run ### Frontend Issues **Failed to fetch:** - Verify backend is running on port 8000 - Check CORS settings in backend - Verify API_BASE_URL in .env.development **Build fails:** ```bash # Clear cache and reinstall rm -rf node_modules package-lock.json npm install npm run build ``` ### Docker Issues **Cannot connect to backend:** - Ensure both containers are on the same network - Check docker-compose logs - Verify service names match in nginx.conf **Volume permission errors:** ```bash # Change volume permissions docker-compose down docker volume rm ics-generator_calink-data docker-compose up -d ``` ## Contributing 1. Fork the repository 2. Create a feature branch 3. Make your changes 4. Test thoroughly 5. Submit a pull request ## License MIT ## Support For issues and questions: - Check the troubleshooting section - Review API documentation at `/docs` - Open an issue on GitHub --- **Powered by Calink** β€’ FastAPI + React + Tailwind CSS