npm package: @studyjoyful/shared
Description: Shared code for StudyJoyful Web and App (i18n, constants, types, utils)
Author: StudyJoyful
Latest version: 1.0.12

# @studyjoyful/shared

Shared code for StudyJoyful Web and App.

## 🎯 Design Principles

### i18n: Single Source of Truth

> ⚠️ **Critical**: This package is the **ONLY** source of translations.
> Web and App do NOT have their own `locales/` directories.

| Principle         | Description                             |
| ----------------- | --------------------------------------- |
| **Single Source** | All translations here, nowhere else     |
| **English Only**  | Singapore market = English only         |
| **Modular**       | Split by feature (auth, chat, tasks...) |
| **Shared**        | Web + App import from this package      |

## 📦 Modules

| Module        | Description          | Exports                                   |
| ------------- | -------------------- | ----------------------------------------- |
| **i18n**      | Internationalization | `resources`, `namespaces`, `defaultNS`    |
| **constants** | Shared constants     | `EXAMPLES_BY_GRADE`, `getExamplesByGrade` |
| **types**     | Type definitions     | `ChildGrade`, `Subject`, `Example`        |
| **utils**     | Utility functions    | `randomSelect`, `shuffle`                 |

## 🚀 Usage

### Installation (yarn link)

```bash
# In this package
cd studyjoyful-shared
yarn link

# In Web
cd ../studyjoyful-web
yarn link "@studyjoyful/shared"

# In App
cd ../studyjoyful-app
yarn link "@studyjoyful/shared"
```

### App Metro Config

The App requires special Metro configuration:

```javascript
// metro.config.js
const sharedPackagePath = path.resolve(__dirname, "../studyjoyful-shared");

config.watchFolders = [sharedPackagePath];
config.resolver.nodeModulesPaths = [
  path.resolve(__dirname, "node_modules"),
  path.resolve(sharedPackagePath, "node_modules"),
];

const ALIASES = {
  "@studyjoyful/shared": sharedPackagePath + "/src",
};
```

### Import Examples

```typescript
// i18n
import { resources, namespaces, defaultNS } from "@studyjoyful/shared";

// Constants
import { EXAMPLES_BY_GRADE, getExamplesByGrade } from "@studyjoyful/shared";

// Types
import type { ChildGrade, Subject, Example } from "@studyjoyful/shared";

// Utils
import { randomSelect, shuffle } from "@studyjoyful/shared";
```

## 📁 Structure

```
src/
├── index.ts           # Main exports
├── i18n/
│   ├── index.ts
│   └── locales/
│       └── en/        # English translations
│           ├── common.json
│           ├── auth.json
│           ├── chat.json
│           ├── tasks.json
│           ├── learning.json
│           ├── profile.json
│           ├── errors.json
│           └── sidebar.json
├── constants/
│   ├── index.ts
│   └── examples.ts    # Learning examples
├── types/
│   ├── index.ts
│   ├── child.ts       # ChildGrade, Subject
│   └── common.ts      # PaginationParams
└── utils/
    ├── index.ts
    └── random.ts      # randomSelect, shuffle
```

## 🔧 Development

```bash
# Type check
npx tsc --noEmit

# After changes, test in both:
# 1. Web (hot reload)
# 2. App (metro refresh)
```

## 📝 Adding New Content

1. Create file in appropriate module
2. Export from module's `index.ts`
3. Re-export from main `src/index.ts`
4. Test in both Web and App

## 🌍 Adding Translations

### DO:

```bash
# Add to this package
src/i18n/locales/en/auth.json    # ✅ Correct
```

### DON'T:

```bash
# Never create locales in consumer projects
studyjoyful-app/locales/         # ❌ WRONG
studyjoyful-web/locales/         # ❌ WRONG
```

### Translation File Structure

```json
// src/i18n/locales/en/auth.json
{
  "welcome": {
    "title": "StudyJoyful",
    "subtitle": "Turn homework into 10-minute learning games",
    "getStarted": "Get Started"
  },
  "errors": {
    "signInFailed": "Sign In Failed",
    "tryAgain": "Please try again"
  }
}
```

### Usage in Consumer Projects

```typescript
// lib/i18n.ts (in Web or App)
import { resources, namespaces, defaultNS } from "@studyjoyful/shared";

// Component
import { useTranslation } from "react-i18next";

function WelcomeScreen() {
  const { t } = useTranslation("auth");
  return <Text>{t("welcome.title")}</Text>;
}
```

---

**Package**: `@studyjoyful/shared`  
**Version**: 1.0.0  
**Consumers**: studyjoyful-web, studyjoyful-app  
**Language**: English only (Singapore market)