Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
dd56ad5
chore: upgrade packages
ManiruzzamanAkash May 31, 2026
f1075bf
moved button component with @wordpress/buttons
ManiruzzamanAkash May 31, 2026
c352980
Refactor admin UI to @wordpress/components + DataViews and expand job…
ManiruzzamanAkash May 31, 2026
4d02f4b
Add agent guidance (AGENTS.md, CLAUDE.md)
ManiruzzamanAkash May 31, 2026
2845740
Fix CI: pin Composer platform to PHP 7.4 and update WPCS 3.0 ruleset
ManiruzzamanAkash May 31, 2026
4b5132a
Add job categories database schema, seeding, and domain layer.
ManiruzzamanAkash May 31, 2026
54377bc
Expose job categories REST API and wire jobs to category IDs.
ManiruzzamanAkash May 31, 2026
58704c5
Add job categories data store and integrate categories into jobs state.
ManiruzzamanAkash May 31, 2026
6843219
Add job categories admin UI and connect jobs form to categories.
ManiruzzamanAkash May 31, 2026
5507bb7
Add companies database schema, seeding, and domain layer.
ManiruzzamanAkash May 31, 2026
021fdde
Expose companies REST API and wire jobs to companies table.
ManiruzzamanAkash May 31, 2026
28b3351
Add companies data store and category stats endpoint support.
ManiruzzamanAkash May 31, 2026
df8ae49
Add shared SideDrawer and refactor category drawer layout.
ManiruzzamanAkash May 31, 2026
133e546
Add companies admin UI, dashboard org stats, and job form integration.
ManiruzzamanAkash May 31, 2026
b285fd4
Rebrand to Job Manager and add server-side jobs list filtering with U…
ManiruzzamanAkash May 31, 2026
d43dd12
Upgrade build tooling for Interactivity API blocks.
ManiruzzamanAkash May 31, 2026
4562fff
Add PHP infrastructure for registering interactivity job blocks.
ManiruzzamanAkash May 31, 2026
4019195
Add dynamic job detail field blocks with PHP front-end rendering.
ManiruzzamanAkash May 31, 2026
4c1bcf4
Add jobs board query blocks with Interactivity API controllers.
ManiruzzamanAkash May 31, 2026
ff8e35c
Add job apply button block with configurable label support.
ManiruzzamanAkash May 31, 2026
d88b84e
Add job page block and shared pattern picker for the block editor.
ManiruzzamanAkash May 31, 2026
2a9e980
Register block patterns and ship FSE job board templates.
ManiruzzamanAkash May 31, 2026
7c2ad65
Add job detail permalink routing and expose permalinks in REST.
ManiruzzamanAkash May 31, 2026
cca37b4
Seed default jobs board page and add PageService helpers.
ManiruzzamanAkash May 31, 2026
bdfe0a6
Add block template service for configurable job detail layouts.
ManiruzzamanAkash May 31, 2026
c1b9665
Add global plugin settings option and REST endpoints.
ManiruzzamanAkash May 31, 2026
ec55577
Add settings admin page and front-end jobs interactivity scripts.
ManiruzzamanAkash May 31, 2026
100107f
Add jobs board front-end styles with BEM layout conventions.
ManiruzzamanAkash May 31, 2026
566babb
Polish admin jobs UI with avatars, sticky form header, and menu icon.
ManiruzzamanAkash May 31, 2026
64a0898
Wire plugin bootstrap for jobs board links and rewrite rules.
ManiruzzamanAkash May 31, 2026
887878e
Document job board blocks, patterns, settings, and SCSS conventions.
ManiruzzamanAkash May 31, 2026
6c60338
Bump plugin version to 1.0.0.
ManiruzzamanAkash May 31, 2026
55dedbc
Align Playwright e2e setup with wp-env and add admin smoke tests.
ManiruzzamanAkash May 31, 2026
d5be3c1
Fix frontend jobs search and keep filters in the URL.
ManiruzzamanAkash May 31, 2026
ccb33ea
Add color and border supports to the Job Template block.
ManiruzzamanAkash May 31, 2026
87bc12e
Align jobs search input and button control heights.
ManiruzzamanAkash May 31, 2026
a578f0e
docs: add v1.0.0 demo screenshots for admin and job board
ManiruzzamanAkash May 31, 2026
bc39196
docs: rewrite REST API reference and refresh README for v1.0.0
ManiruzzamanAkash May 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 0 additions & 1 deletion .github/workflows/phpunit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ jobs:
- name: Composer install and build
run: |
composer install
composer update
composer dump-autoload -o

