Say "student" and "profile" in the UI, not "child" and "family"
CI / Tests (PHP 8.1) (pull_request) Successful in 41s
CI / Tests (PHP 8.2) (pull_request) Successful in 40s
CI / No Debug Code (pull_request) Successful in 2s
CI / Coding Standards (pull_request) Successful in 2m55s
CI / PHPStan (pull_request) Successful in 3m1s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m43s
CI / Build Plugin Zip (pull_request) Skipped
CI / Tests (PHP 8.1) (pull_request) Successful in 41s
CI / Tests (PHP 8.2) (pull_request) Successful in 40s
CI / No Debug Code (pull_request) Successful in 2s
CI / Coding Standards (pull_request) Successful in 2m55s
CI / PHPStan (pull_request) Successful in 3m1s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m43s
CI / Build Plugin Zip (pull_request) Skipped
Sweep the translatable strings across the frontend templates, the admin screens, the editor previews and the block inserter entry. Nothing else moves: the database columns, request parameters, form field names, CSS classes, the us_family shortcode and the us-scheduler/family block name are contracts with existing installs and with post content people have already saved, so renaming them would break sites for no user-visible gain. Two strings are reworded rather than swapped, because the direct substitution reads wrong: - The students list said "Child of Jane" and now says "Managed by Jane". "Student of Jane" would read as a teacher's pupil, which is exactly the wrong idea in a music studio. - A managed account is now "a managed student account" rather than "a student account", which would not distinguish it from the account holder. The guardian feature doc gains a short section on the split, so the next person to work on it does not read the mismatch as drift and "fix" it. Closes #144 Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -13,6 +13,9 @@ each change under the current top section as you work.
|
|||||||
|
|
||||||
## [1.3.1]
|
## [1.3.1]
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- The interface now says **student** where it said "child" and **profile** where it said "family". The `[us_family]` page is headed **Your profile**, its form is **Add a student**, signup asks for a **Student's name**, and the wp-admin students list and student screen both label the relationship **Profile**. Two strings were reworded rather than swapped: the students list reads **Managed by _name_** (a bare "Student of _name_" would read as a teacher's pupil), and a managed account is described as a **managed student account** so it is not confused with the account holder. Internal names — database columns, request parameters, form field names, the `us_family` shortcode and the `us-scheduler/family` block — are unchanged, since they are contracts with existing installs and saved post content.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Upcoming lesson rows no longer render on top of each other. The row's text sits in inline elements that a theme can pull out of normal flow, which dropped the date and time onto the lesson title and the status pill onto the Cancel button; those elements are now pinned into flow alongside the rest of the panel's theme-proofing. The rows held behind **Show all** also stayed visible under the `div { display: block }` reset that many themes still carry, since `[hidden]` is only a browser default — they are now hidden for real.
|
- Upcoming lesson rows no longer render on top of each other. The row's text sits in inline elements that a theme can pull out of normal flow, which dropped the date and time onto the lesson title and the status pill onto the Cancel button; those elements are now pinned into flow alongside the rest of the panel's theme-proofing. The rows held behind **Show all** also stayed visible under the `div { display: block }` reset that many themes still carry, since `[hidden]` is only a browser default — they are now hidden for real.
|
||||||
|
|
||||||
|
|||||||
+6
-3
@@ -284,10 +284,13 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'us-scheduler/family',
|
name: 'us-scheduler/family',
|
||||||
title: __('Family', 'unsupervised-schedular'),
|
title: __('Profile', 'unsupervised-schedular'),
|
||||||
description: __('Lets a parent or guardian add, edit and remove the children they book lessons for.', 'unsupervised-schedular'),
|
description: __('Lets a parent or guardian add, edit and remove the students they book lessons for.', 'unsupervised-schedular'),
|
||||||
icon: 'groups',
|
icon: 'groups',
|
||||||
keywords: ['family', 'children', 'guardian', 'parent'],
|
// 'family' and 'children' are kept as search terms only — they are
|
||||||
|
// never displayed, and the block answered to them before it was
|
||||||
|
// renamed, so anyone reaching for the old word still finds it.
|
||||||
|
keywords: ['profile', 'students', 'family', 'children', 'guardian', 'parent'],
|
||||||
shortcode: 'us_family',
|
shortcode: 'us_family',
|
||||||
attributes: {
|
attributes: {
|
||||||
loginPageId: { type: 'number', default: 0 },
|
loginPageId: { type: 'number', default: 0 },
|
||||||
|
|||||||
@@ -9,6 +9,19 @@ A guardian may also be a student in their own right — they appear in their own
|
|||||||
"who is this for?" selector alongside their children, so a parent taking lessons
|
"who is this for?" selector alongside their children, so a parent taking lessons
|
||||||
next to their kids needs only the one account.
|
next to their kids needs only the one account.
|
||||||
|
|
||||||
|
## Vocabulary: "child" in the code, "student" in the UI
|
||||||
|
|
||||||
|
The interface says **student** and **profile**; the code says **child** and
|
||||||
|
**family**. This is deliberate, not drift. Every identifier below — the
|
||||||
|
`us_guardian_links` columns, `GuardianService::createChild()`, the `children[]`
|
||||||
|
request parameters, the `child_name` form fields, the `us-scheduler/family`
|
||||||
|
block name and the `[us_family]` shortcode — is a stable contract with the
|
||||||
|
database, saved post content and existing installs, so renaming them would break
|
||||||
|
sites for no user-visible gain. Only the strings a person reads were changed.
|
||||||
|
|
||||||
|
When adding to this feature, keep the split: internal names follow the
|
||||||
|
data model, translatable strings follow the interface.
|
||||||
|
|
||||||
## Core Decision: children are accountless WordPress users
|
## Core Decision: children are accountless WordPress users
|
||||||
|
|
||||||
Every `student_id` column in `src/Schema.php` (`us_lessons`, `us_payments`,
|
Every `student_id` column in `src/Schema.php` (`us_lessons`, `us_payments`,
|
||||||
@@ -159,7 +172,7 @@ child.
|
|||||||
|
|
||||||
## Managing children
|
## Managing children
|
||||||
|
|
||||||
`[us_family]` (block: **Family**) renders the guardian's manage-children screen:
|
`[us_family]` (block: **Profile**) renders the guardian's manage-children screen:
|
||||||
list the children, add one, edit a name/date of birth, remove one.
|
list the children, add one, edit a name/date of birth, remove one.
|
||||||
|
|
||||||
- **Add** creates another accountless child user and links it. Account-scope
|
- **Add** creates another accountless child user and links it. Account-scope
|
||||||
@@ -219,11 +232,11 @@ than being left as a single-student-only path.
|
|||||||
|
|
||||||
## Admin
|
## Admin
|
||||||
|
|
||||||
- **Students list** gains a **Guardian / Children** column: a child links to its
|
- **Students list** gains a **Profile** column: a child links to its
|
||||||
guardian's detail screen, a guardian lists its children as links. Children are
|
guardian's detail screen, a guardian lists its children as links. Children are
|
||||||
listed alongside every other student rather than nested, so nothing about
|
listed alongside every other student rather than nested, so nothing about
|
||||||
finding a student changes.
|
finding a student changes.
|
||||||
- **Student detail** gains a **Family** panel — the guardian (for a child) or
|
- **Student detail** gains a **Profile** panel — the guardian (for a child) or
|
||||||
the children (for a guardian), each a link to the other's screen — and the
|
the children (for a guardian), each a link to the other's screen — and the
|
||||||
credit balance shown is the **payer's** balance, labelled with whose it is, so
|
credit balance shown is the **payer's** balance, labelled with whose it is, so
|
||||||
an admin looking at a child sees the family balance that will actually settle
|
an admin looking at a child sees the family balance that will actually settle
|
||||||
|
|||||||
@@ -88,8 +88,8 @@ All actions are nonce-protected POSTs handled on the detail page:
|
|||||||
`tests/Unit/Payment/PaymentRepositoryTest.php`
|
`tests/Unit/Payment/PaymentRepositoryTest.php`
|
||||||
|
|
||||||
## Family Relationships
|
## Family Relationships
|
||||||
The students list gains a **Family** column — a child links to their guardian,
|
The students list gains a **Profile** column — a child links to their guardian,
|
||||||
a guardian lists their children — and the student screen a **Family** panel. A
|
a guardian lists their children — and the student screen a **Profile** panel. A
|
||||||
child's listed email is their guardian's, since a child's own address is an
|
child's listed email is their guardian's, since a child's own address is an
|
||||||
undeliverable placeholder, and the credit balance shown is the payer's, labelled
|
undeliverable placeholder, and the credit balance shown is the payer's, labelled
|
||||||
with whose account holds it. See `parent-guardian-accounts.md`.
|
with whose account holds it. See `parent-guardian-accounts.md`.
|
||||||
|
|||||||
@@ -286,14 +286,14 @@ class RegistrationPage {
|
|||||||
// Everything is validated before a single user is created, so a bad child
|
// Everything is validated before a single user is created, so a bad child
|
||||||
// block never leaves a half-registered family behind.
|
// block never leaves a half-registered family behind.
|
||||||
if ( $isGuardian && [] === $children ) {
|
if ( $isGuardian && [] === $children ) {
|
||||||
return esc_html__( 'Please add at least one child, or uncheck the parent/guardian option.', 'unsupervised-schedular' );
|
return esc_html__( 'Please add at least one student, or uncheck the parent/guardian option.', 'unsupervised-schedular' );
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ( $isGuardian ? array_column( $children, 'answers' ) : [ $answers ] as $set ) {
|
foreach ( $isGuardian ? array_column( $children, 'answers' ) : [ $answers ] as $set ) {
|
||||||
foreach ( $accountQuestions as $question ) {
|
foreach ( $accountQuestions as $question ) {
|
||||||
if ( $question->isRequired && '' === trim( (string) ( $set[ (int) $question->id ] ?? '' ) ) ) {
|
if ( $question->isRequired && '' === trim( (string) ( $set[ (int) $question->id ] ?? '' ) ) ) {
|
||||||
return $isGuardian
|
return $isGuardian
|
||||||
? esc_html__( 'Please answer all required registration questions for each child.', 'unsupervised-schedular' )
|
? esc_html__( 'Please answer all required registration questions for each student.', 'unsupervised-schedular' )
|
||||||
: esc_html__( 'Please answer all required registration questions.', 'unsupervised-schedular' );
|
: esc_html__( 'Please answer all required registration questions.', 'unsupervised-schedular' );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -189,16 +189,16 @@ class BlockPreview {
|
|||||||
'<h4>%s</h4><p><label for="us-child-name">%s</label><input type="text" id="us-child-name"></p>'
|
'<h4>%s</h4><p><label for="us-child-name">%s</label><input type="text" id="us-child-name"></p>'
|
||||||
. '<p><label for="us-child-dob">%s</label><input type="date" id="us-child-dob"></p>'
|
. '<p><label for="us-child-dob">%s</label><input type="date" id="us-child-dob"></p>'
|
||||||
. '<p><button type="button" disabled>%s</button></p>',
|
. '<p><button type="button" disabled>%s</button></p>',
|
||||||
esc_html__( 'Add a child', 'unsupervised-schedular' ),
|
esc_html__( 'Add a student', 'unsupervised-schedular' ),
|
||||||
esc_html__( 'Name', 'unsupervised-schedular' ),
|
esc_html__( 'Name', 'unsupervised-schedular' ),
|
||||||
esc_html__( 'Date of birth', 'unsupervised-schedular' ),
|
esc_html__( 'Date of birth', 'unsupervised-schedular' ),
|
||||||
esc_html__( 'Add child', 'unsupervised-schedular' )
|
esc_html__( 'Add student', 'unsupervised-schedular' )
|
||||||
);
|
);
|
||||||
|
|
||||||
return sprintf(
|
return sprintf(
|
||||||
'<div class="us-family">%s<h3>%s</h3><ul class="us-family-list">%s</ul><form class="us-family-add">%s</form></div>',
|
'<div class="us-family">%s<h3>%s</h3><ul class="us-family-list">%s</ul><form class="us-family-add">%s</form></div>',
|
||||||
self::note( __( 'Editor preview — signed-in guardians see and manage their own children here.', 'unsupervised-schedular' ) ),
|
self::note( __( 'Editor preview — signed-in guardians see and manage their own students here.', 'unsupervised-schedular' ) ),
|
||||||
esc_html__( 'Your family', 'unsupervised-schedular' ),
|
esc_html__( 'Your profile', 'unsupervised-schedular' ),
|
||||||
$children,
|
$children,
|
||||||
$add
|
$add
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ class ChildLoginGate {
|
|||||||
if ( $user instanceof \WP_User && GuardianService::isChild( (int) $user->ID ) ) {
|
if ( $user instanceof \WP_User && GuardianService::isChild( (int) $user->ID ) ) {
|
||||||
return new \WP_Error(
|
return new \WP_Error(
|
||||||
'us_child_account',
|
'us_child_account',
|
||||||
esc_html__( 'This is a child account and cannot be signed in to. Please sign in with the parent or guardian account.', 'unsupervised-schedular' )
|
esc_html__( 'This is a managed student account and cannot be signed in to. Please sign in with the parent or guardian account.', 'unsupervised-schedular' )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class FamilyPage {
|
|||||||
'<p>%s <a href="%s">%s</a>.</p>',
|
'<p>%s <a href="%s">%s</a>.</p>',
|
||||||
esc_html__( 'Please', 'unsupervised-schedular' ),
|
esc_html__( 'Please', 'unsupervised-schedular' ),
|
||||||
esc_url( $this->loginUrl( $loginPageId ) ),
|
esc_url( $this->loginUrl( $loginPageId ) ),
|
||||||
esc_html__( 'log in to manage your family', 'unsupervised-schedular' )
|
esc_html__( 'log in to manage your profile', 'unsupervised-schedular' )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,7 +168,7 @@ class FamilyPage {
|
|||||||
private function firstMissingAnswer( array $questions, array $answers ): ?\WP_Error {
|
private function firstMissingAnswer( array $questions, array $answers ): ?\WP_Error {
|
||||||
foreach ( $questions as $question ) {
|
foreach ( $questions as $question ) {
|
||||||
if ( $question->isRequired && '' === trim( (string) ( $answers[ (int) $question->id ] ?? '' ) ) ) {
|
if ( $question->isRequired && '' === trim( (string) ( $answers[ (int) $question->id ] ?? '' ) ) ) {
|
||||||
return new \WP_Error( 'missing_answer', __( 'Please answer all required questions for this child.', 'unsupervised-schedular' ) );
|
return new \WP_Error( 'missing_answer', __( 'Please answer all required questions for this student.', 'unsupervised-schedular' ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,9 +237,9 @@ class FamilyPage {
|
|||||||
*/
|
*/
|
||||||
private function noticeFor( string $result ): string {
|
private function noticeFor( string $result ): string {
|
||||||
return match ( $result ) {
|
return match ( $result ) {
|
||||||
self::RESULT_ADDED => __( 'Child added.', 'unsupervised-schedular' ),
|
self::RESULT_ADDED => __( 'Student added.', 'unsupervised-schedular' ),
|
||||||
self::RESULT_UPDATED => __( 'Details updated.', 'unsupervised-schedular' ),
|
self::RESULT_UPDATED => __( 'Details updated.', 'unsupervised-schedular' ),
|
||||||
self::RESULT_REMOVED => __( 'Child removed.', 'unsupervised-schedular' ),
|
self::RESULT_REMOVED => __( 'Student removed.', 'unsupervised-schedular' ),
|
||||||
default => '',
|
default => '',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class GuardianService {
|
|||||||
public function createChild( int $guardianId, string $name, string $dateOfBirth = '', string $relationship = '' ): int|\WP_Error {
|
public function createChild( int $guardianId, string $name, string $dateOfBirth = '', string $relationship = '' ): int|\WP_Error {
|
||||||
$name = trim( $name );
|
$name = trim( $name );
|
||||||
if ( '' === $name ) {
|
if ( '' === $name ) {
|
||||||
return new \WP_Error( 'missing_name', __( 'Please give each child a name.', 'unsupervised-schedular' ) );
|
return new \WP_Error( 'missing_name', __( 'Please give each student a name.', 'unsupervised-schedular' ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
$email = $this->childEmail();
|
$email = $this->childEmail();
|
||||||
@@ -89,7 +89,7 @@ class GuardianService {
|
|||||||
if ( $linkId <= 0 ) {
|
if ( $linkId <= 0 ) {
|
||||||
$this->deleteUser( $userId );
|
$this->deleteUser( $userId );
|
||||||
|
|
||||||
return new \WP_Error( 'link_failed', __( 'Could not add this child. Please contact the studio.', 'unsupervised-schedular' ) );
|
return new \WP_Error( 'link_failed', __( 'Could not add this student. Please contact the studio.', 'unsupervised-schedular' ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return $userId;
|
return $userId;
|
||||||
@@ -104,12 +104,12 @@ class GuardianService {
|
|||||||
*/
|
*/
|
||||||
public function updateChild( int $guardianId, int $studentId, string $name, string $dateOfBirth = '' ): ?\WP_Error {
|
public function updateChild( int $guardianId, int $studentId, string $name, string $dateOfBirth = '' ): ?\WP_Error {
|
||||||
if ( ! $this->guardians->isGuardianOf( $guardianId, $studentId ) ) {
|
if ( ! $this->guardians->isGuardianOf( $guardianId, $studentId ) ) {
|
||||||
return new \WP_Error( 'forbidden', __( 'That is not one of your children.', 'unsupervised-schedular' ) );
|
return new \WP_Error( 'forbidden', __( 'That is not one of your students.', 'unsupervised-schedular' ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
$name = trim( $name );
|
$name = trim( $name );
|
||||||
if ( '' === $name ) {
|
if ( '' === $name ) {
|
||||||
return new \WP_Error( 'missing_name', __( 'Please give each child a name.', 'unsupervised-schedular' ) );
|
return new \WP_Error( 'missing_name', __( 'Please give each student a name.', 'unsupervised-schedular' ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = wp_update_user(
|
$result = wp_update_user(
|
||||||
@@ -139,13 +139,13 @@ class GuardianService {
|
|||||||
*/
|
*/
|
||||||
public function removeChild( int $guardianId, int $studentId ): ?\WP_Error {
|
public function removeChild( int $guardianId, int $studentId ): ?\WP_Error {
|
||||||
if ( ! $this->guardians->isGuardianOf( $guardianId, $studentId ) ) {
|
if ( ! $this->guardians->isGuardianOf( $guardianId, $studentId ) ) {
|
||||||
return new \WP_Error( 'forbidden', __( 'That is not one of your children.', 'unsupervised-schedular' ) );
|
return new \WP_Error( 'forbidden', __( 'That is not one of your students.', 'unsupervised-schedular' ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( [] !== $this->bookings->findByStudent( $studentId ) || [] !== $this->enrollments->findByStudent( $studentId ) ) {
|
if ( [] !== $this->bookings->findByStudent( $studentId ) || [] !== $this->enrollments->findByStudent( $studentId ) ) {
|
||||||
return new \WP_Error(
|
return new \WP_Error(
|
||||||
'has_history',
|
'has_history',
|
||||||
__( 'This child has lessons or enrolments on record and cannot be removed here. Please contact the studio.', 'unsupervised-schedular' )
|
__( 'This student has lessons or enrolments on record and cannot be removed here. Please contact the studio.', 'unsupervised-schedular' )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ $renderLessons = static function (array $rows, bool $withActions = false): void
|
|||||||
</form>
|
</form>
|
||||||
|
|
||||||
<?php if ($guardian !== null || ! empty($children)) : ?>
|
<?php if ($guardian !== null || ! empty($children)) : ?>
|
||||||
<h2><?php esc_html_e('Family', 'unsupervised-schedular'); ?></h2>
|
<h2><?php esc_html_e('Profile', 'unsupervised-schedular'); ?></h2>
|
||||||
<?php $detailUrl = static fn(int $id): string => add_query_arg(['page' => $pageSlug, 'student_id' => $id], admin_url('admin.php')); ?>
|
<?php $detailUrl = static fn(int $id): string => add_query_arg(['page' => $pageSlug, 'student_id' => $id], admin_url('admin.php')); ?>
|
||||||
<?php if ($guardian !== null) : ?>
|
<?php if ($guardian !== null) : ?>
|
||||||
<p>
|
<p>
|
||||||
@@ -123,7 +123,7 @@ $renderLessons = static function (array $rows, bool $withActions = false): void
|
|||||||
);
|
);
|
||||||
?>
|
?>
|
||||||
</p>
|
</p>
|
||||||
<p class="description"><?php esc_html_e('This is a child account: it has no login of its own, and its email address is a placeholder that cannot receive mail.', 'unsupervised-schedular'); ?></p>
|
<p class="description"><?php esc_html_e('This is a managed student account: it has no login of its own, and its email address is a placeholder that cannot receive mail.', 'unsupervised-schedular'); ?></p>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<?php if (! empty($children)) : ?>
|
<?php if (! empty($children)) : ?>
|
||||||
<p><?php esc_html_e('Books and pays for:', 'unsupervised-schedular'); ?></p>
|
<p><?php esc_html_e('Books and pays for:', 'unsupervised-schedular'); ?></p>
|
||||||
@@ -293,7 +293,7 @@ $renderLessons = static function (array $rows, bool $withActions = false): void
|
|||||||
<?php
|
<?php
|
||||||
printf(
|
printf(
|
||||||
/* translators: %s: name of the parent/guardian whose account holds the balance. */
|
/* translators: %s: name of the parent/guardian whose account holds the balance. */
|
||||||
esc_html__('Held on %s’s account — the family shares one balance.', 'unsupervised-schedular'),
|
esc_html__('Held on %s’s account — the profile shares one balance.', 'unsupervised-schedular'),
|
||||||
esc_html($payer['name'])
|
esc_html($payer['name'])
|
||||||
);
|
);
|
||||||
?>
|
?>
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ $familyCell = static function (array $student) use ($pageSlug): string {
|
|||||||
if ($student['guardian'] !== null) {
|
if ($student['guardian'] !== null) {
|
||||||
return sprintf(
|
return sprintf(
|
||||||
/* translators: %s: linked name of the parent/guardian who books for this student. */
|
/* translators: %s: linked name of the parent/guardian who books for this student. */
|
||||||
esc_html__('Child of %s', 'unsupervised-schedular'),
|
esc_html__('Managed by %s', 'unsupervised-schedular'),
|
||||||
$link($student['guardian']['id'], $student['guardian']['name'])
|
$link($student['guardian']['id'], $student['guardian']['name'])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -51,7 +51,7 @@ $familyCell = static function (array $student) use ($pageSlug): string {
|
|||||||
<tr>
|
<tr>
|
||||||
<th><?php esc_html_e('Name', 'unsupervised-schedular'); ?></th>
|
<th><?php esc_html_e('Name', 'unsupervised-schedular'); ?></th>
|
||||||
<th><?php esc_html_e('Email', 'unsupervised-schedular'); ?></th>
|
<th><?php esc_html_e('Email', 'unsupervised-schedular'); ?></th>
|
||||||
<th><?php esc_html_e('Family', 'unsupervised-schedular'); ?></th>
|
<th><?php esc_html_e('Profile', 'unsupervised-schedular'); ?></th>
|
||||||
<th><?php esc_html_e('Registered', 'unsupervised-schedular'); ?></th>
|
<th><?php esc_html_e('Registered', 'unsupervised-schedular'); ?></th>
|
||||||
<th><?php esc_html_e('Upcoming lessons', 'unsupervised-schedular'); ?></th>
|
<th><?php esc_html_e('Upcoming lessons', 'unsupervised-schedular'); ?></th>
|
||||||
<th><?php esc_html_e('Active enrolments', 'unsupervised-schedular'); ?></th>
|
<th><?php esc_html_e('Active enrolments', 'unsupervised-schedular'); ?></th>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ if (! defined('ABSPATH')) {
|
|||||||
*/
|
*/
|
||||||
?>
|
?>
|
||||||
<div class="us-family">
|
<div class="us-family">
|
||||||
<h3><?php esc_html_e('Your family', 'unsupervised-schedular'); ?></h3>
|
<h3><?php esc_html_e('Your profile', 'unsupervised-schedular'); ?></h3>
|
||||||
|
|
||||||
<?php if ($notice !== '') : ?>
|
<?php if ($notice !== '') : ?>
|
||||||
<p class="us-success"><?php echo esc_html($notice); ?></p>
|
<p class="us-success"><?php echo esc_html($notice); ?></p>
|
||||||
@@ -27,7 +27,7 @@ if (! defined('ABSPATH')) {
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<?php if (empty($children)) : ?>
|
<?php if (empty($children)) : ?>
|
||||||
<p><?php esc_html_e('You have not added any children yet. Add one below to start booking lessons for them.', 'unsupervised-schedular'); ?></p>
|
<p><?php esc_html_e('You have not added any students yet. Add one below to start booking lessons for them.', 'unsupervised-schedular'); ?></p>
|
||||||
<?php else : ?>
|
<?php else : ?>
|
||||||
<ul class="us-family-list">
|
<ul class="us-family-list">
|
||||||
<?php foreach ($children as $child) : ?>
|
<?php foreach ($children as $child) : ?>
|
||||||
@@ -74,7 +74,7 @@ if (! defined('ABSPATH')) {
|
|||||||
<?php wp_nonce_field('us_family'); ?>
|
<?php wp_nonce_field('us_family'); ?>
|
||||||
<input type="hidden" name="us_family_action" value="add">
|
<input type="hidden" name="us_family_action" value="add">
|
||||||
|
|
||||||
<h4><?php esc_html_e('Add a child', 'unsupervised-schedular'); ?></h4>
|
<h4><?php esc_html_e('Add a student', 'unsupervised-schedular'); ?></h4>
|
||||||
<p>
|
<p>
|
||||||
<label for="us-child-name"><?php esc_html_e('Name', 'unsupervised-schedular'); ?></label>
|
<label for="us-child-name"><?php esc_html_e('Name', 'unsupervised-schedular'); ?></label>
|
||||||
<input type="text" name="child_name" id="us-child-name" required>
|
<input type="text" name="child_name" id="us-child-name" required>
|
||||||
@@ -90,7 +90,7 @@ if (! defined('ABSPATH')) {
|
|||||||
|
|
||||||
<?php if (! empty($questions)) : ?>
|
<?php if (! empty($questions)) : ?>
|
||||||
<fieldset class="us-reg-questions">
|
<fieldset class="us-reg-questions">
|
||||||
<legend><?php esc_html_e('About this child', 'unsupervised-schedular'); ?></legend>
|
<legend><?php esc_html_e('About this student', 'unsupervised-schedular'); ?></legend>
|
||||||
<?php foreach ($questions as $question) : ?>
|
<?php foreach ($questions as $question) : ?>
|
||||||
<?php
|
<?php
|
||||||
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- QuestionField::render() escapes every interpolated value.
|
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- QuestionField::render() escapes every interpolated value.
|
||||||
@@ -101,7 +101,7 @@ if (! defined('ABSPATH')) {
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<button type="submit"><?php esc_html_e('Add child', 'unsupervised-schedular'); ?></button>
|
<button type="submit"><?php esc_html_e('Add student', 'unsupervised-schedular'); ?></button>
|
||||||
</p>
|
</p>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -75,18 +75,18 @@ if (! defined('ABSPATH')) {
|
|||||||
<p>
|
<p>
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" name="us_is_guardian" id="us-is-guardian" value="1">
|
<input type="checkbox" name="us_is_guardian" id="us-is-guardian" value="1">
|
||||||
<?php esc_html_e("I'm registering as a parent or guardian, for one or more children", 'unsupervised-schedular'); ?>
|
<?php esc_html_e("I'm registering as a parent or guardian, for one or more students", 'unsupervised-schedular'); ?>
|
||||||
</label>
|
</label>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<?php /* Revealed by the checkbox; without JS it is simply always visible. */ ?>
|
<?php /* Revealed by the checkbox; without JS it is simply always visible. */ ?>
|
||||||
<div class="us-children" id="us-children">
|
<div class="us-children" id="us-children">
|
||||||
<p class="us-children-intro"><?php esc_html_e('Add each child you will be booking lessons for. They do not need their own login — you book and pay for them from this account.', 'unsupervised-schedular'); ?></p>
|
<p class="us-children-intro"><?php esc_html_e('Add each student you will be booking lessons for. They do not need their own login — you book and pay for them from this account.', 'unsupervised-schedular'); ?></p>
|
||||||
|
|
||||||
<?php /* The first block is the template the "Add another child" button clones. */ ?>
|
<?php /* The first block is the template the "Add another student" button clones. */ ?>
|
||||||
<div class="us-child" data-child-index="0">
|
<div class="us-child" data-child-index="0">
|
||||||
<p>
|
<p>
|
||||||
<label for="us-child-0-name"><?php esc_html_e("Child's name", 'unsupervised-schedular'); ?></label>
|
<label for="us-child-0-name"><?php esc_html_e("Student's name", 'unsupervised-schedular'); ?></label>
|
||||||
<input type="text" name="children[0][name]" id="us-child-0-name">
|
<input type="text" name="children[0][name]" id="us-child-0-name">
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
@@ -107,7 +107,7 @@ if (! defined('ABSPATH')) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<button type="button" class="us-add-child"><?php esc_html_e('Add another child', 'unsupervised-schedular'); ?></button>
|
<button type="button" class="us-add-child"><?php esc_html_e('Add another student', 'unsupervised-schedular'); ?></button>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|||||||
@@ -667,7 +667,7 @@ class RegistrationPageTest extends TestCase
|
|||||||
|
|
||||||
$result = $this->submit(new Invite(email: '[email protected]', token: 'hash'), false);
|
$result = $this->submit(new Invite(email: '[email protected]', token: 'hash'), false);
|
||||||
|
|
||||||
self::assertStringContainsString('at least one child', $result);
|
self::assertStringContainsString('at least one student', $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -694,7 +694,7 @@ class RegistrationPageTest extends TestCase
|
|||||||
Functions\expect('wp_insert_user')->never();
|
Functions\expect('wp_insert_user')->never();
|
||||||
$this->ctx['guardians']->shouldNotReceive('createChild');
|
$this->ctx['guardians']->shouldNotReceive('createChild');
|
||||||
|
|
||||||
self::assertStringContainsString('for each child', $this->submit(new Invite(email: '[email protected]', token: 'hash'), false));
|
self::assertStringContainsString('for each student', $this->submit(new Invite(email: '[email protected]', token: 'hash'), false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ class FamilyPageTest extends TestCase
|
|||||||
|
|
||||||
$html = $this->page->render([]);
|
$html = $this->page->render([]);
|
||||||
|
|
||||||
self::assertStringContainsString('log in to manage your family', $html);
|
self::assertStringContainsString('log in to manage your profile', $html);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testRenderListsTheGuardiansChildren(): void
|
public function testRenderListsTheGuardiansChildren(): void
|
||||||
@@ -100,7 +100,7 @@ class FamilyPageTest extends TestCase
|
|||||||
|
|
||||||
self::assertStringContainsString('Ada', $html);
|
self::assertStringContainsString('Ada', $html);
|
||||||
self::assertStringContainsString('2015-04-02', $html);
|
self::assertStringContainsString('2015-04-02', $html);
|
||||||
self::assertStringContainsString('Add a child', $html);
|
self::assertStringContainsString('Add a student', $html);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testAddCreatesTheChildRecordsItsAnswersAndRedirects(): void
|
public function testAddCreatesTheChildRecordsItsAnswersAndRedirects(): void
|
||||||
@@ -161,7 +161,7 @@ class FamilyPageTest extends TestCase
|
|||||||
$_POST = ['us_family_action' => 'add', 'child_name' => ''];
|
$_POST = ['us_family_action' => 'add', 'child_name' => ''];
|
||||||
|
|
||||||
$this->questions->shouldReceive('findByScope')->once()->andReturn([]);
|
$this->questions->shouldReceive('findByScope')->once()->andReturn([]);
|
||||||
$this->guardians->shouldReceive('createChild')->once()->andReturn(new \WP_Error('missing_name', 'Please give each child a name.'));
|
$this->guardians->shouldReceive('createChild')->once()->andReturn(new \WP_Error('missing_name', 'Please give each student a name.'));
|
||||||
$this->answers->shouldNotReceive('insert');
|
$this->answers->shouldNotReceive('insert');
|
||||||
|
|
||||||
$captured = null;
|
$captured = null;
|
||||||
@@ -207,7 +207,7 @@ class FamilyPageTest extends TestCase
|
|||||||
$_POST = ['us_family_action' => 'remove', 'child_id' => '42'];
|
$_POST = ['us_family_action' => 'remove', 'child_id' => '42'];
|
||||||
|
|
||||||
$this->guardians->shouldReceive('removeChild')->once()->andReturn(
|
$this->guardians->shouldReceive('removeChild')->once()->andReturn(
|
||||||
new \WP_Error('has_history', 'This child has lessons or enrolments on record.')
|
new \WP_Error('has_history', 'This student has lessons or enrolments on record.')
|
||||||
);
|
);
|
||||||
|
|
||||||
$captured = null;
|
$captured = null;
|
||||||
@@ -271,6 +271,6 @@ class FamilyPageTest extends TestCase
|
|||||||
$this->guardians->shouldReceive('children')->andReturn([]);
|
$this->guardians->shouldReceive('children')->andReturn([]);
|
||||||
$this->questions->shouldReceive('findByScope')->andReturn([]);
|
$this->questions->shouldReceive('findByScope')->andReturn([]);
|
||||||
|
|
||||||
self::assertStringContainsString('Child added.', $this->page->render([]));
|
self::assertStringContainsString('Student added.', $this->page->render([]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user