diff --git a/README.md b/README.md new file mode 100644 index 0000000..edf95c0 --- /dev/null +++ b/README.md @@ -0,0 +1,181 @@ +# Znakovni.hr - Croatian Sign Language Web Application + +A modern web application for learning and using Croatian Sign Language (Hrvatski znakovni jezik). This is a proof-of-concept implementation designed to replicate the functionality of the original Znakovni.hr platform. + +## 🎯 Project Overview + +Znakovni.hr is a comprehensive platform that enables users to: +- **Browse and search** a dictionary of Croatian sign language terms with video demonstrations +- **Build sentences** using a visual sentence builder (Znakopis) +- **Watch video playback** of complete sentences in sign language +- **Save and manage** documents in the cloud +- **Collaborate** through community features and feedback + +## πŸš€ Technology Stack + +### Frontend +- **React 18.2+** with TypeScript +- **Vite 5+** for fast development and building +- **Tailwind CSS 3+** for pixel-perfect styling +- **shadcn/ui** for beautiful, accessible components +- **Zustand** for lightweight state management +- **Plyr** for video playback +- **@dnd-kit** for drag-and-drop functionality +- **React Router v6** for navigation + +### Backend +- **Node.js 20 LTS** with Express.js +- **TypeScript** for type safety +- **Prisma 5+** as ORM with MySQL +- **Passport.js** for authentication (Google, Microsoft, local) +- **Multer** for file uploads + +### Database +- **MySQL 8.0+** with Prisma ORM +- Full-text search capabilities +- Optimized for 1-2 concurrent users (PoC) + +### Storage +- Local filesystem for media storage +- `/uploads` directory structure for videos, icons, and documents + +## πŸ“ Project Structure + +``` +znakovni/ +β”œβ”€β”€ packages/ +β”‚ β”œβ”€β”€ frontend/ # React + Vite application +β”‚ β”‚ β”œβ”€β”€ src/ +β”‚ β”‚ β”‚ β”œβ”€β”€ components/ # Reusable UI components +β”‚ β”‚ β”‚ β”œβ”€β”€ pages/ # Route pages +β”‚ β”‚ β”‚ β”œβ”€β”€ stores/ # Zustand stores +β”‚ β”‚ β”‚ β”œβ”€β”€ lib/ # Utilities and API client +β”‚ β”‚ β”‚ └── types/ # TypeScript types +β”‚ β”‚ └── package.json +β”‚ β”‚ +β”‚ └── backend/ # Express + TypeScript API +β”‚ β”œβ”€β”€ src/ +β”‚ β”‚ β”œβ”€β”€ routes/ # API route handlers +β”‚ β”‚ β”œβ”€β”€ controllers/ # Business logic +β”‚ β”‚ β”œβ”€β”€ middleware/ # Express middleware +β”‚ β”‚ β”œβ”€β”€ services/ # External services +β”‚ β”‚ └── lib/ # Utilities +β”‚ β”œβ”€β”€ prisma/ # Database schema and migrations +β”‚ β”œβ”€β”€ uploads/ # Local file storage +β”‚ └── package.json +β”‚ +β”œβ”€β”€ original/ # Original specifications and screenshots +β”œβ”€β”€ main-plan.md # Detailed implementation plan +β”œβ”€β”€ package.json # Root package.json (workspace) +└── pnpm-workspace.yaml # pnpm workspace configuration +``` + +## πŸ› οΈ Getting Started + +### Prerequisites + +- **Node.js 20 LTS** or higher +- **pnpm** package manager +- **MySQL 8.0+** database server +- **Git** for version control + +### Installation + +1. **Clone the repository** + ```bash + git clone https://git.matijaturk.from.hr/johnny2211/znakovni.hr.git + cd znakovni + ``` + +2. **Install dependencies** + ```bash + pnpm install + ``` + +3. **Configure environment variables** + ```bash + # Backend + cp packages/backend/.env.example packages/backend/.env + # Edit packages/backend/.env with your database credentials and OAuth keys + + # Frontend + cp packages/frontend/.env.example packages/frontend/.env + # Edit packages/frontend/.env with your API URL + ``` + +4. **Set up the database** + ```bash + cd packages/backend + npx prisma migrate dev + npx prisma db seed + cd ../.. + ``` + +5. **Start development servers** + ```bash + pnpm dev + ``` + + This will start: + - Frontend: http://localhost:5173 + - Backend: http://localhost:3000 + +## πŸ“š Key Features + +### 1. Dictionary (Riječi) +- Browse and search Croatian sign language terms +- Filter by word type and CEFR level +- View video demonstrations for each term +- Add words to sentence builder + +### 2. Sentence Builder (Znakopis) +- Build sentences by adding words from the dictionary +- Drag-and-drop to reorder tokens +- Multi-page document support +- Save documents to the cloud + +### 3. Video Sentence Player (Video rečenica) +- Sequential video playback of complete sentences +- Synchronized token highlighting +- Playback controls (play, pause, speed, loop) + +### 4. Cloud Storage (Oblak) +- Save and manage documents +- Share documents with others +- Load documents into the sentence builder + +### 5. Community Features +- Submit comments and feedback +- Report bugs and issues +- Access help documentation + +## πŸ” Authentication + +The application supports multiple authentication methods: +- **Email/Password** - Traditional local authentication +- **Google OAuth** - Sign in with Google account +- **Microsoft OAuth** - Sign in with Microsoft account + +## πŸ“– Documentation + +For detailed implementation information, see: +- **[main-plan.md](./main-plan.md)** - Complete implementation plan with technical specifications +- **[original/project1.md](./original/project1.md)** - Original functional specifications +- **[original/project2.md](./original/project2.md)** - Replication requirements + +## 🚒 Deployment + +See the [Deployment Guide](./main-plan.md#10-deployment-guide-poc) in main-plan.md for detailed deployment instructions. + +## πŸ“„ License + +This project is a proof-of-concept implementation for educational purposes. + +## πŸ‘₯ Contributing + +This is a proof-of-concept project. For questions or suggestions, please use the bug report feature within the application. + +## πŸ™ Acknowledgments + +This project aims to support the Croatian deaf and hard-of-hearing community by providing accessible tools for learning and using Croatian Sign Language. + diff --git a/main-plan.md b/main-plan.md new file mode 100644 index 0000000..37300a0 --- /dev/null +++ b/main-plan.md @@ -0,0 +1,1355 @@ +# Znakovni.hr - Proof of Concept Implementation Plan + +## Executive Summary +This document provides a complete implementation plan for a 1:1 functional and visual replica of the Znakovni.hr Croatian Sign Language web application. This is a proof-of-concept build optimized for 1-2 concurrent users with local storage. + +--- + +## 1. Technology Stack (PoC-Optimized) + +### Frontend +- **Framework**: React 18.2+ with TypeScript +- **Build Tool**: Vite 5+ +- **UI Framework**: Tailwind CSS 3+ (for exact pixel-perfect replication) +- **Component Library**: shadcn/ui (customizable, matches screenshot aesthetics) +- **State Management**: Zustand (lightweight sentence/document state) +- **Video Player**: Plyr (clean, customizable controls) +- **Drag & Drop**: @dnd-kit/core (sentence token reordering) +- **Routing**: React Router v6 +- **HTTP Client**: Axios +- **Forms**: React Hook Form + Zod +- **Icons**: Lucide React (modern, clean icons) + +### Backend +- **Runtime**: Node.js 20 LTS +- **Framework**: Express.js with TypeScript +- **Authentication**: Passport.js (Google OAuth, Microsoft OAuth, local email/password) +- **Session**: express-session with MySQL session store +- **Validation**: Zod (shared with frontend) +- **File Upload**: Multer (for video/image uploads) +- **CORS**: cors middleware + +### Database +- **RDBMS**: MySQL 8.0+ +- **ORM**: Prisma 5+ (type-safe, excellent MySQL support) +- **Migrations**: Prisma Migrate +- **Full-Text Search**: MySQL FULLTEXT indexes + +### Media Storage +- **Storage**: Local filesystem (`/uploads` directory) +- **Structure**: `/uploads/videos/`, `/uploads/icons/`, `/uploads/documents/` +- **Serving**: Express static middleware with proper MIME types +- **Video Format**: MP4 (H.264) for maximum compatibility + +### Development Tools +- **Package Manager**: pnpm +- **Monorepo Structure**: pnpm workspaces (frontend + backend) +- **Linting**: ESLint + Prettier +- **Type Checking**: TypeScript strict mode +- **Environment**: dotenv +- **Development**: Concurrently (run frontend + backend together) + +### Deployment (PoC) +- **Server**: Single VPS or local machine +- **Process Manager**: PM2 +- **Reverse Proxy**: nginx (optional, for production-like setup) +- **Database**: MySQL server (local or managed) + +--- + +## 2. Project Folder Structure + +``` +turkshop/ +β”œβ”€β”€ packages/ +β”‚ β”œβ”€β”€ frontend/ # React + Vite application +β”‚ β”‚ β”œβ”€β”€ public/ +β”‚ β”‚ β”‚ └── assets/ # Static assets +β”‚ β”‚ β”œβ”€β”€ src/ +β”‚ β”‚ β”‚ β”œβ”€β”€ components/ # Reusable UI components +β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ ui/ # shadcn/ui base components +β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ layout/ # Sidebar, Header, Layout +β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ dictionary/ # WordCard, WordGrid, FilterBar +β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ znakopis/ # SentenceBuilder, TokenTray +β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ video/ # VideoPlayer, PlaylistControls +β”‚ β”‚ β”‚ β”‚ └── cloud/ # DocumentBrowser, DocumentList +β”‚ β”‚ β”‚ β”œβ”€β”€ pages/ # Route pages +β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ Home.tsx +β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ Dictionary.tsx +β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ Znakopis.tsx +β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ VideoSentence.tsx +β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ Cloud.tsx +β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ Auth.tsx +β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ Help.tsx +β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ Community.tsx +β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ Comments.tsx +β”‚ β”‚ β”‚ β”‚ └── BugReport.tsx +β”‚ β”‚ β”‚ β”œβ”€β”€ stores/ # Zustand stores +β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ authStore.ts +β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ sentenceStore.ts +β”‚ β”‚ β”‚ β”‚ └── documentStore.ts +β”‚ β”‚ β”‚ β”œβ”€β”€ lib/ # Utilities +β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ api.ts # Axios instance +β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ utils.ts +β”‚ β”‚ β”‚ β”‚ └── constants.ts +β”‚ β”‚ β”‚ β”œβ”€β”€ types/ # TypeScript types +β”‚ β”‚ β”‚ β”‚ └── index.ts +β”‚ β”‚ β”‚ β”œβ”€β”€ hooks/ # Custom React hooks +β”‚ β”‚ β”‚ β”œβ”€β”€ App.tsx +β”‚ β”‚ β”‚ β”œβ”€β”€ main.tsx +β”‚ β”‚ β”‚ └── index.css # Tailwind imports +β”‚ β”‚ β”œβ”€β”€ package.json +β”‚ β”‚ β”œβ”€β”€ vite.config.ts +β”‚ β”‚ β”œβ”€β”€ tailwind.config.js +β”‚ β”‚ └── tsconfig.json +β”‚ β”‚ +β”‚ └── backend/ # Express + TypeScript API +β”‚ β”œβ”€β”€ src/ +β”‚ β”‚ β”œβ”€β”€ routes/ # API route handlers +β”‚ β”‚ β”‚ β”œβ”€β”€ auth.ts +β”‚ β”‚ β”‚ β”œβ”€β”€ terms.ts +β”‚ β”‚ β”‚ β”œβ”€β”€ documents.ts +β”‚ β”‚ β”‚ β”œβ”€β”€ sentences.ts +β”‚ β”‚ β”‚ β”œβ”€β”€ playlists.ts +β”‚ β”‚ β”‚ β”œβ”€β”€ community.ts +β”‚ β”‚ β”‚ └── index.ts +β”‚ β”‚ β”œβ”€β”€ controllers/ # Business logic +β”‚ β”‚ β”‚ β”œβ”€β”€ authController.ts +β”‚ β”‚ β”‚ β”œβ”€β”€ termController.ts +β”‚ β”‚ β”‚ β”œβ”€β”€ documentController.ts +β”‚ β”‚ β”‚ └── sentenceController.ts +β”‚ β”‚ β”œβ”€β”€ middleware/ # Express middleware +β”‚ β”‚ β”‚ β”œβ”€β”€ auth.ts +β”‚ β”‚ β”‚ β”œβ”€β”€ validation.ts +β”‚ β”‚ β”‚ β”œβ”€β”€ errorHandler.ts +β”‚ β”‚ β”‚ └── upload.ts +β”‚ β”‚ β”œβ”€β”€ services/ # External services +β”‚ β”‚ β”‚ β”œβ”€β”€ authService.ts +β”‚ β”‚ β”‚ β”œβ”€β”€ storageService.ts +β”‚ β”‚ β”‚ └── playlistService.ts +β”‚ β”‚ β”œβ”€β”€ lib/ # Utilities +β”‚ β”‚ β”‚ β”œβ”€β”€ prisma.ts # Prisma client +β”‚ β”‚ β”‚ └── passport.ts # Passport config +β”‚ β”‚ β”œβ”€β”€ types/ # TypeScript types +β”‚ β”‚ β”‚ └── index.ts +β”‚ β”‚ β”œβ”€β”€ config/ # Configuration +β”‚ β”‚ β”‚ └── index.ts +β”‚ β”‚ └── server.ts # Express app entry +β”‚ β”œβ”€β”€ prisma/ +β”‚ β”‚ β”œβ”€β”€ schema.prisma # Database schema +β”‚ β”‚ β”œβ”€β”€ migrations/ # Migration files +β”‚ β”‚ └── seed.ts # Seed data +β”‚ β”œβ”€β”€ uploads/ # Local file storage +β”‚ β”‚ β”œβ”€β”€ videos/ +β”‚ β”‚ β”œβ”€β”€ icons/ +β”‚ β”‚ └── documents/ +β”‚ β”œβ”€β”€ package.json +β”‚ └── tsconfig.json +β”‚ +β”œβ”€β”€ shared/ # Shared types/schemas (optional) +β”‚ β”œβ”€β”€ types/ +β”‚ └── schemas/ +β”‚ +β”œβ”€β”€ package.json # Root package.json (workspace) +β”œβ”€β”€ pnpm-workspace.yaml +β”œβ”€β”€ .gitignore +β”œβ”€β”€ README.md +└── main-plan.md # This file +``` + +--- + +## 3. Database Schema (Prisma + MySQL) + +### Complete Prisma Schema + +```prisma +// prisma/schema.prisma + +generator client { + provider = "prisma-client-js" +} + +datasource db { + provider = "mysql" + url = env("DATABASE_URL") +} + +// ============================================ +// AUTHENTICATION & USERS +// ============================================ + +model User { + id String @id @default(uuid()) + email String @unique + displayName String? @map("display_name") + passwordHash String? @map("password_hash") + authProvider String @default("local") @map("auth_provider") // local, google, microsoft + providerId String? @map("provider_id") + createdAt DateTime @default(now()) @map("created_at") + updatedAt DateTime @updatedAt @map("updated_at") + + documents Document[] + comments Comment[] + bugReports BugReport[] + + @@map("users") +} + +// ============================================ +// DICTIONARY / TERMS +// ============================================ + +model Term { + id String @id @default(uuid()) + wordText String @map("word_text") @db.VarChar(255) + normalizedText String @map("normalized_text") @db.VarChar(255) + language String @default("hr") @db.VarChar(10) + wordType WordType @map("word_type") + cefrLevel CefrLevel @map("cefr_level") + shortDescription String? @map("short_description") @db.Text + tags String? @db.Text // JSON array stored as text + iconAssetId String? @map("icon_asset_id") + createdAt DateTime @default(now()) @map("created_at") + updatedAt DateTime @updatedAt @map("updated_at") + + media TermMedia[] + examples TermExample[] + sentenceTokens SentenceToken[] + + @@index([normalizedText]) + @@fulltext([wordText, normalizedText]) + @@map("terms") +} + +model TermMedia { + id String @id @default(uuid()) + termId String @map("term_id") + kind MediaKind + url String @db.VarChar(500) + durationMs Int? @map("duration_ms") + width Int? + height Int? + checksum String? @db.VarChar(64) + createdAt DateTime @default(now()) @map("created_at") + + term Term @relation(fields: [termId], references: [id], onDelete: Cascade) + + @@index([termId]) + @@map("term_media") +} + +model TermExample { + id String @id @default(uuid()) + termId String @map("term_id") + exampleText String @map("example_text") @db.Text + notes String? @db.Text + createdAt DateTime @default(now()) @map("created_at") + + term Term @relation(fields: [termId], references: [id], onDelete: Cascade) + + @@index([termId]) + @@map("term_examples") +} + +// ============================================ +// DOCUMENTS & SENTENCES (ZNAKOPIS) +// ============================================ + +model Document { + id String @id @default(uuid()) + ownerUserId String? @map("owner_user_id") + title String @db.VarChar(255) + description String? @db.Text + visibility Visibility @default(PRIVATE) + createdAt DateTime @default(now()) @map("created_at") + updatedAt DateTime @updatedAt @map("updated_at") + + owner User? @relation(fields: [ownerUserId], references: [id], onDelete: SetNull) + pages DocumentPage[] + + @@index([ownerUserId]) + @@map("documents") +} + +model DocumentPage { + id String @id @default(uuid()) + documentId String @map("document_id") + pageIndex Int @map("page_index") + title String? @db.VarChar(255) + + document Document @relation(fields: [documentId], references: [id], onDelete: Cascade) + sentences Sentence[] + + @@unique([documentId, pageIndex]) + @@index([documentId]) + @@map("document_pages") +} + +model Sentence { + id String @id @default(uuid()) + documentPageId String @map("document_page_id") + sentenceIndex Int @map("sentence_index") + rawText String? @map("raw_text") @db.Text + + documentPage DocumentPage @relation(fields: [documentPageId], references: [id], onDelete: Cascade) + tokens SentenceToken[] + + @@unique([documentPageId, sentenceIndex]) + @@index([documentPageId]) + @@map("sentences") +} + +model SentenceToken { + id String @id @default(uuid()) + sentenceId String @map("sentence_id") + tokenIndex Int @map("token_index") + termId String? @map("term_id") + displayText String @map("display_text") @db.VarChar(255) + isPunctuation Boolean @default(false) @map("is_punctuation") + + sentence Sentence @relation(fields: [sentenceId], references: [id], onDelete: Cascade) + term Term? @relation(fields: [termId], references: [id], onDelete: SetNull) + + @@unique([sentenceId, tokenIndex]) + @@index([sentenceId]) + @@index([termId]) + @@map("sentence_tokens") +} + +// ============================================ +// COMMUNITY & SUPPORT +// ============================================ + +model Comment { + id String @id @default(uuid()) + userId String @map("user_id") + content String @db.Text + context String? @db.VarChar(255) // e.g., "term:uuid" or "general" + createdAt DateTime @default(now()) @map("created_at") + + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + + @@index([userId]) + @@map("comments") +} + +model BugReport { + id String @id @default(uuid()) + userId String? @map("user_id") + title String @db.VarChar(255) + description String @db.Text + status BugStatus @default(OPEN) + createdAt DateTime @default(now()) @map("created_at") + updatedAt DateTime @updatedAt @map("updated_at") + + user User? @relation(fields: [userId], references: [id], onDelete: SetNull) + + @@index([userId]) + @@index([status]) + @@map("bug_reports") +} + +// ============================================ +// ENUMS +// ============================================ + +enum WordType { + NOUN + VERB + ADJECTIVE + ADVERB + PRONOUN + PREPOSITION + CONJUNCTION + INTERJECTION + PHRASE + OTHER +} + +enum CefrLevel { + A1 + A2 + B1 + B2 + C1 + C2 +} + +enum MediaKind { + VIDEO + IMAGE + ILLUSTRATION +} + +enum Visibility { + PRIVATE + SHARED + PUBLIC +} + +enum BugStatus { + OPEN + IN_PROGRESS + RESOLVED + CLOSED +} +``` + +--- + +## 4. API Routes & Endpoints + +### Base URL +- Development: `http://localhost:3000/api` +- Production: `https://yourdomain.com/api` + +### 4.1 Authentication Routes (`/api/auth`) + +| Method | Endpoint | Description | Auth Required | +|--------|----------|-------------|---------------| +| POST | `/auth/register` | Register new user with email/password | No | +| POST | `/auth/login` | Login with email/password | No | +| POST | `/auth/logout` | Logout current user | Yes | +| GET | `/auth/me` | Get current user info | Yes | +| GET | `/auth/google` | Initiate Google OAuth flow | No | +| GET | `/auth/google/callback` | Google OAuth callback | No | +| GET | `/auth/microsoft` | Initiate Microsoft OAuth flow | No | +| GET | `/auth/microsoft/callback` | Microsoft OAuth callback | No | + +### 4.2 Dictionary/Terms Routes (`/api/terms`) + +| Method | Endpoint | Description | Auth Required | +|--------|----------|-------------|---------------| +| GET | `/terms` | List/search terms with filters | No | +| GET | `/terms/:id` | Get single term details | No | +| GET | `/terms/:id/media` | Get all media for a term | No | +| GET | `/terms/:id/examples` | Get examples for a term | No | +| POST | `/terms` | Create new term (admin) | Yes (Admin) | +| PUT | `/terms/:id` | Update term (admin) | Yes (Admin) | +| DELETE | `/terms/:id` | Delete term (admin) | Yes (Admin) | + +**Query Parameters for GET `/terms`:** +- `query` (string): Search text +- `wordType` (enum): Filter by word type +- `cefrLevel` (enum): Filter by CEFR level +- `page` (number): Page number (default: 1) +- `limit` (number): Items per page (default: 20) +- `sortBy` (string): Sort field (default: wordText) +- `sortOrder` (asc|desc): Sort direction (default: asc) + +### 4.3 Document Routes (`/api/documents`) + +| Method | Endpoint | Description | Auth Required | +|--------|----------|-------------|---------------| +| GET | `/documents` | List user's documents | Yes | +| GET | `/documents/:id` | Get full document with pages/sentences | Yes | +| POST | `/documents` | Create new document | Yes | +| PUT | `/documents/:id` | Update document metadata | Yes | +| DELETE | `/documents/:id` | Delete document | Yes | +| PUT | `/documents/:id/content` | Update document content (pages/sentences) | Yes | +| POST | `/documents/:id/share` | Generate share link | Yes | + +### 4.4 Sentence Routes (`/api/sentences`) + +| Method | Endpoint | Description | Auth Required | +|--------|----------|-------------|---------------| +| GET | `/sentences/:id` | Get sentence with tokens | Yes | +| POST | `/sentences` | Create new sentence | Yes | +| PUT | `/sentences/:id` | Update sentence | Yes | +| DELETE | `/sentences/:id` | Delete sentence | Yes | +| POST | `/sentences/:id/tokens` | Add token to sentence | Yes | +| PUT | `/sentences/:id/tokens/:tokenId` | Update token | Yes | +| DELETE | `/sentences/:id/tokens/:tokenId` | Remove token | Yes | +| PUT | `/sentences/:id/reorder` | Reorder tokens | Yes | + +### 4.5 Playlist Routes (`/api/playlists`) + +| Method | Endpoint | Description | Auth Required | +|--------|----------|-------------|---------------| +| POST | `/playlists/generate` | Generate video playlist from sentence | No | + +**Request Body:** +```json +{ + "sentenceId": "uuid", + "tokenIds": ["uuid1", "uuid2", "uuid3"] +} +``` + +**Response:** +```json +{ + "playlist": [ + { + "tokenId": "uuid1", + "termId": "uuid", + "displayText": "Dobar", + "videoUrl": "/uploads/videos/dobar.mp4", + "durationMs": 2500, + "thumbnailUrl": "/uploads/videos/dobar-thumb.jpg" + } + ], + "totalDuration": 7500 +} +``` + +### 4.6 Community Routes (`/api/community`) + +| Method | Endpoint | Description | Auth Required | +|--------|----------|-------------|---------------| +| GET | `/community/comments` | List comments | No | +| POST | `/community/comments` | Create comment | Yes | +| DELETE | `/community/comments/:id` | Delete own comment | Yes | + +### 4.7 Bug Report Routes (`/api/bugs`) + +| Method | Endpoint | Description | Auth Required | +|--------|----------|-------------|---------------| +| GET | `/bugs` | List bug reports | Yes (Admin) | +| GET | `/bugs/:id` | Get bug report details | Yes | +| POST | `/bugs` | Submit bug report | Yes | +| PUT | `/bugs/:id` | Update bug status (admin) | Yes (Admin) | + +### 4.8 Upload Routes (`/api/uploads`) + +| Method | Endpoint | Description | Auth Required | +|--------|----------|-------------|---------------| +| POST | `/uploads/video` | Upload video file | Yes (Admin) | +| POST | `/uploads/icon` | Upload icon/image | Yes (Admin) | + +### 4.9 Static File Serving + +| Path | Description | +|------|-------------| +| `/uploads/videos/*` | Video files | +| `/uploads/icons/*` | Icon/image files | +| `/uploads/documents/*` | Document exports | + +--- + +## 5. UI/UX Specifications (Exact Replication) + +### 5.1 Design System (From Screenshots) + +**Color Palette:** +- Primary Blue: `#2563eb` (buttons, active states) +- Sidebar Background: `#1e293b` (dark slate) +- Card Colors (word difficulty): + - Green: `#10b981` (A1-A2) + - Yellow: `#f59e0b` (B1-B2) + - Orange: `#f97316` (C1-C2) +- Background: `#f8fafc` (light gray) +- Text Primary: `#0f172a` +- Text Secondary: `#64748b` +- Border: `#e2e8f0` + +**Typography:** +- Font Family: Inter, system-ui, sans-serif +- Headings: 600-700 weight +- Body: 400-500 weight +- Sizes: 14px (body), 16px (large), 12px (small) + +**Spacing:** +- Base unit: 4px (Tailwind default) +- Card padding: 16px +- Section gaps: 24px +- Grid gap: 16px + +**Border Radius:** +- Cards: 8px +- Buttons: 6px +- Inputs: 6px + +### 5.2 Layout Components + +**Sidebar (Left Navigation):** +- Width: 240px +- Fixed position +- Dark background (#1e293b) +- White text with hover states +- Logo at top +- Navigation items with icons +- Auth section at bottom + +**Main Content Area:** +- Margin-left: 240px (sidebar width) +- Padding: 24px +- Max-width: 1400px (for large screens) + +**Filter Bar (Dictionary Page):** +- Sticky top position +- White background with shadow +- Flex layout: inputs on left, actions on right +- Input fields: text search, dropdowns for filters +- Action buttons: Search (blue), Text toggle, Reset + +**Word Card Grid:** +- CSS Grid: 4-5 columns on desktop, responsive +- Gap: 16px +- Card structure: + - Icon area (top, colored background) + - Word label (bottom, white background) + - Action buttons (overlay on hover) + +### 5.3 Page-Specific Layouts + +**Home (Početna):** +- Hero section with large heading +- 2x2 grid of feature cards +- Each card: icon, title, description, link + +**Dictionary (Riječi):** +- Filter bar (sticky) +- Word card grid +- Pagination at bottom +- Word detail modal (overlay) + +**Znakopis (Sentence Builder):** +- Two-column layout: + - Left: Token tray (current sentence) + - Right: Document panel (sentence list, page controls) +- Drag-and-drop interface for tokens +- Save/Load buttons in header + +**Video Rečenica (Video Sentence):** +- Two-column layout: + - Left: Large video player (60% width) + - Right: Sentence panel (40% width) +- Video controls below player +- Highlighted current token in sentence list + +**Oblak (Cloud):** +- Document list with cards +- Upload/Create buttons +- Document metadata display +- Load/Delete actions per document + +### 5.4 Component Library (shadcn/ui) + +Components to install: +- `button` - All action buttons +- `input` - Text inputs +- `select` - Dropdowns +- `card` - Word cards, document cards +- `dialog` - Modals (word detail, confirmations) +- `dropdown-menu` - User menu +- `tabs` - Znakopis/Oblak tabs +- `toast` - Notifications +- `avatar` - User avatar +- `badge` - CEFR level badges +- `separator` - Dividers +- `scroll-area` - Scrollable lists + +### 5.5 Croatian Text (Exact Labels) + +**Navigation:** +- Početna (Home) +- Riječi (Words/Dictionary) +- Znakopis (Sentence Builder) +- Video rečenica (Video Sentence) +- Oblak (Cloud) +- KoriΕ‘tenje aplikacije (Help) +- Zajednica (Community) +- Komentari (Comments) +- Prijavi greΕ‘ku (Bug Report) + +**Dictionary Page:** +- Riječ (Word) - search input label +- Tip riječi (Word Type) - dropdown label +- CEFR razina (CEFR Level) - dropdown label +- TraΕΎi (Search) - button +- Text - toggle button +- Reset - button +- Dodaj (Add) - card action +- Info - card action + +**Znakopis Page:** +- Popis rečenica (Sentence List) +- stranica (page) +- Učitajte dokument (Load Document) +- Spremi (Save) +- Nova rečenica (New Sentence) + +**Auth:** +- Prijavi se (Sign In) +- Odjavi se (Sign Out) +- Registriraj se (Sign Up) +- Email adresa (Email Address) +- Lozinka (Password) + +--- + +## 6. Implementation Milestones + +### Phase 0: Project Setup (Week 1) +**Goal:** Initialize project structure and development environment + +**Tasks:** +1. Create monorepo structure with pnpm workspaces +2. Initialize frontend (Vite + React + TypeScript) +3. Initialize backend (Express + TypeScript) +4. Set up Prisma with MySQL +5. Configure Tailwind CSS and shadcn/ui +6. Set up ESLint, Prettier, and TypeScript configs +7. Create `.env.example` files +8. Set up Git repository and `.gitignore` +9. Create initial README with setup instructions + +**Deliverables:** +- βœ… Project compiles and runs (frontend + backend) +- βœ… Database connection works +- βœ… Basic "Hello World" on both ends + +--- + +### Phase 1: Core Infrastructure (Week 2) +**Goal:** Build authentication and basic layout + +**Backend Tasks:** +1. Implement Prisma schema (User model) +2. Run initial migration +3. Set up Passport.js with local strategy +4. Implement session management +5. Create auth routes (register, login, logout, me) +6. Set up Google OAuth +7. Set up Microsoft OAuth +8. Create auth middleware +9. Set up CORS and security headers + +**Frontend Tasks:** +1. Create layout components (Sidebar, Header, Layout) +2. Set up React Router with routes +3. Create auth pages (Login, Register) +4. Implement auth store (Zustand) +5. Create auth API client +6. Implement protected routes +7. Add OAuth buttons + +**Deliverables:** +- βœ… Users can register and login +- βœ… OAuth works (Google + Microsoft) +- βœ… Session persists across page reloads +- βœ… Sidebar navigation works +- βœ… Protected routes redirect to login + +--- + +### Phase 2: Dictionary Module (Week 3-4) +**Goal:** Complete dictionary browsing and search + +**Backend Tasks:** +1. Implement Term, TermMedia, TermExample models +2. Run migrations +3. Create seed script with sample terms +4. Implement term routes (list, get, search) +5. Add filtering logic (wordType, cefrLevel, query) +6. Add pagination +7. Implement full-text search +8. Set up file upload for videos/icons +9. Create static file serving + +**Frontend Tasks:** +1. Create Dictionary page layout +2. Build FilterBar component +3. Build WordCard component +4. Build WordGrid component +5. Implement term API client +6. Add search and filter functionality +7. Create WordDetailModal component +8. Integrate video player (Plyr) +9. Add pagination controls +10. Implement "Text" toggle view + +**Deliverables:** +- βœ… Dictionary page displays word cards +- βœ… Search and filters work +- βœ… Word detail modal shows video +- βœ… Pagination works +- βœ… UI matches screenshots exactly + +--- + +### Phase 3: Sentence Builder (Znakopis) (Week 5-6) +**Goal:** Build sentence composition workspace + +**Backend Tasks:** +1. Implement Document, DocumentPage, Sentence, SentenceToken models +2. Run migrations +3. Create document routes (CRUD) +4. Create sentence routes (CRUD) +5. Implement token management (add, remove, reorder) +6. Add document content update endpoint +7. Implement document listing for user + +**Frontend Tasks:** +1. Create Znakopis page layout +2. Build sentence store (Zustand) +3. Implement "Add to sentence" from Dictionary +4. Create TokenTray component +5. Implement drag-and-drop reordering (@dnd-kit) +6. Create SentenceList component +7. Build DocumentPanel component +8. Implement save/load document +9. Add page management (multi-page documents) +10. Create new sentence functionality + +**Deliverables:** +- βœ… Users can add words from dictionary to sentence +- βœ… Tokens can be reordered via drag-and-drop +- βœ… Sentences can be saved to documents +- βœ… Documents can be loaded from cloud +- βœ… Multi-page documents work +- βœ… UI matches screenshots exactly + +--- + +### Phase 4: Video Sentence Player (Week 7) +**Goal:** Implement video playback of sentences + +**Backend Tasks:** +1. Create playlist generation endpoint +2. Implement playlist resolver (tokens β†’ videos) +3. Handle missing media gracefully +4. Add video metadata to responses + +**Frontend Tasks:** +1. Create VideoSentence page layout +2. Build VideoPlayer component with Plyr +3. Implement playlist logic +4. Add playback controls (play, pause, next, prev) +5. Implement token highlighting sync +6. Add speed control +7. Add loop functionality +8. Implement preloading of next video +9. Create sentence panel (right side) + +**Deliverables:** +- βœ… Sentences play as sequential videos +- βœ… Playback controls work +- βœ… Current token is highlighted +- βœ… Videos transition smoothly +- βœ… UI matches screenshots exactly + +--- + +### Phase 5: Cloud Documents (Week 8) +**Goal:** Complete document management + +**Backend Tasks:** +1. Implement document visibility settings +2. Add share link generation +3. Create document export functionality +4. Add document search/filtering + +**Frontend Tasks:** +1. Create Oblak (Cloud) page +2. Build DocumentBrowser component +3. Implement document list with cards +4. Add upload document functionality +5. Create document metadata editor +6. Implement load document into Znakopis +7. Add delete document with confirmation +8. Implement document sharing UI + +**Deliverables:** +- βœ… Users can view all their documents +- βœ… Documents can be loaded into editor +- βœ… Documents can be deleted +- βœ… Share links work +- βœ… UI matches screenshots exactly + +--- + +### Phase 6: Community & Support (Week 9) +**Goal:** Add community features + +**Backend Tasks:** +1. Implement Comment and BugReport models +2. Run migrations +3. Create community routes +4. Create bug report routes +5. Add admin endpoints for bug management + +**Frontend Tasks:** +1. Create Help page (KoriΕ‘tenje aplikacije) +2. Create Community page (Zajednica) +3. Create Comments page (Komentari) +4. Build comment form and list +5. Create BugReport page (Prijavi greΕ‘ku) +6. Build bug report form +7. Add toast notifications + +**Deliverables:** +- βœ… Users can post comments +- βœ… Users can submit bug reports +- βœ… Help page has documentation +- βœ… UI matches screenshots exactly + +--- + +### Phase 7: Polish & Testing (Week 10) +**Goal:** Final refinements and quality assurance + +**Tasks:** +1. Responsive design testing (mobile, tablet, desktop) +2. Cross-browser testing (Chrome, Firefox, Safari, Edge) +3. Accessibility audit (keyboard nav, ARIA labels, screen readers) +4. Performance optimization (lazy loading, code splitting) +5. Error handling improvements +6. Loading states and skeletons +7. Form validation refinements +8. Video loading optimization +9. Database query optimization +10. Security audit +11. Write E2E tests (Playwright) +12. Write unit tests for critical functions +13. Documentation updates +14. Deployment preparation + +**Deliverables:** +- βœ… App works on all major browsers +- βœ… Mobile responsive +- βœ… Accessible (WCAG 2.1 AA) +- βœ… Fast loading times +- βœ… No critical bugs +- βœ… Tests pass +- βœ… Ready for deployment + +--- + +## 7. Environment Configuration + +### Backend `.env` (packages/backend/.env) + +```env +# Server +NODE_ENV=development +PORT=3000 +FRONTEND_URL=http://localhost:5173 + +# Database +DATABASE_URL="mysql://user:password@localhost:3306/znakovni" + +# Session +SESSION_SECRET=your-super-secret-session-key-change-in-production + +# OAuth - Google +GOOGLE_CLIENT_ID=your-google-client-id +GOOGLE_CLIENT_SECRET=your-google-client-secret +GOOGLE_CALLBACK_URL=http://localhost:3000/api/auth/google/callback + +# OAuth - Microsoft +MICROSOFT_CLIENT_ID=your-microsoft-client-id +MICROSOFT_CLIENT_SECRET=your-microsoft-client-secret +MICROSOFT_CALLBACK_URL=http://localhost:3000/api/auth/microsoft/callback + +# File Upload +UPLOAD_DIR=./uploads +MAX_FILE_SIZE=104857600 +# 100MB in bytes + +# CORS +CORS_ORIGIN=http://localhost:5173 +``` + +### Frontend `.env` (packages/frontend/.env) + +```env +VITE_API_URL=http://localhost:3000/api +VITE_UPLOADS_URL=http://localhost:3000/uploads +``` + +--- + +## 8. Key Features & User Flows + +### 8.1 Dictionary Search Flow +1. User navigates to "Riječi" (Dictionary) +2. User enters search term in "Riječ" input +3. User optionally selects "Tip riječi" (word type) filter +4. User optionally selects "CEFR razina" (level) filter +5. User clicks "TraΕΎi" (Search) +6. Grid updates with filtered results +7. User clicks "Info" on a card +8. Modal opens showing: + - Word details + - Sign video (auto-plays) + - Examples + - Metadata +9. User can click "Dodaj" to add word to current sentence + +### 8.2 Sentence Building Flow +1. User searches for words in Dictionary +2. User clicks "Dodaj" on multiple word cards +3. Words are added to sentence store +4. User navigates to "Znakopis" +5. Tokens appear in TokenTray +6. User drags tokens to reorder +7. User can remove tokens +8. User clicks "Spremi" (Save) +9. Document is saved to cloud (if logged in) or local storage +10. User can create multiple sentences across pages + +### 8.3 Video Playback Flow +1. User builds or loads a sentence in Znakopis +2. User navigates to "Video rečenica" +3. Sentence tokens appear in right panel +4. User clicks play button +5. Videos play sequentially for each token +6. Current token is highlighted +7. User can pause, skip, or adjust speed +8. User can navigate between pages/sentences + +### 8.4 Cloud Document Flow +1. User logs in +2. User creates sentences in Znakopis +3. User saves document to cloud +4. User navigates to "Oblak" +5. Document appears in list +6. User can: + - Load document into Znakopis + - Delete document + - Share document (get link) + - View document metadata + +--- + +## 9. Technical Implementation Details + +### 9.1 Video Playlist Resolution Algorithm + +```typescript +// Pseudocode for playlist generation +async function generatePlaylist(sentenceId: string) { + // 1. Fetch sentence with tokens + const sentence = await prisma.sentence.findUnique({ + where: { id: sentenceId }, + include: { + tokens: { + include: { term: { include: { media: true } } }, + orderBy: { tokenIndex: 'asc' } + } + } + }); + + // 2. Map tokens to video URLs + const playlist = sentence.tokens.map(token => { + if (!token.term) { + return null; // Skip punctuation or free-text + } + + // Find primary video media + const video = token.term.media.find(m => m.kind === 'VIDEO'); + + if (!video) { + console.warn(`No video for term ${token.term.id}`); + return null; + } + + return { + tokenId: token.id, + termId: token.term.id, + displayText: token.displayText, + videoUrl: video.url, + durationMs: video.durationMs, + thumbnailUrl: video.url.replace('.mp4', '-thumb.jpg') + }; + }).filter(Boolean); + + return { + playlist, + totalDuration: playlist.reduce((sum, item) => sum + item.durationMs, 0) + }; +} +``` + +### 9.2 Full-Text Search Implementation + +```typescript +// MySQL full-text search query +async function searchTerms(query: string, filters: Filters) { + const where = { + AND: [ + query ? { + OR: [ + { wordText: { contains: query } }, + { normalizedText: { contains: query } } + ] + } : {}, + filters.wordType ? { wordType: filters.wordType } : {}, + filters.cefrLevel ? { cefrLevel: filters.cefrLevel } : {} + ] + }; + + return await prisma.term.findMany({ + where, + include: { media: true }, + orderBy: { wordText: 'asc' }, + skip: (filters.page - 1) * filters.limit, + take: filters.limit + }); +} +``` + +### 9.3 Token Reordering Logic + +```typescript +// Frontend: Drag-and-drop reorder +function handleDragEnd(event: DragEndEvent) { + const { active, over } = event; + + if (active.id !== over.id) { + const oldIndex = tokens.findIndex(t => t.id === active.id); + const newIndex = tokens.findIndex(t => t.id === over.id); + + const reordered = arrayMove(tokens, oldIndex, newIndex); + + // Update local state + setSentenceTokens(reordered); + + // Sync to backend + await api.put(`/sentences/${sentenceId}/reorder`, { + tokenIds: reordered.map(t => t.id) + }); + } +} +``` + +--- + +## 10. Deployment Guide (PoC) + +### 10.1 Prerequisites +- Ubuntu 20.04+ or similar Linux server +- Node.js 20 LTS installed +- MySQL 8.0+ installed and running +- pnpm installed globally +- nginx installed (optional, for reverse proxy) + +### 10.2 Deployment Steps + +**1. Clone and Install** +```bash +git clone +cd turkshop +pnpm install +``` + +**2. Configure Environment** +```bash +# Backend +cd packages/backend +cp .env.example .env +# Edit .env with production values +nano .env + +# Frontend +cd ../frontend +cp .env.example .env +# Edit .env with production API URL +nano .env +``` + +**3. Database Setup** +```bash +cd packages/backend +npx prisma migrate deploy +npx prisma db seed +``` + +**4. Build Applications** +```bash +# From root +pnpm build +``` + +**5. Start with PM2** +```bash +# Install PM2 +npm install -g pm2 + +# Start backend +cd packages/backend +pm2 start dist/server.js --name znakovni-api + +# Serve frontend (with nginx or serve) +cd ../frontend +pm2 serve dist 5173 --name znakovni-frontend +``` + +**6. Configure nginx (Optional)** +```nginx +server { + listen 80; + server_name yourdomain.com; + + # Frontend + location / { + root /path/to/turkshop/packages/frontend/dist; + try_files $uri $uri/ /index.html; + } + + # Backend API + location /api { + proxy_pass http://localhost:3000; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_cache_bypass $http_upgrade; + } + + # Uploads + location /uploads { + proxy_pass http://localhost:3000; + } +} +``` + +**7. Set up SSL (Production)** +```bash +sudo apt install certbot python3-certbot-nginx +sudo certbot --nginx -d yourdomain.com +``` + +--- + +## 11. Development Workflow + +### 11.1 Initial Setup + +```bash +# Clone repo +git clone +cd turkshop + +# Install dependencies +pnpm install + +# Set up environment files +cp packages/backend/.env.example packages/backend/.env +cp packages/frontend/.env.example packages/frontend/.env + +# Edit .env files with your local MySQL credentials and OAuth keys + +# Run database migrations +cd packages/backend +npx prisma migrate dev +npx prisma db seed + +# Return to root +cd ../.. +``` + +### 11.2 Running Development Servers + +```bash +# From root directory +pnpm dev + +# This runs both frontend (port 5173) and backend (port 3000) concurrently +``` + +### 11.3 Database Management + +```bash +# Create new migration +cd packages/backend +npx prisma migrate dev --name description_of_change + +# Reset database (WARNING: deletes all data) +npx prisma migrate reset + +# Open Prisma Studio (GUI for database) +npx prisma studio + +# Generate Prisma Client after schema changes +npx prisma generate +``` + +### 11.4 Adding shadcn/ui Components + +```bash +cd packages/frontend +npx shadcn-ui@latest add button +npx shadcn-ui@latest add input +npx shadcn-ui@latest add card +# etc. +``` + +--- + +## 12. Success Criteria + +### Functional Requirements βœ… +- [ ] Users can browse and search dictionary with filters +- [ ] Word detail modal displays video and metadata +- [ ] Users can build sentences by adding words +- [ ] Tokens can be reordered via drag-and-drop +- [ ] Sentences can be saved to documents +- [ ] Documents can be loaded from cloud +- [ ] Video sentence player works with sequential playback +- [ ] Authentication works (email + Google + Microsoft) +- [ ] Cloud document management works +- [ ] Comments and bug reports can be submitted + +### Visual Requirements βœ… +- [ ] UI matches screenshots pixel-perfect +- [ ] Croatian text labels are exact +- [ ] Color scheme matches original +- [ ] Typography matches original +- [ ] Layout and spacing match original +- [ ] Icons and graphics match original + +### Performance Requirements βœ… +- [ ] Dictionary search returns results < 500ms +- [ ] Video playback starts < 1s +- [ ] Page load time < 2s +- [ ] Smooth animations (60fps) + +### Quality Requirements βœ… +- [ ] TypeScript strict mode with no errors +- [ ] All forms have validation +- [ ] Error handling on all API calls +- [ ] Loading states for async operations +- [ ] Responsive design (desktop, tablet, mobile) +- [ ] Accessible (keyboard navigation, ARIA labels) + +--- + +## 13. Next Steps + +1. **Review and approve this plan** +2. **Set up OAuth credentials** (Google Cloud Console, Microsoft Azure) +3. **Prepare MySQL database** (local or cloud) +4. **Begin Phase 0: Project Setup** +5. **Iterate through phases sequentially** +6. **Test continuously during development** +7. **Deploy to production server** + +--- + +## 14. Resources & References + +### Documentation +- React: https://react.dev +- Vite: https://vitejs.dev +- TypeScript: https://www.typescriptlang.org +- Tailwind CSS: https://tailwindcss.com +- shadcn/ui: https://ui.shadcn.com +- Prisma: https://www.prisma.io +- Express: https://expressjs.com +- Passport.js: https://www.passportjs.org +- Plyr: https://plyr.io +- @dnd-kit: https://dndkit.com + +### Original Specifications +- `/usr/src/znakovni/original/project1.md` - Detailed functional spec +- `/usr/src/znakovni/original/project2.md` - Replication requirements +- `/usr/src/znakovni/original/*.png` - UI screenshots + +--- + +**END OF PLAN** + diff --git a/original/5325fda0-1faf-4472-ab17-e08a1e80e0d6.png b/original/5325fda0-1faf-4472-ab17-e08a1e80e0d6.png new file mode 100644 index 0000000..fa54eaf Binary files /dev/null and b/original/5325fda0-1faf-4472-ab17-e08a1e80e0d6.png differ diff --git a/original/8f275429-27e9-44f0-9a9d-a7bfa27e6f74.png b/original/8f275429-27e9-44f0-9a9d-a7bfa27e6f74.png new file mode 100644 index 0000000..bdc92e1 Binary files /dev/null and b/original/8f275429-27e9-44f0-9a9d-a7bfa27e6f74.png differ diff --git a/original/939b5c5a-19ca-4bc5-9540-b8fb3d1ef261.png b/original/939b5c5a-19ca-4bc5-9540-b8fb3d1ef261.png new file mode 100644 index 0000000..4e5b276 Binary files /dev/null and b/original/939b5c5a-19ca-4bc5-9540-b8fb3d1ef261.png differ diff --git a/original/d9b613dc-14b0-4654-ab83-624c0b9cba2a.png b/original/d9b613dc-14b0-4654-ab83-624c0b9cba2a.png new file mode 100644 index 0000000..17205f0 Binary files /dev/null and b/original/d9b613dc-14b0-4654-ab83-624c0b9cba2a.png differ diff --git a/original/dec2888a-e09b-481f-8dcf-42c5f2efff36.png b/original/dec2888a-e09b-481f-8dcf-42c5f2efff36.png new file mode 100644 index 0000000..29a278d Binary files /dev/null and b/original/dec2888a-e09b-481f-8dcf-42c5f2efff36.png differ diff --git a/original/f88da8a7-f760-4e36-bd27-75bd5d6b57f2.png b/original/f88da8a7-f760-4e36-bd27-75bd5d6b57f2.png new file mode 100644 index 0000000..a16e815 Binary files /dev/null and b/original/f88da8a7-f760-4e36-bd27-75bd5d6b57f2.png differ diff --git a/original/project1.md b/original/project1.md new file mode 100644 index 0000000..a26a215 --- /dev/null +++ b/original/project1.md @@ -0,0 +1,362 @@ +# project.md β€” Sign-Language Video Dictionary + Sentence Builder (Znakovni-style) + +## Purpose +This file captures the **observed functionality** of the znakovni.hr web application (Croatian Sign Language portal) from the provided screenshots, so engineering agents can plan a comparable product. + +### full copy +- Replicate **capabilities** and **branding**. I need 1to1 copy of the app. + +--- + +## 1) Product summary (what it is) +A web app that provides: +1) A **sign-language dictionary**: browse and search words/terms and open an entry to view sign media. +2) A **sentence/document workspace** (β€œZnakopis”): build a sentence by selecting terms from the dictionary, save it as a document. +3) A **video sentence player** (β€œVideo rečenica”): play a selected sentence/sequence as sign video; manage a sentence list and document pages. +4) A **cloud storage layer** (β€œOblak”): store/load documents, likely behind login. +5) A **support/community area**: usage docs, community, comments, bug reporting. + +From the screenshots, navigation is a **left sidebar** with core sections: +- **Početna** (Home) +- **Riječi** (Words / Dictionary) +- **Znakopis** (Sentence builder) +- **Video rečenica** (Video sentence) +- **Oblak** (Cloud) + +A secondary β€œPortal za podrΕ‘ku” section appears in the sidebar: +- **KoriΕ‘tenje aplikacije** +- **Zajednica** +- **Komentari** +- **Prijavi greΕ‘ku** +- External link: **znakovni.org** + +Authentication UI shows **Sign in** when logged out and **Sign out + username** when logged in. + +--- + +## 2) Screens (as observed) + +### 2.1 Home (Početna) +Purpose: marketing/overview of capabilities. +Observed content blocks: +- Large brand header and a tagline (β€œyour path into sign language world”). +- Feature cards/tiles that preview: + - Dictionary browsing grid + - Sentence building (Znakopis) + - Video sentence playback + - Cloud/integrations-style illustration + +Functional requirements: +- Static content page +- Links to primary features + +--- + +### 2.2 Dictionary (Riječi) +This is the primary discovery/browsing screen. + +#### Layout +- **Top filter bar** with: + - Text input: **Riječ** (word) + - Dropdown: **Tip riječi** (word type) + - Dropdown: **CEFR razina** (language level; example shows **A2**) +- **Top-right action cluster** includes: + - Button with magnifier: **TraΕΎi** (search/submit) + - Button: **Text** (likely toggles text-only vs icons/cards) + - Button: **Reset** (clear filters) +- Main area: **grid of word cards**. + +#### Word card (observed) +Each card shows: +- A simple **illustration/icon** representing the word +- The **word label** in a colored bar (colors vary per word) +- Two actions: + - **Dodaj** (Add) + - **Info** (Details) + +Interpretation of actions: +- **Dodaj** likely adds the word to the current sentence/document in Znakopis / Video sentence workflow. +- **Info** opens a details view/modal with sign media (video), description, examples, metadata. + +Functional requirements: +- Server-side / API-backed query with filtering +- Pagination or infinite scroll (not visible, but grid implies many items) +- Two presentation modes (cards with icons vs text list) toggled by β€œText” +- Deterministic sorting (likely alphabetic by default) +- Per-term details + +--- + +### 2.3 Sentence Builder (Znakopis) +A workspace for assembling words into sentences and saving them as documents. + +Observed elements (from screenshots) +- A page titled similar to β€œZnakopis β€” Rečenica detaljno” (Sentence details) +- A right-side panel that shows: + - **Popis rečenica** (Sentence list) + - Page indicator like **1 / 0 stranica** (page count) + - Controls resembling pagination / page navigation + - Buttons/tabs at top: **Znakopis** and **Oblak** + - A prompt like β€œUčitajte dokument” (Upload/load document) when no document loaded + +Assumed core behavior: +- Users create a **document** containing one or more **sentences**. +- A sentence is assembled from selected dictionary entries. +- The document can be saved locally and/or to cloud. + +Functional requirements: +- Create new document +- Add/remove/reorder tokens (words) in a sentence +- Save document; load document; export/import (likely) +- Maintain versioned pages or β€œpages” within a document + +--- + +### 2.4 Video Sentence (Video rečenica) +A video player view to play the sign sequence corresponding to the constructed sentence. + +Observed layout +- Left: **large video player** area with playback controls under it. + - Controls include play/pause and additional buttons (likely speed, step, previous/next clip). +- Right: document area with: + - **Popis rečenica** (Sentence list) in a large text box region + - Tabs/buttons: **Znakopis** and **Oblak** + - Pagination controls on the right (page number, next/prev) + +Functional requirements: +- Given a sentence token list, create a **playlist** of videos (one per token) and play sequentially. +- Controls: + - Play/pause + - Next/previous token + - (Recommended) speed control, loop, scrub/seek, fullscreen +- Sync player position with highlighted token in the sentence list. + +--- + +### 2.5 Cloud (Oblak) +Based on UI labels, this is a storage layer for documents. + +Functional requirements: +- List documents +- Load into Znakopis / Video sentence +- Save current document +- (Recommended) share via link, permissions, export + +--- + +### 2.6 Authentication (Sign in) +Observed sign-in screen: +- β€œSign in with your email address” (email-based login) +- β€œSign in with your social account” with **Microsoft** and **Google** buttons +- β€œSign up now” link + +Functional requirements: +- Email + password or email magic link (choose one) +- OAuth for Microsoft and Google +- Account creation +- Session management + +--- + +## 3) Core user flows + +### Flow A β€” Find a sign for a word +1. Go to **Riječi**. +2. Filter by word text / type / CEFR. +3. Click **Info** on a card. +4. View sign media (video), metadata, and examples. + +### Flow B β€” Build a sentence/document +1. Go to **Riječi**. +2. Click **Dodaj** on multiple cards. +3. Switch to **Znakopis**. +4. Reorder/remove tokens; optionally add punctuation. +5. Save document (local/cloud). + +### Flow C β€” Play a sentence as sign video +1. Build or load a sentence in **Znakopis**. +2. Open **Video rečenica**. +3. Press play to see signs for each token in sequence. +4. Navigate pages/sentences. + +### Flow D β€” Cloud document management +1. Sign in. +2. Open **Oblak**. +3. Create folders/tags (optional), load/save documents. + +--- + +## 4) Data model (suggested) + +### 4.1 Dictionary +**Term** +- id (uuid) +- word_text (string) +- normalized_text (string; for search) +- language (e.g., hr) +- word_type (enum; e.g., noun/verb/adj/phrase/etc.) +- cefr_level (enum: A1, A2, B1, B2, C1, C2) +- short_description (string, optional) +- tags (string[]) +- icon_asset_id (nullable) +- created_at / updated_at + +**TermMedia** +- id +- term_id +- kind (enum: video, image, illustration) +- url +- duration_ms (for video) +- width/height +- checksum + +**TermExample** (optional) +- id +- term_id +- example_text +- notes + +### 4.2 Documents / Znakopis +**Document** +- id +- owner_user_id (nullable if anonymous/local) +- title +- description +- visibility (private/shared/public) +- created_at / updated_at + +**DocumentPage** +- id +- document_id +- page_index (int) +- title (optional) + +**Sentence** +- id +- document_page_id +- sentence_index (int) +- raw_text (optional) + +**SentenceToken** +- id +- sentence_id +- token_index (int) +- term_id (nullable if free-text) +- display_text +- punctuation (bool) + +### 4.3 Community/support (optional) +- Comment/feedback +- Bug report + +--- + +## 5) API surface (suggested) + +### Dictionary +- `GET /api/terms?query=&type=&cefr=&page=` +- `GET /api/terms/{id}` +- `GET /api/terms/{id}/media` + +### Documents +- `POST /api/documents` (create) +- `GET /api/documents` (list) +- `GET /api/documents/{id}` (full graph) +- `PUT /api/documents/{id}` (update metadata) +- `PUT /api/documents/{id}/content` (pages/sentences/tokens) +- `POST /api/documents/{id}/share` (optional) + +### Playback helpers +- `POST /api/playlists` (sentence β†’ resolved media playlist) + - input: sentence_id or token list + - output: ordered list of video URLs + metadata + +--- + +## 6) Playback logic (Video sentence) +Recommended playlist resolution algorithm: +1. For each token, resolve `term_id`. +2. Choose primary media of kind=video. +3. Construct ordered playlist. +4. Player features: + - preload next clip + - auto-advance on end + - handle missing media (skip with warning) + - optional: loop sentence + +--- + +## 7) UX components (reusable) +- Sidebar navigation with auth state (sign in/out) +- FilterBar component (text + dropdowns + reset) +- WordCard / WordRow (card and text modes) +- InfoModal (term details + video) +- TokenTray (current sentence tokens) +- DocumentBrowser (cloud) +- VideoPlayer with playlist +- SentenceList with token highlighting and page controls + +--- + +## 8) Authentication & security +- OAuth (Google, Microsoft) + email auth +- RBAC: + - anonymous: browse dictionary + - authenticated: save/load cloud docs, comment, bug report +- Store secrets in vault; rotate keys +- Rate limit search and auth endpoints + +--- + +## 9) Storage & delivery +- Relational DB: PostgreSQL +- Media storage: S3-compatible (S3, R2, MinIO) +- CDN for video assets +- Transcoding pipeline (recommended): upload β†’ transcode to H.264 MP4 + WebM + poster frame + +--- + +## 10) Non-functional requirements +- Performance: search results < 300ms p95 for common queries +- Accessibility: keyboard nav, visible focus, ARIA labels, captions where possible +- Internationalization-ready (hr now; extendable) +- Observability: logs, metrics, tracing + +--- + +## 11) MVP scope (if building β€œparity-first”) +**MVP-1** +- Dictionary grid with filters (query/type/CEFR) +- Term details modal with video +- Add-to-sentence (β€œDodaj”) into a simple token tray +- Znakopis page: edit/reorder tokens; save locally (browser storage) +- Video sentence page: playlist playback + +**MVP-2** +- Login (Google/Microsoft/email) +- Cloud documents (create/list/load/save) +- Multi-page documents + sentence list + +**MVP-3** +- Comments/feedback + bug reporting +- Sharing and permissions + +--- + +## 12) Open questions (for agents to resolve) +- Exact meaning of β€œText” toggle on Riječi page (list mode? free-text search within cards?) +- Definition and taxonomy of β€œTip riječi” values +- Whether CEFR is per-term or per-example usage +- Document model: pages vs sentences; how β€œ1 / 0 stranica” should behave +- Whether β€œOblak” is a separate page *and* a tab within editors (observed as a tab) + +--- + +## 13) References to provided screenshots (for context) +From screenshots you provided, the following are clearly visible: +- Home page with feature previews +- Dictionary page with filter bar and grid of word cards + β€œDodaj/Info” actions +- Video sentence page with large player + sentence list panel +- Znakopis/Sentence details page with document loading prompt +- Sign-in page with email + Microsoft/Google + diff --git a/original/project2.md b/original/project2.md new file mode 100644 index 0000000..1f62304 --- /dev/null +++ b/original/project2.md @@ -0,0 +1,241 @@ +# Znakovni.hr – Full Application Replication Specification + +## Purpose +This document specifies the **exact functionality, structure, and behavior** of the Znakovni.hr web application. +The goal is to enable AI programming agents to design and implement a **functionally identical copy** of the platform, +including UX flows, features, and system architecture. + +Explicit permission has been granted by the original author to replicate the application for demonstration, +research, and AI capability showcasing purposes. + +--- + +## 1. Application Overview + +Znakovni.hr is a **web-based Croatian Sign Language (HZJ) platform** that provides: +- A video-based sign language dictionary +- Sentence construction tools using signs +- Video sentence playback +- User accounts and cloud storage + +The platform functions as a **learning tool, reference dictionary, and sentence composition environment**. + +--- + +## 2. Main Navigation & Screens + +### 2.1 Sidebar Navigation +Persistent left sidebar with the following items: + +- Početna (Home) +- Riječi (Dictionary) +- Znakopis (Sentence Builder) +- Video rečenica (Video Sentence Player) +- Oblak (Cloud Documents) +- KoriΕ‘tenje aplikacije (Help) +- Zajednica (Community) +- Komentari (Comments) +- Prijavi greΕ‘ku (Bug Report) +- Sign in / Sign out + +Sidebar is visible on all authenticated pages. + +--- + +## 3. Screens & Functionality + +### 3.1 Home (Početna) +- Intro headline: β€œTvoj put u svijet znakovnog jezika” +- Feature overview cards: + - Dictionary + - Sentence composition (Znakopis) + - Video sentences + - Cloud documents + +Static informational screen. + +--- + +### 3.2 Dictionary (Riječi) + +#### Features +- Free-text search +- Filters: + - Word type + - CEFR level (A1–C2) +- Paginated grid of word cards + +#### Word Card +Each card includes: +- Icon representation +- Word label +- Difficulty color indicator +- Actions: + - Add to sentence + - Info + +#### Word Detail +- Embedded sign video +- Linguistic metadata +- Usage context + +--- + +### 3.3 Znakopis (Sentence Builder) + +#### Purpose +Visual assembly of sign-language sentences. + +#### Layout +- Sentence structure panel (left) +- Sentence description editor (right) + +#### Features +- Add words from dictionary +- Reorder via drag or controls +- Remove words +- Multi-page sentence support +- Save as document + +Documents may be saved locally or in cloud. + +--- + +### 3.4 Video Rečenica (Video Sentence) + +#### Purpose +Playback of complete sentences using video signs. + +#### Layout +- Video player (left) +- Sentence structure view (right) + +#### Controls +- Play / Pause +- Step navigation +- Repeat +- Speed adjustment (optional) + +--- + +### 3.5 Oblak (Cloud Documents) + +#### Purpose +Centralized storage of sentence documents. + +#### Features +- Upload documents +- Save Znakopis documents +- Load and edit documents +- Document listing + +--- + +### 3.6 Authentication + +#### Login Methods +- Email/password +- Google OAuth +- Microsoft OAuth + +#### Authenticated Capabilities +- Document persistence +- User-specific content +- Session continuity + +--- + +## 4. Core Data Models + +### User +- id +- email +- display_name +- auth_provider +- created_at + +### Word +- id +- text +- word_type +- cefr_level +- icon_url +- video_url + +### Sentence +- id +- user_id +- title +- created_at + +### SentenceItem +- id +- sentence_id +- word_id +- position + +### Document +- id +- user_id +- sentence_id +- storage_location +- updated_at + +--- + +## 5. API Surface (Illustrative) + +- GET /api/words +- GET /api/words/{id} +- POST /api/sentences +- PUT /api/sentences/{id} +- GET /api/documents +- POST /api/auth/login + +--- + +## 6. Video Handling + +- Short video clips per word +- Consistent framing +- Loop-ready +- Neutral background + +Sentence playback = sequential video concatenation. + +--- + +## 7. Non-Functional Requirements + +- Desktop-first responsive UI +- High accessibility +- Fast filtering/search +- Stateless backend +- Secure auth + +--- + +## 8. Architecture (Technology-Agnostic) + +- SPA frontend +- REST backend +- Relational database +- Object storage for videos +- OAuth + JWT authentication + +--- + +## 9. Functional Parity Criteria + +- Dictionary search and filters +- Sentence creation +- Video sentence playback +- Cloud document storage +- Authentication + +--- + +## 10. Scope + +This document defines a **1:1 functional replication** of the Znakovni.hr application, +intended for controlled demonstration and AI-driven implementation planning.