- name: Running the phpunit tests
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
.phpunit.result.cache
.DS_Store
/dist
auth.json

# Playwright
/test-results/
Expand Down
5 changes: 4 additions & 1 deletion .wp-env.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"core": null,
"phpVersion": "7.4",
"plugins": [
"."
Expand All @@ -16,8 +17,10 @@
"./tests/e2e/gutenberg-test-plugin-disables-the-css-animations"
],
"config": {
"FS_METHOD": "direct",
"WP_DEBUG": false,
"WP_TESTS_DOMAIN": "localhost"
}
}
}
}
}
234 changes: 234 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
# AGENTS.md

Guidance for any AI coding agent (Cursor, Claude Code, Codex, Copilot, etc.)
working in this repository. `CLAUDE.md` defers to this file.

## Project

**WP React Kit / "Job Place"** — a WordPress plugin with a React admin UI
(`src/`) backed by a PHP REST API (`includes/`). It manages job postings
(CRUD, publish/draft, dashboard stats) inside `wp-admin`, and ships a
**public job board** built with Gutenberg blocks and the Interactivity API.

- Text domain: `jobplace`
- PHP namespace root: `Akash\JobPlace` (PSR-4 → `includes/`)
- REST namespace: `job-place/v1`
- Block namespace: `wrc/*` (e.g. `wrc/jobs-list`, `wrc/job-page`)
- Build output: `build/` (committed-ignored; produced by `@wordpress/scripts`)

## Commands

```bash
npm run build # Production build (webpack) → build/
npm run start # Watch/dev build
npm run test:unit # Jest unit tests (jest-unit.config.js)
npm run makepot # Regenerate languages/jobplace.pot
php -l <file> # Lint a PHP file
```

After editing `src/`, run `npm run build` and confirm it compiles. After
editing PHP, run `php -l` on changed files.

## Directory map

```
job-place.php # Bootstrap: DI container, hooks, activation
includes/ # PHP (PSR-4: Akash\JobPlace\*)
Abstracts/ # BaseModel, RESTController, DBMigrator
Admin/ # Admin menu registration
Assets/Manager.php # Enqueues scripts/styles (incl. DataViews CSS)
Blocks/ # PatternRegistry, BlockTemplatesService, EditorData
Common/Keys.php # Option-name constants
Databases/
Migrations/ # dbDelta schemas (Jobs, JobType, Company, …)
Seeder/ # Demo data
Jobs/ # Domain: Job model, JobStatus, Manager (queries)
REST/ # Controllers + Api.php (route registry)
Routing/ # Job detail permalinks + template router
Setup/ # Installer, Upgrader, PageSeeder
Common/Settings.php # Global plugin settings (option jobplace_settings)
WordPress/Pages/ # PageService (default Jobs page)
Traits/ # InputSanitizer, Queryable
blocks-interactivity.php # Interactivity API script module registration
src/ # React/TypeScript admin app + block sources
index.tsx # Entry: mounts <App/> into #jobplace
App.tsx # HashRouter + routes; runs useMenuFix
routes/ # Route table (path → page component)
pages/ # Route pages (HomePage, jobs/JobsPage, …)
components/ # UI (jobs/, dashboard/, Notices.tsx)
blocks/ # Gutenberg blocks (jobs board + job fields)
scripts/ # Interactivity modules (@jobplace/jobs, …)
styles/ # Shared front-end SCSS (jobs-board.scss)
data/jobs/ # wp-data Redux store (see below)
interfaces/ # Shared TypeScript types
hooks/ utils/ style/ # Helpers, MenuFix, global SCSS
templates/
patterns/ # Block patterns (*.php → register_block_pattern)
templates/ # Plugin block templates (single-job.html)
```

