feat: orientation model, password confirm, frontend build

- Collapse orientation to landscape/portrait (ribbon left = portrait standard)
- Add OrientationPicker component and wire settings sheet in HomeView
- Add password confirmation field to registration form (RepeatedType)
- Build frontend SPA to public/build/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-04 16:59:03 -04:00
parent 6c7c7a1a6f
commit 6c891d6fad
119 changed files with 82314 additions and 75 deletions
+7
View File
@@ -6,6 +6,13 @@ namespace App\Enum;
enum Orientation: string
{
/** Ribbon at bottom; nail/hanging point at top. */
case Landscape = 'landscape';
/** Ribbon on left; nail/hanging point on right. */
case Portrait = 'portrait';
public function isPortrait(): bool
{
return $this === self::Portrait;
}
}
+16 -8
View File
@@ -8,6 +8,7 @@ use App\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\Email;
@@ -26,15 +27,22 @@ class RegistrationFormType extends AbstractType
new Email(message: 'Please enter a valid email address'),
],
])
->add('plainPassword', PasswordType::class, [
'label' => 'Password',
->add('plainPassword', RepeatedType::class, [
'type' => PasswordType::class,
'mapped' => false,
'constraints' => [
new NotBlank(message: 'Please enter a password'),
new Length(
min: 8,
minMessage: 'Your password must be at least {{ limit }} characters',
),
'invalid_message' => 'Passwords do not match.',
'first_options' => [
'label' => 'Password',
'constraints' => [
new NotBlank(message: 'Please enter a password'),
new Length(
min: 8,
minMessage: 'Your password must be at least {{ limit }} characters',
),
],
],
'second_options' => [
'label' => 'Confirm password',
],
]);
}