# Localization & RTL Support Guide

> The `feat/localization` branch introduces a production-grade, config-driven Localization and Right-to-Left (RTL) rendering system. Built on top of the `base` branch, it allows the application to dynamically switch between English and Arabic (and any future language) — fully flipping the UI layout direction without a single hardcoded CSS override.

---

## Table of Contents

1. [Module Overview](#1-module-overview)
2. [What You Inherit](#2-what-you-inherit)
3. [Deep Dive: Features & Functionality](#3-deep-dive-features--functionality)
4. [File Paths & Architecture](#4-file-paths--architecture)
5. [Step-by-Step Usage Guide](#5-step-by-step-usage-guide)
6. [Precautions & Future Development Rules](#6-precautions--future-development-rules)

---

## 1. Module Overview

This module manages the application's language and text direction. When a user switches their language (e.g., from English to Arabic), the system stores the selection in the session, applies it globally via a middleware on every subsequent request, and instructs all layouts to render in the correct direction (`ltr` or `rtl`). The switch is seamless — no page architecture changes are required.

---

## 2. What You Inherit

By merging with the **Base** branch, this feature inherits:

- **Alpine.js & Axios:** The language switcher (`lang-toggle`) uses Alpine.js for the dropdown interaction and standard HTML forms with CSRF for the secure POST switch request.
- **Blade Component System:** The `<x-common.lang-toggle />` component plugs directly into any layout or navbar that already uses the base branch's Blade component conventions.
- **Tailwind CSS Build Pipeline:** The RTL rendering relies on Tailwind's logical properties (`ms-*`, `me-*`, `ps-*`, `pe-*`) which are already compiled through the base branch's `vite.config.js` and `tailwind.config.js`.

---

## 3. Deep Dive: Features & Functionality

### Config-Driven Language Registry
All supported languages live in a single file — `config/localization.php`. Adding or removing a language is a one-line change. There are no hardcoded language lists anywhere in the application. The config exposes two keys:
- **`languages`**: A map of locale code → display name, used by the language switcher UI.
- **`rtl_locales`**: An array of locale codes that trigger RTL layout. The rest of the system reads this array automatically.

### Global `SetLocale` Middleware
The `SetLocale` middleware is registered in `bootstrap/app.php` as a global web middleware. It runs on every request, reads the `locale` key from the session, validates it against the `localization.languages` config, and sets Laravel's application locale. If the session value is absent or invalid, it gracefully falls back to the `app.locale` value in `.env`.

### Secure Language Switch Route
The language switcher submits a **POST form** (not a GET link) protected by a `@csrf` token to the `locale.switch` named route. The route handler validates the submitted locale against the config whitelist before writing it to the session — preventing arbitrary locale injection.

### Helper Functions (`app_direction` & `is_rtl`)
Two global PHP helpers are autoloaded from `app/helpers.php`:
- **`is_rtl(): bool`** — Returns `true` if the current locale is in the `rtl_locales` config array.
- **`app_direction(): string`** — Returns `'rtl'` or `'ltr'`. Used directly in the `dir=""` attribute of every `<html>` tag across all layouts.

### `window.__direction` JavaScript Bridge
Every layout template exposes the current direction to the frontend via `window.__direction = '{{ app_direction() }}'`. JavaScript modules (e.g., `front-layout.js`, `dropdown.js`) read this global to make RTL-aware positioning decisions at runtime without needing to inspect the DOM.

### Language Toggle UI Component
The `<x-common.lang-toggle />` Blade component renders a dropdown that lists all languages from the config. Each option submits a dedicated POST form. The active language is highlighted. The component reads directly from the config — no hardcoded language arrays in the view.

### PHP-Based Translation Files
Translation strings are organized as **PHP array files** inside namespaced subdirectories under `lang/`. Each language has its own folder (`lang/en/`, `lang/ar/`) containing files grouped by domain (e.g., `auth.php`, `buttons.php`, `messages.php`, `pages/dashboard.php`). This is more scalable than a single flat JSON file and supports dot-notation namespacing like `__('buttons.save')`.

---

## 4. File Paths & Architecture

### Configuration & Helpers
- **`config/localization.php`**: The single source of truth for all supported languages and RTL locale codes.
- **`app/helpers.php`**: Defines the `is_rtl()` and `app_direction()` global helper functions. Autoloaded via `composer.json`.

### Routing & Middleware
- **`routes/web.php`**: Contains the `POST locale/{locale}` route (named `locale.switch`) that validates and stores the chosen locale in the session.
- **`app/Http/Middleware/SetLocale.php`**: The global middleware that reads the session locale and calls `App::setLocale()` on every request.
- **`bootstrap/app.php`**: Registers `SetLocale::class` as a global web middleware.

### Views & Components
- **`resources/views/components/common/lang-toggle.blade.php`**: The language switcher dropdown UI component.
- **`resources/views/layouts/app-full.blade.php`**: Main authenticated layout — uses `app_direction()` on the `<html>` tag and exposes `window.__direction`.
- **`resources/views/layouts/front/app.blade.php`**: Front-facing (public) layout — same `app_direction()` integration.
- **`resources/views/layouts/fullscreen.blade.php`**: Fullscreen layout (auth screens) — same integration.
- **`resources/views/layouts/error.blade.php`**: Error page layout — same integration.

### Translation Files
- **`lang/en/`**: All English translation files, organized by domain.
- **`lang/ar/`**: All Arabic translation files, mirroring the `en/` structure exactly.

### JavaScript
- **`resources/js/front-layout.js`**: Reads `window.__direction` to calculate RTL-aware horizontal positioning for fixed dropdown panels.
- **`resources/js/dropdown.js`**: Also reads `window.__direction` to flip dropdown anchor logic for RTL layouts.
- **`resources/css/app.css`**: Contains `[dir="rtl"]` CSS overrides for browser-native elements (e.g., `<select>` dropdowns) that cannot be fixed by Tailwind logical properties alone.

---

## 5. Step-by-Step Usage Guide

### Step 1: Verify Environment & Dependencies
Run the following after pulling this branch to ensure the helper functions are autoloaded:
```bash
composer dump-autoload
```
> If you see a `Call to undefined function app_direction()` error, this command will fix it.

### Step 2: Add a New Language (e.g., French)

**a) Register the language in the config:**
Open `config/localization.php` and add the new locale to the `languages` array:
```php
'languages' => [
    'en' => 'English',
    'ar' => 'العربية',
    'fr' => 'Français', // Add this line
],
```

**b) Register it as RTL if applicable:**
If the new language is Right-to-Left (Arabic, Hebrew, Urdu, etc.), also add its code to `rtl_locales`:
```php
'rtl_locales' => ['ar', 'he'], // Add the code here
```
For LTR languages like French, no change to `rtl_locales` is needed.

**c) Create the translation files:**
Create a new folder `lang/fr/` and mirror the file structure from `lang/en/`. Copy the keys from each English file and provide the translated strings.

The folder structure should look like this:
```
lang/
├── en/
│   ├── auth.php
│   ├── buttons.php
│   ├── messages.php
│   └── pages/
│       └── dashboard.php
│       └── ...
├── ar/         ← existing
└── fr/         ← your new folder
    ├── auth.php
    ├── buttons.php
    └── ...
```

### Step 3: Using Translations in Blade Views
Use Laravel's `__()` helper with dot-notation to reference namespaced translation keys:
```blade
{{ __('buttons.save') }}
{{ __('pages/dashboard.welcome') }}
```

### Step 4: Protecting New Routes / Layouts
Any new layout file you create must integrate with the direction system. Add `app_direction()` to the `<html>` tag and expose `window.__direction` in a script block:
```html
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" dir="{{ app_direction() }}">
```
```html
<script>
    window.__direction = '{{ app_direction() }}';
</script>
```

### Step 5: Testing the Flow
1. Start the dev server and open the application.
2. Click the language toggle in the navbar and switch to **Arabic (العربية)**.
3. Observe the entire UI flipping to RTL — the sidebar, navigation, icons, and text alignment should all mirror correctly.
4. Switch back to **English** and confirm the LTR layout is restored.
5. Verify the session persists across a page refresh.

---

## 6. Precautions & Future Development Rules

To maintain the structural integrity of RTL layouts, all future development **must** adhere to the following rules.

### A. Strict Use of RTL-Compatible Tailwind Classes
**NEVER** use physical directional utilities (Left/Right). **ALWAYS** use Logical Properties (Start/End). If you use hardcoded directional classes, the UI will break when the user switches to an RTL language.

| Physical (DO NOT USE) | Logical (USE THIS) | Description |
| :--- | :--- | :--- |
| `ml-*`, `mr-*` | `ms-*`, `me-*` | Margin Start / Margin End |
| `pl-*`, `pr-*` | `ps-*`, `pe-*` | Padding Start / Padding End |
| `left-*`, `right-*` | `start-*`, `end-*` | Absolute Positioning |
| `border-l-*`, `border-r-*` | `border-s-*`, `border-e-*` | Border Placement |
| `rounded-l-*`, `rounded-r-*` | `rounded-s-*`, `rounded-e-*` | Border Radius |
| `text-left`, `text-right` | `text-start`, `text-end` | Text Alignment |

### B. Guarding Blade Icon Components
When refactoring or building new components, **do not alter the literal names of Blade icon components** just because they contain the words `left` or `right`.
- **Incorrect:** `<x-heroicon-o-arrow-end-on-rectangle />` — This will crash the page because the icon file doesn't exist.
- **Correct:** `<x-heroicon-o-arrow-right-on-rectangle />`

If an icon needs to point the opposite way in RTL mode, use Tailwind's `rtl:` variant to flip it dynamically:
```html
<x-heroicon-o-arrow-right class="rtl:-scale-x-100" />
```

### C. Custom CSS Overrides (Forms & Selects)
Native HTML inputs and plugins (like `@tailwindcss/forms`) occasionally have hardcoded directional properties. For example, `<select>` dropdowns hardcode the caret icon on the right side.
We override these globally in `resources/css/app.css` using the `[dir="rtl"]` selector:
```css
[dir="rtl"] select {
    background-position: left 0.5rem center;
    padding-right: 0.75rem;
    padding-left: 2.5rem;
}
```
*If you build a custom component that relies on background-images or absolute positioning that Tailwind logical properties cannot fix, add your override to `app.css` under the `[dir="rtl"]` selector.*

### D. JavaScript RTL Awareness
If you write a JavaScript module that positions elements dynamically (e.g., tooltips, dropdowns, overlays), read the `window.__direction` global to determine the current direction:
```js
const isRtl = window.__direction === 'rtl';
const anchorSide = isRtl ? rect.right - panelWidth : rect.left;
```
**Never** inspect the DOM `dir` attribute directly in JS — always use `window.__direction` as it is set server-side before the page renders.
