# Maven Group CMS — Laravel Backend Setup

This folder contains the **application code** (models, migrations, controllers, routes,
seeders) for the CMS backend. Because this was generated outside a live server, you'll
merge it into a fresh Laravel skeleton rather than running the app directly from here.

## 1. Create the base Laravel project

```bash
composer create-project laravel/laravel:^11.0 maven-backend
cd maven-backend
```

## 2. Copy in the provided files

Copy these folders/files from this package **into** your new `maven-backend` project,
overwriting where prompted:

```
app/Models/*                → maven-backend/app/Models/
app/Http/Controllers/*      → maven-backend/app/Http/Controllers/
app/Http/Middleware/*       → maven-backend/app/Http/Middleware/
app/Policies/*              → maven-backend/app/Policies/
app/Providers/AppServiceProvider.php → maven-backend/app/Providers/
database/migrations/*       → maven-backend/database/migrations/
database/seeders/*          → maven-backend/database/seeders/
routes/api.php              → maven-backend/routes/api.php
routes/web.php              → maven-backend/routes/web.php
bootstrap/app.php           → maven-backend/bootstrap/app.php
bootstrap/providers.php     → maven-backend/bootstrap/providers.php
config/cors.php             → maven-backend/config/cors.php
composer.json               → merge the "require" section into your composer.json
.env.example                → merge relevant keys into your .env
```

## 3. Install packages

```bash
composer require laravel/sanctum spatie/laravel-permission spatie/laravel-sluggable intervention/image
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
```
(You already have the permission migration provided in `database/migrations` — if the
publish command adds a duplicate migration, delete the one it generates and keep ours,
which matches the `config/permission.php` it also publishes.)

## 4. Configure environment

```bash
cp .env.example .env    # or merge keys manually
php artisan key:generate
```

Set your DB credentials, `FRONTEND_URL` (your Next.js site), and `ADMIN_URL` (the React
admin dashboard) in `.env`.

## 5. Storage & database

```bash
php artisan storage:link
php artisan migrate
php artisan db:seed
```

This creates the default **super admin** login:

```
email:    admin@mavengroup.com
password: ChangeMe!12345
```

**Change this password immediately after first login.**

### Importing your existing blog posts

`database/legacy-blog-posts.json` (included in this package) is your 268
existing posts extracted from the Next.js site's `lib/blogPosts.ts`. Import
them with:

```bash
php artisan blog:import-legacy
```

Note: that file only ever had title/excerpt/image/category/date — the full
article body was being scraped live from the old WordPress site on each page
view, not stored anywhere. This command imports everything *except* body
content, which comes in empty. The Next.js blog detail page falls back to the
old scrape for any post whose CMS `content` is empty, so nothing breaks — but
re-pasting each article's body into the dashboard over time (or pointing me
at a WordPress export) will let you fully retire the scraper.

### Importing your real site settings & service pages

`database/legacy-service-pages.json` (included) holds the actual content
currently live for your 12 service pages (CRM, SEM, e-commerce, ERP, etc.),
extracted from their fallback data. Import everything — site settings
(contact info, social links, WhatsApp number), SEO defaults, and these 12
pages' Page Builder blocks — with:

```bash
php artisan content:import-real
```

Safe to re-run — it updates existing rows rather than duplicating them.

## 6. Run it

```bash
php artisan serve
```

API is now live at `http://localhost:8000/api`.

## Roles created by the seeder

| Role         | Can do |
|--------------|--------|
| `super-admin`| Everything: users, roles, pages, blog, media, site settings, SEO |
| `admin`      | Create/edit/publish pages & blog posts, manage media — no user management, no site settings |
| `seo-manager`| Edit SEO fields on pages/posts, manage redirects, manage global SEO settings — cannot edit page/post body content |

Field-level permission checks (e.g. an `seo-manager` can only touch the SEO fields of a
page, not its content blocks) are enforced in `PageController@update` and
`BlogPostController@update`.

## API overview

**Public (no auth) — for the Next.js site:**
- `GET /api/public/pages` — list published pages
- `GET /api/public/pages/{slug}` — page + ordered blocks
- `GET /api/public/blog` — paginated posts (filter by `?category=`, `?tag=`)
- `GET /api/public/blog/{slug}` — single post (increments view count)
- `GET /api/public/settings/site` — logo, contact info, social links
- `GET /api/public/settings/seo` — GA/GTM IDs, default meta, robots.txt content

**Admin (Bearer token via Sanctum) — for the React dashboard:**
- `POST /api/admin/login` → `{ token, user }`
- `GET /api/admin/dashboard` — counts + recent activity
- `apiResource /api/admin/pages` + `/pages/{page}/blocks` (CRUD + `PUT /blocks/reorder`)
- `apiResource /api/admin/blog-posts`, `/blog-taxonomy`, `/blog-categories`, `/blog-tags`
- `/api/admin/media` — upload/list/delete (multipart `file` field)
- `/api/admin/users`, `/api/admin/roles`
- `/api/admin/settings/site`, `/api/admin/settings/seo`
- `/api/admin/redirects`

Send the token as `Authorization: Bearer <token>` on every admin request.

## Page Builder data model

A `Page` has many `PageBlock` rows, each with a `type` (e.g. `hero`, `rich_text`,
`image`, `video`, `gallery`, `services`, `why_us`, `faq`, `cta_banner`, `ticker`,
`testimonials`, `custom_html`) and a `data` JSON column holding whatever fields that
block needs (headline, body, image URL, video URL, list items, etc). The React admin's
drag-and-drop builder reorders blocks by posting the new order to
`PUT /pages/{page}/blocks/reorder`. Your Next.js frontend fetches
`GET /api/public/pages/{slug}` and renders each block by `type`, mapping it to the
matching existing React component (Hero, Services, FAQ, etc).