> Note: several legacy folders under `src/components/` are empty leftovers from
> the starter kit (button, table, modal, inputs, …). Don't reintroduce them —
> use `@wordpress/components` / `@wordpress/dataviews` instead.

## Admin app (wp-admin)

- React via `@wordpress/element`; routing via `react-router-dom` **HashRouter**.
- Lists render with `@wordpress/dataviews` (`DataViews`); forms with `DataForm`.
- **State** lives in a single `@wordpress/data` store `wp-react/jobs`
(`src/data/jobs/`):
- `actions.ts` — action creators + generator actions (`setFilters`, `saveJob`,
`deleteJobs`). Generator actions yield `controls` and re-throw on error.
- `controls.ts` — `apiFetch` side effects (FETCH/CREATE/UPDATE/DELETE).
- `resolvers.ts` — lazy data loaders for selectors (`getJobs`, `getJobStats`,
`getJobDetail`, dropdowns). Resolved values are **cached**.
- `selectors.ts`, `reducer.ts`, `default-state.ts`, `types.ts`, `endpoint.ts`.
- **Read data through the store**, not raw `apiFetch` in components.
- Jobs list company column uses `CompanyAvatar` (logo or initials placeholder;
no broken images when Clearbit/external URLs fail).
- Notices: dispatch `@wordpress/notices` (`createSuccessNotice`/`createErrorNotice`
with `{ type: 'snackbar' }`); `src/components/Notices.tsx` renders them.

## Job board blocks (front-end)

Built with `@wordpress/scripts` (webpack), **Interactivity API** for client-side
search/pagination without full page reloads, and PHP `view.php` render templates.

### Core blocks

| Block | Role |
|-------|------|
| `wrc/jobs-list` | Query root: toolbar, inner template, no-results, pagination |
| `wrc/jobs-template` | Repeats inner blocks per job (`<article class="jobplace-job-card">`) |
| `wrc/job-page` | Single job detail root (used in `single-job` template) |
| `wrc/job-title`, `wrc/job-company`, … | Dynamic job fields (context-driven) |
| `wrc/jobs-search`, `wrc/jobs-count`, `wrc/jobs-pagination`, `wrc/jobs-no-results` | Board chrome |

Shared editor utilities: `src/blocks/shared/` (`pattern-utils`, `patterns-toolbar`,
`pattern-selection-modal`, `preview-jobs`). List editor uses `TemplateListEdit`
(`src/components/TemplateListEdit.js`) for multi-job previews.

### Block patterns

PHP files in `templates/patterns/*.php` return `title`, `categories`,
`blockTypes` (`wrc/jobs-list` or `wrc/job-page`), `priority`, and `content`.
Registered by `includes/Blocks/PatternRegistry.php`.

- **Jobs list:** `jobs-board-default`, `jobs-board-grid`, `jobs-board-compact`,
`jobs-board-featured`
- **Job detail:** `job-detail-default`, `job-detail-compact`, `job-detail-split`

In the editor, select **Jobs List** or **Job Page** → toolbar **Replace** opens
the pattern picker (same UX as SureCart shop patterns).

### Default Jobs page

On activation (and for existing installs via `Upgrader::maybe_seed_pages`),
`Setup/PageSeeder` creates a published page (slug `jobs`) with the default board
pattern. ID stored in `jobplace_jobs_page_id`. Plugin row links: View / Edit Jobs
Board.

### Settings (admin + REST)

- Admin route: `#/settings` (submenu **Settings**).
- REST: `GET/PUT /job-place/v1/settings` (`SettingsController`, `manage_options`).
- `Common/Settings.php` stores `jobplace_settings` and drives:
- **Global job detail layout** — pattern slug from `templates/patterns/job-detail-*.php`;
merged into `single-job` template via `Settings::get_single_job_template_content()`
(used by `JobDetailRouter` and `BlockTemplatesService`). Theme-customized
Single Job templates (`source: custom`) still take precedence.
- **Jobs list page** — select which page is the board (`jobplace_jobs_page_id`).
- **Default jobs per page** — fallback in `JobsQuery` when a block has no `perPage`.
- **Default apply button text** — used in `job-apply-button/view.php` when empty.
- Permalink base remains on **Settings → Permalinks** (`PermalinkService`); linked from UI.

