# Shavhani Attorneys — Rebuild Plan

> **Source:** Cloned from Laravel 12 + Jetstream/Livewire + Tailwind CMS at `c:\xampp\htdocs\shavhani-attorneys`  
> **Do not edit:** `mafanedza-dietitian` (reference only)

---

## Client (locked)

| Field | Value |
|-------|-------|
| Firm | Shavhani Attorneys |
| Tagline | Think Is Practical |
| Logo | SA mark (red S, blue A) |
| Website | www.shavhaniattorneys.co.za |
| Email | info@shavhaniattorneys.co.za |
| Tel | +27 64 530 9035 / +27 76 312 4974 |
| Fax | 086 414 2006 |
| Hours | Mon–Fri 08:00–17:00 (weekends closed) |
| Address | placeholder until client confirms |

**Practice areas to seed:** Civil Litigations, Road Accidents Claims, PRASA, Labour Disputes, Divorce, Unlawful Arrest, Family Law, Commercial Law, Deceased Estates, Wills.

**Brand colors:** navy `#2F4A8A`, blue `#1E4F9C`, red CTA `#C84B4B`, surface `#F4F5F7`, ink `#2F3236`. Avoid generic AI-template looks (purple gradients, Inter-only). Use **DM Sans + Source Serif 4**. Use the office exterior photo for hero when available.

---

## Phase 1 — Boot

```bash
composer install && npm install
```

Create `.env`:

- `APP_NAME="Shavhani Attorneys"`
- `APP_URL` (local or production URL)
- `DB_CONNECTION=mysql`
- `DB_DATABASE=shavhani_attorneys`

```bash
php artisan key:generate
php artisan migrate:fresh --seed --force
npm run build
```

**Admin login after seed:** `admin@example.com` / `password`

---

## Phases 2–6 — Build

1. **Tailwind:** replace `dietitian-green` with `firm-navy` / `firm-blue` / `firm-red`
2. **Seeders:** Shavhani settings + 10 practice areas + law FAQs
3. **Logo component:** SA SVG fallback; nav/footer rebrand
4. **UI labels:** Services → Practice Areas; Bookings → Consultation Requests
5. **Rewrite** home, about, services, legal pages for law firm (not medical)
6. **SchemaService:** `LegalService` / `Attorney` (not `MedicalBusiness` / `Dietitian`)
7. **UserWay widget:** middle-right positioning (keep from source project)

---

## Production fixes — apply from day one

These were fixed on the dietitian site; ensure Shavhani has them baked in.

### A. Unstyled site / missing CSS

- Production needs `public/build/` (`manifest.json` + compiled assets)
- Run `npm run build` locally or on server; deploy entire `public/build/` folder
- Then: `php artisan optimize:clear`

### B. Vite dev URLs on production (`http://[::1]:5173/...` CORS errors)

- Set `APP_ENV=production` and `APP_DEBUG=false`
- Ensure `public/build/` exists (see A) — never rely on Vite dev server in production
- Run `php artisan optimize:clear` after env/build changes

### C. Shared hosting: `vite: Permission denied`

```bash
chmod -R +x node_modules/.bin
# fallback:
node node_modules/vite/bin/vite.js build
```

### D. Admin login 500: Undefined variable `$slot`

`resources/views/layouts/app.blade.php` and `guest.blade.php` must support both Jetstream `$slot` and Blade `@yield('content')`:

```blade
@isset($slot)
    {{ $slot }}
@else
    @yield('content')
@endisset
```

### E. Migration order: bookings FK before services table exists

- `bookings.service_id` without inline FK in create migration
- Separate migration adds FK after services table exists

### F. Seeder: service duration must be integer (not `'45 minutes'` strings)

### G. Default DB: `config/database.php` default `mysql` (not sqlite)

### H. Legal blade parse errors: no chained inline `@if` in `@section` titles

Use proper `@if` / `@elseif` / `@else` blocks in `legal/terms.blade.php` and `legal/privacy-policy.blade.php`.

### I. Post-deploy cache clear

Always run `php artisan optimize:clear` (or at minimum `view:clear`) after uploading layout/view changes.

---

## Production fix audit (clone status)

| Fix | Status in clone |
|-----|-------------------|
| A. `public/build/` | ❌ Not built yet — run `npm run build` in Phase 1 |
| B. Production env | ⚠️ Verify `.env` on deploy |
| C. Vite permissions | ⚠️ Document in README for shared hosting |
| D. `$slot` / `@yield` | ✅ Already in `app.blade.php` and `guest.blade.php` |
| E. Bookings FK order | ✅ Separate migration `add_service_foreign_key_to_bookings_table` |
| F. Integer durations | ✅ Seeder uses integers (30, 45, 60) |
| G. MySQL default | ✅ `config/database.php` defaults to `mysql` |
| H. Legal blade titles | ⚠️ Verify during legal page rewrite (currently dietitian copy) |
| I. Cache clear | ⚠️ Document in README deploy checklist |

