diff --git a/README.md b/README.md index 53fbb34..2e81d24 100644 --- a/README.md +++ b/README.md @@ -1,208 +1,148 @@ -# Spanglish - Language Exchange Event Platform +# Spanglish — Language Exchange Event Platform -A full-stack web application for organizing and managing language exchange events in Asunción, Paraguay. +A full-stack web app for organizing and managing language exchange events (Asunción, Paraguay). ## Features -### Public Website -- **Homepage** - Hero section with next event, about section, newsletter signup -- **Events** - Browse upcoming and past events, view event details -- **Booking** - Book tickets for events with payment options -- **Community** - WhatsApp and social media links, community guidelines -- **Contact** - Contact form for inquiries -- **Multi-language** - English and Spanish support with easy extensibility +- **Public site**: events, booking, contact, community, legal pages, bilingual (EN/ES) +- **User dashboard**: profile, tickets, payments, sessions/security +- **Admin** (`/admin`): events, tickets/check-in, users/roles, payments, email templates, media uploads +- **API**: Swagger UI at `/api-docs`, OpenAPI JSON at `/openapi.json`, health check at `/health` -### Admin Dashboard (`/admin`) -- **Dashboard** - Overview stats, alerts, quick actions -- **Events** - Create, edit, publish, and manage events -- **Tickets** - View bookings, check-in attendees, manage ticket status -- **Users** - Manage user accounts and roles -- **Payments** - View and confirm payments, process refunds -- **Messages** - View and respond to contact form submissions +## Tech stack -### API -- **API Docs** - Swagger UI at `/api-docs` -- **OpenAPI Spec** - JSON specification at `/openapi.json` -- Full REST API with JWT authentication +- **Backend**: Node.js + TypeScript, Hono, Drizzle ORM, SQLite (default) or PostgreSQL +- **Auth**: JWT (via `jose`), **Argon2id** password hashing (with legacy bcrypt verification for older hashes) +- **Email**: `nodemailer` (SMTP) with optional provider config +- **Frontend**: Next.js 14 (App Router), Tailwind CSS, SWR, Heroicons -## Tech Stack - -### Backend -- **Runtime**: Node.js with TypeScript -- **Framework**: Hono (fast, lightweight) -- **Database**: SQLite (default) or PostgreSQL -- **ORM**: Drizzle ORM -- **Authentication**: JWT with bcrypt password hashing -- **API Documentation**: OpenAPI 3.0 / Swagger UI - -### Frontend -- **Framework**: Next.js 14 (App Router) -- **Styling**: Tailwind CSS -- **Icons**: Heroicons -- **State Management**: React Context -- **HTTP Client**: SWR / Fetch API -- **Notifications**: React Hot Toast - -## Getting Started +## Local development ### Prerequisites + - Node.js 18+ -- npm or yarn +- npm -### Installation +### Setup -1. Clone the repository: -```bash -git clone -cd Spanglish -``` - -2. Install dependencies: ```bash npm install -``` - -3. Set up environment variables: -```bash -# Backend cp backend/.env.example backend/.env -# Edit backend/.env with your settings +cp frontend/.env.example frontend/.env ``` -4. Initialize the database: +### Initialize database (SQLite by default) + ```bash npm run db:migrate ``` -5. Start the development servers: +### Run + ```bash npm run dev ``` -The application will be available at: -- Frontend: http://localhost:3002 -- Backend API: http://localhost:3001 -- API Docs: http://localhost:3001/api-docs +Default URLs: -### First User = Admin +- Frontend: `http://localhost:3002` +- Backend API: `http://localhost:3001` +- API docs: `http://localhost:3001/api-docs` -The first user to register becomes the admin. Register at `/register` to create the admin account. +### First user becomes admin -## Database Configuration +The first user to register becomes the **admin**. Register at `/register`. -### SQLite (Default) -No additional configuration needed. Database file is created at `backend/data/spanglish.db`. +## Useful scripts (workspace) + +Run these from the repo root: + +```bash +npm run dev +npm run build +npm run start +npm run db:generate +npm run db:migrate +npm run db:studio +``` + +You can also run per workspace: + +```bash +npm run dev --workspace=backend +npm run dev --workspace=frontend +``` + +## Environment variables + +### Backend (`backend/.env`) + +Key settings (see `backend/.env.example` for the full list): + +- **DB**: `DB_TYPE=sqlite|postgres`, `DATABASE_URL=./data/spanglish.db` (or Postgres URL) +- **Auth**: `JWT_SECRET` (change in production) +- **URLs/ports**: `PORT`, `API_URL`, `FRONTEND_URL` +- **Email**: `EMAIL_PROVIDER` (`console|smtp|resend`) and corresponding credentials +- **Payments (optional)**: Stripe/MercadoPago/LNbits configuration + +### Frontend (`frontend/.env`) + +Key settings (see `frontend/.env.example`): + +- **Server port**: `PORT=3002` +- **API base URL**: `NEXT_PUBLIC_API_URL` (optional) + - Leave empty to use same-origin `/api` (recommended when running behind nginx) + - In local dev, Next.js rewrites `/api/*` and `/uploads/*` to the backend +- **Social links (optional)**: `NEXT_PUBLIC_WHATSAPP`, `NEXT_PUBLIC_INSTAGRAM`, etc. + +## Database + +### SQLite (default) + +- DB file defaults to `backend/data/spanglish.db` (via `DATABASE_URL=./data/spanglish.db`) +- Run migrations with `npm run db:migrate` ### PostgreSQL -Update `backend/.env`: + +Set in `backend/.env`: + ```env DB_TYPE=postgres DATABASE_URL=postgresql://user:password@localhost:5432/spanglish ``` -## Project Structure +Then run: -``` -Spanglish/ -├── backend/ -│ ├── src/ -│ │ ├── db/ # Database schema and migrations -│ │ ├── lib/ # Utilities (auth, helpers) -│ │ ├── routes/ # API routes -│ │ └── index.ts # Server entry point -│ └── drizzle.config.ts -├── frontend/ -│ ├── src/ -│ │ ├── app/ # Next.js pages -│ │ │ ├── (public)/ # Public pages -│ │ │ └── admin/ # Admin dashboard -│ │ ├── components/ # React components -│ │ ├── context/ # React contexts -│ │ ├── i18n/ # Internationalization -│ │ └── lib/ # API client, utilities -│ └── tailwind.config.js -└── package.json # Monorepo workspace config +```bash +npm run db:migrate ``` -## Adding New Languages +## Production deployment (nginx + systemd) -The i18n system is designed for easy extensibility: +This repo includes example configs in `deploy/`: -1. Create a new locale file at `frontend/src/i18n/locales/{code}.json` -2. Copy structure from `en.json` and translate -3. Update `frontend/src/i18n/index.ts`: +- **systemd**: `deploy/spanglish-backend.service`, `deploy/spanglish-frontend.service` + - Backend runs on **3018**, frontend on **3019** by default (see the unit files) + - Backend needs write access to `backend/data` and `backend/uploads` +- **nginx**: + - `deploy/spanglish_upstreams.conf` defines upstreams for ports 3018/3019 + - `deploy/front-end_nginx.conf` proxies `/api` and `/uploads` to the backend and everything else to the frontend + - `deploy/back-end_nginx.conf` is a dedicated API vhost example with CORS handling -```typescript -import pt from './locales/pt.json'; +Typical production flow: -export type Locale = 'en' | 'es' | 'pt'; - -export const locales: Record = { - en, - es, - pt, // Add new locale -}; - -export const localeNames: Record = { - en: 'English', - es: 'Español', - pt: 'Português', // Add display name -}; - -export const localeFlags: Record = { - en: '🇺🇸', - es: '🇪🇸', - pt: '🇧🇷', // Add flag -}; +```bash +npm ci +npm run build +npm run db:migrate ``` -## API Endpoints +Then install/enable the systemd services and nginx configs for your server. -### Authentication -- `POST /api/auth/register` - Register new user -- `POST /api/auth/login` - Login -- `GET /api/auth/me` - Get current user +## Documentation -### Events -- `GET /api/events` - List events -- `GET /api/events/:id` - Get event -- `POST /api/events` - Create event (admin) -- `PUT /api/events/:id` - Update event (admin) -- `DELETE /api/events/:id` - Delete event (admin) - -### Tickets -- `POST /api/tickets` - Book ticket -- `GET /api/tickets/:id` - Get ticket -- `POST /api/tickets/:id/checkin` - Check in (staff) - -### Users -- `GET /api/users` - List users (admin) -- `PUT /api/users/:id` - Update user - -### Payments -- `GET /api/payments` - List payments (admin) -- `PUT /api/payments/:id` - Update payment status -- `POST /api/payments/:id/refund` - Process refund - -### Contacts -- `POST /api/contacts` - Submit contact form -- `POST /api/contacts/subscribe` - Subscribe to newsletter - -## User Roles - -- **admin** - Full access to all features -- **organizer** - Manage events, tickets, view payments -- **staff** - Check-in attendees, view ticket info -- **marketing** - Access to subscriber lists, analytics -- **user** - Public user, can book events - -## Brand Colors - -- Primary Yellow: `#FFD84D` -- Primary Dark: `#111111` -- Primary White: `#FFFFFF` -- Secondary Gray: `#F5F5F5` -- Accent Blue: `#2F80ED` +- **Specs / notes**: `about/` +- **Legal docs**: `frontend/legal/` ## License