### Single job URLs

`includes/Routing/` handles custom permalinks and `single-job` block template
(`templates/templates/single-job.html`). Settings under Job Manager permalinks.

### SEO / markup conventions

- Job list wrapper uses `role="list"`; each job is `<article role="listitem">`.
- Job titles render as links (`wrc/job-title`) to the job detail URL.
- Use heading blocks in patterns where appropriate; keep one `h1` per page in
the theme template.
- Descriptions output escaped text; apply button supports real URLs or `mailto:`.
- Prefer theme + block spacing (`blockGap`) over hard-coded margins in patterns.

## SCSS conventions

- **No Tailwind.** Use SCSS or `@wordpress/components`.
- **BEM** with `jobplace-` prefix. Nest elements/modifiers with `&__element` and
`&--modifier` under the block root — do not repeat the full class name:

```scss
.jobplace-jobs-template {
width: 100%;

&__item {
display: flex;
}

&.is-layout-grid {
gap: var(--wp--style--block-gap, 1rem);
}
}
```

- Shared front-end board styles: `src/styles/jobs-board.scss` (enqueued as
`jobplace-jobs-board`). Per-block overrides: `src/blocks/<block>/style.scss`.
- Respect `--wp--style--block-gap` on template/list blocks; avoid fixed `gap`
values that override the block editor spacing control.
- Admin-only styles: `src/pages/jobs/jobs-page.scss`, `src/components/jobs/job-form.scss`.

## Backend architecture

- `Api.php` registers each `*Controller` (extends `RESTController`).
- Controllers validate via JSON schema (`get_item_schema`), map request →
DB array (`prepare_item_for_database`), and format DB → response
(`Job::to_array` / `prepare_item_for_response`).
- `Jobs/Manager.php` runs queries through the `Job` model (extends `BaseModel`).
- Status is derived: `is_active` (DB) → `status` (`published`/`draft`) via
`JobStatus`.

## Schema changes / migrations

1. Add the column to `includes/Databases/Migrations/JobsMigration.php`. Keep
`CREATE TABLE` (NOT `IF NOT EXISTS`) so `dbDelta` can ALTER existing tables.
2. Bump `Upgrader::DB_VERSION` in `includes/Setup/Upgrader.php` — the admin-side
upgrader auto-runs `dbDelta` on the next page load (no reactivation needed).
3. Wire it through: model defaults + sanitize (`Jobs/Job.php`), REST schema +
`prepare_item_for_database` (`REST/JobsController.php`), then the TS side
(`interfaces/jobs.ts`, `data/jobs/default-state.ts`, form/list fields).

## Conventions

- UI (admin): only `@wordpress/components` + `@wordpress/dataviews`.
- PHP: WordPress Coding Standards. Sanitize input, escape output.
- TypeScript: keep types in `src/interfaces/`; convert select values to numbers
on change where the model expects ints.
- Comments: only when the *why* is non-obvious; short and natural.

## Gotchas

- DataViews ships CSS separately and is `sideEffects:false`; `webpack.config.js`
copies its stylesheet into `build/` and `Assets/Manager.php` enqueues it.
- `dbDelta` is picky: `CREATE TABLE` (no `IF NOT EXISTS`), two spaces in
`PRIMARY KEY (\`id\`)`, lowercase types, `KEY` not `INDEX`.
- Job Template **block spacing** in the editor applies via `__unstableLayoutClassNames`
and `--wp--style--block-gap`; the edit component must pass `useBlockProps()` from
the parent block, not a second wrapper without layout classes.
- Interactivity scripts are ES modules in `src/scripts/`; registered in
`includes/blocks-interactivity.php`.

## Git commit policy (important)

- **Never commit or push on your own.** Only when the user explicitly asks in
that message ("commit", "commit this", "commit and push"). Finishing a task is
not permission to commit.
- Commit as the repo's existing git identity, which already matches the GitHub
account (`ManiruzzamanAkash`). Do **not** edit git config or pass `--author`.
- **No agent attribution of any kind** in the message, author, or committer.
- Stage explicit paths only (never `git add .` / `-A`). Use a HEREDOC for
multi-line messages. Don't GPG-sign unless asked.
94 changes: 94 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# CLAUDE.md

