{{--
Add New User — docs/wireframes-v12/add-user.html (the card at lines 76-291),
minus everything CR-13 §0 removes.
## Shape
ONE `.card`. Inside it, a `.form-section` per heading — each with its
`.form-section-title` and the wireframe's own icon — and a `.card-footer` at
the bottom. Fields are laid out by v12's `.form-row.form-row-2/-3` grids,
not by Bootstrap columns, which is why no field carries a `group-class`: the
row owns the columns and `.form-group` owns its own margin.
## The twin rule (recipe §9)
This file and users/edit.blade.php are twins. Every field is written out in
both, and neither includes a shared form partial. **A field added, removed
or renamed here must be mirrored in edit.blade.php in the same commit.**
### These twins are NOT in TwinViewParityTest, and that is deliberate
Every other twin pair in this application is in that test's dataset. This
one cannot be, and the reason is the client's own instruction rather than an
omission: CR-13 §0.6 makes Password and Confirm Password **required on add
and optional on edit**, so the two screens' required-attribute sets differ by
design — which is precisely the thing
`it('marks the same field names required on the create and edit twins')`
exists to fail on. Adding the pair to the dataset would mean either
weakening that assertion for every other module or asserting something
untrue about this one.
CR-13 §0.1 also forbids new test files and lists the pinned tests that may
be touched; TwinViewParityTest is on that list "if it enumerates" and it
does, but what it would enumerate here is a pair it cannot compare. So the
guardrail this pair actually gets is the docblock rule above, and whoever
edits one of them owes the other.
### What this screen has that its twin does not
* the action (`users.store`) and the method (POST, not PUT);
* the submit label — "Save User", where the twin says "Update User";
* the rule source — StoreUserRequest, where the twin names
UpdateUserRequest (whose email rule ignores the row being edited and
whose password rules are nullable);
* the header wording and the breadcrumb's last crumb;
* **required Password and Confirm Password**, with the wireframe's own
placeholders. The twin's are optional and say so in the placeholder;
* **a longer set of `data-validate-*` markers** on those two fields, for
the same reason: this screen re-arms `required` on Password and
`required` + `equalTo` on Confirm Password, where the twin re-arms
`equalTo` alone (CR-13.1 B1). The Email and Role markers are identical
on both;
* no Account Activity section — a user who does not exist yet has no
account history;
* no Deactivate/Activate button in the footer — same reason.
## Deliberate differences from the wireframe
* **The Username field is gone** (client instruction, CR-13 §0.3;
add-user.html:119-123). Login is by email and always has been —
config/fortify.php:48 — and there is no username column to fill. Its
slot in the Account Details row is taken by Password, and an empty
`.form-group` keeps the row at three tracks so the two password fields
stay a third wide rather than stretching to halves.
* **The Permissions section is gone** (client, §0.4; lines 163-254). Its
sixteen checkboxes were per-user direct permissions; access is by role
here, and the profile screen still SHOWS what a role grants.
* **The Additional Settings section is gone** (client, §0.5; lines
256-284). Max Login Attempts, Session Timeout, Two-Factor and
Notification Preferences are four features this application does not
have.
* **The Role select lists the REAL spatie roles** (decision D3), narrowed
by guard §4.6.2a — "Super Admin" is not offered to anybody who is not
one — where v12 hardcodes eight fictional options.
* **No Status control.** Unlike the broker form (CR-12 decision D1), a new
user is always created `active` and their standing is changed by the
status action afterwards, with its own confirmation and its own guards
(CR-13 §4.5). A select here would have been a fourth way to reach a
decision that has three guards on it.
--}}
@extends('layouts.app')
@section('title', __('users.create_title'))
@section('breadcrumbs')