---

## Production deploy checklist (document in README)

- [ ] `.env`: `APP_ENV=production`, `APP_DEBUG=false`, correct `APP_URL`
- [ ] Upload `public/build/` after every frontend change
- [ ] `php artisan migrate --force` on server
- [ ] `php artisan optimize:clear`
- [ ] Verify admin login, public pages styled, no `:5173` URLs in page source

---

## Commit policy

Work through all phases. **Commit only when explicitly asked.**

---

## Kickoff prompt (copy into new Cursor window)

Open **File → Open Folder → `c:\xampp\htdocs\shavhani-attorneys`**, then paste this into chat:

```
Execute the Shavhani Attorneys rebuild. This project was cloned from a Laravel 12 + Jetstream/Livewire + Tailwind CMS at c:\xampp\htdocs\shavhani-attorneys. The dietitian source is at mafanedza-dietitian — do not edit that folder.

Client (locked)
Firm: Shavhani Attorneys
Tagline: Think Is Practical
Logo: SA mark (red S, blue A)
Website: www.shavhaniattorneys.co.za
Email: info@shavhaniattorneys.co.za
Tel: +27 64 530 9035 / +27 76 312 4974
Fax: 086 414 2006
Hours: Mon–Fri 08:00–17:00 (weekends closed)
Address: placeholder until client confirms
Practice areas to seed: Civil Litigations, Road Accidents Claims, PRASA, Labour Disputes, Divorce, Unlawful Arrest, Family Law, Commercial Law, Deceased Estates, Wills.

Brand colors: navy #2F4A8A, blue #1E4F9C, red CTA #C84B4B, surface #F4F5F7, ink #2F3236. Avoid generic AI-template looks (purple gradients, Inter-only). Use DM Sans + Source Serif 4. Use the office exterior photo for hero when available.

Phase 1 — Boot
composer install && npm install
Create .env: APP_NAME="Shavhani Attorneys", APP_URL, MySQL DB_DATABASE=shavhani_attorneys, DB_CONNECTION=mysql
php artisan key:generate
php artisan migrate:fresh --seed --force
npm run build
Admin login after seed: admin@example.com / password

Phases 2–6 — Build
Tailwind: replace dietitian-green with firm-navy / firm-blue / firm-red
Seeders: Shavhani settings + 10 practice areas + law FAQs
Logo component: SA SVG fallback; nav/footer rebrand
UI labels: Services → Practice Areas; Bookings → Consultation Requests
Rewrite home, about, services, legal pages for law firm (not medical)
SchemaService: LegalService / Attorney (not MedicalBusiness / Dietitian)
UserWay widget: middle-right positioning (keep from source project)

Production fixes — apply from day one
These were fixed on the dietitian site; ensure Shavhani has them baked in:

A. Unstyled site / missing CSS
Production needs public/build/ (manifest.json + compiled assets)
Run npm run build locally or on server; deploy entire public/build/ folder
Then: php artisan optimize:clear

B. Vite dev URLs on production (http://[::1]:5173/... CORS errors)
Set APP_ENV=production and APP_DEBUG=false
Ensure public/build/ exists (see A) — never rely on Vite dev server in production
Run php artisan optimize:clear after env/build changes

C. Shared hosting: vite: Permission denied
chmod -R +x node_modules/.bin
# fallback:
node node_modules/vite/bin/vite.js build

D. Admin login 500: Undefined variable $slot
resources/views/layouts/app.blade.php and guest.blade.php must support both Jetstream $slot and Blade @yield('content'):
@isset($slot)
    {{ $slot }}
@else
    @yield('content')
@endisset

E. Migration order: bookings FK before services table exists
bookings.service_id without inline FK in create migration
Separate migration adds FK after services table exists

F. Seeder: service duration must be integer (not '45 minutes' strings)

G. Default DB: config/database.php default mysql (not sqlite)

H. Legal blade parse errors: no chained inline @if in @section titles — use proper @if/@elseif/@else blocks in legal/terms.blade.php and legal/privacy-policy.blade.php

I. Post-deploy cache clear: always run php artisan optimize:clear (or at minimum view:clear) after uploading layout/view changes

Production deploy checklist (document in README)
.env: APP_ENV=production, APP_DEBUG=false, correct APP_URL
Upload public/build/ after every frontend change
php artisan migrate --force on server
php artisan optimize:clear
Verify admin login, public pages styled, no 5173 URLs in page source

Work through all phases. Commit only when I ask.

Alternatively, read REBUILD_PLAN.md in the project root for the full plan.
```