Guidance for Claude Code in this repository. This mirrors `AGENTS.md`; keep the
two in sync when either changes.

## Project

**WP React Kit / "Job Place"** — a WordPress plugin with a React admin UI
(`src/`) backed by a PHP REST API (`includes/`). It manages job postings
(CRUD, publish/draft, dashboard stats) inside `wp-admin`, and ships a
**public job board** built with Gutenberg blocks and the Interactivity API.

- Text domain: `jobplace`
- PHP namespace root: `Akash\JobPlace` (PSR-4 → `includes/`)
- REST namespace: `job-place/v1`
- Block namespace: `wrc/*` (e.g. `wrc/jobs-list`, `wrc/job-page`)
- Build output: `build/` (produced by `@wordpress/scripts`)

## Commands

```bash
npm run build # Production build (webpack) → build/
npm run start # Watch/dev build
npm run test:unit # Jest unit tests (jest-unit.config.js)
npm run makepot # Regenerate languages/jobplace.pot
php -l <file> # Lint a PHP file
```

After editing `src/`, run `npm run build` and confirm it compiles. After
editing PHP, run `php -l` on changed files.

## Directory map

```
job-place.php # Bootstrap: DI container, hooks, activation
includes/ # PHP (PSR-4: Akash\JobPlace\*)
Blocks/ # PatternRegistry, BlockTemplatesService, EditorData
Routing/ # Job detail permalinks + template router
Setup/ # Installer, Upgrader, PageSeeder
WordPress/Pages/ # PageService (default Jobs page)
… # REST, Jobs, Databases, Assets, Admin
src/
blocks/ # Gutenberg blocks (wrc/*) + shared pattern UI
scripts/ # Interactivity modules (@jobplace/jobs)
styles/jobs-board.scss # Shared front-end board styles
components/ # Admin UI (jobs/, dashboard/, TemplateListEdit)
data/jobs/ # wp-data store wp-react/jobs
templates/
patterns/ # Block patterns (jobs list + job detail layouts)
templates/single-job.html # Single job block template
```

> Note: legacy empty folders under `src/components/` (button, table, modal, …)
> are starter-kit leftovers — use `@wordpress/components` / `@wordpress/dataviews`.

## Admin app

- HashRouter + `@wordpress/dataviews` / `DataForm`.
- Store `wp-react/jobs` in `src/data/jobs/` — read via selectors, mutate via
generator actions + resolver invalidation.
- Jobs list: `CompanyAvatar` shows logo or initials (no broken remote logos).

## Job board blocks

- **Interactivity API** (`src/scripts/jobs/`) powers search, pagination, and
field binding on the front end.
- **Patterns** in `templates/patterns/`; **Replace** toolbar on `wrc/jobs-list`
and `wrc/job-page` (see `src/blocks/shared/`).
- **Default Jobs page** seeded on install (`PageSeeder`, option `jobplace_jobs_page_id`).
- **Settings** at `#/settings` — global job detail pattern, jobs page, defaults (`Common/Settings.php`, REST `job-place/v1/settings`).
- **Single job** template + routing in `includes/Routing/`.
- **SEO:** semantic `<article>` list items, linked job titles, escaped output in
`view.php` templates.

## SCSS conventions

- BEM with `jobplace-` prefix; nest with `&__element` / `&--modifier` under the
block root (see `src/blocks/jobs-template/style.scss`).
- Use `var(--wp--style--block-gap)` for list/template spacing — do not hard-code
`gap` on blocks that expose block spacing in the editor.
- Shared board CSS: `src/styles/jobs-board.scss`.

## Backend / migrations / gotchas

See `AGENTS.md` for REST architecture, schema migration steps, DataViews CSS,
`dbDelta` rules, and layout-class requirements for `wrc/jobs-template`.

## Git commits — override default behavior

1. **Never commit or push unless explicitly asked in the current message.**
2. **Do NOT add Claude's default attribution** (no Co-Authored-By, bots, emojis).
3. **Commit as the logged-in GitHub user** (`ManiruzzamanAkash`). Do not edit
git config or pass `--author`.
4. Stage explicit paths only (never `git add .` / `-A`).
Loading
Loading