feat: add alot

This commit is contained in:
2026-10-08 04:12:36 +02:00
parent ccf5165417
commit fc607cb7bd
99 changed files with 4981 additions and 3655 deletions
+48 -26
View File
@@ -1,10 +1,9 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
import '../l10n/app_localizations.dart';
import '../viewmodels/registration_view_model.dart';
import '../viewmodels/remote_sync_view_model.dart';
import '../l10n/app_localizations.dart';
class RegistrationView extends StatefulWidget {
const RegistrationView({super.key});
@@ -115,8 +114,10 @@ class _RegistrationViewState extends State<RegistrationView> {
vm.errorMessage ?? 'Unknown error',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.6),
),
color: Theme.of(
context,
).colorScheme.onSurface.withValues(alpha: 0.6),
),
),
const SizedBox(height: 24),
FilledButton.icon(
@@ -150,21 +151,27 @@ class _RegistrationViewState extends State<RegistrationView> {
'Select your venue to link this device',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.6),
),
color: Theme.of(
context,
).colorScheme.onSurface.withValues(alpha: 0.6),
),
),
const SizedBox(height: 32),
Text(
'Select venue',
style: Theme.of(context).textTheme.labelLarge?.copyWith(
color: Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.7),
),
color: Theme.of(
context,
).colorScheme.onSurface.withValues(alpha: 0.7),
),
),
const SizedBox(height: 8),
Container(
decoration: BoxDecoration(
border: Border.all(
color: Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.15),
color: Theme.of(
context,
).colorScheme.onSurface.withValues(alpha: 0.15),
),
borderRadius: BorderRadius.circular(12),
),
@@ -176,7 +183,10 @@ class _RegistrationViewState extends State<RegistrationView> {
child: InkWell(
onTap: () => vm.selectVenue(venue),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 14,
),
child: Row(
children: [
Icon(
@@ -192,7 +202,9 @@ class _RegistrationViewState extends State<RegistrationView> {
),
Icon(
Icons.chevron_right_rounded,
color: Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.3),
color: Theme.of(
context,
).colorScheme.onSurface.withValues(alpha: 0.3),
),
],
),
@@ -235,8 +247,10 @@ class _RegistrationViewState extends State<RegistrationView> {
'Enter device details to complete pairing',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.6),
),
color: Theme.of(
context,
).colorScheme.onSurface.withValues(alpha: 0.6),
),
),
const SizedBox(height: 32),
TextFormField(
@@ -246,7 +260,9 @@ class _RegistrationViewState extends State<RegistrationView> {
hintText: 'e.g. Bar terminal 1',
border: OutlineInputBorder(),
),
validator: (v) => v == null || v.trim().isEmpty ? 'Device name is required' : null,
validator: (v) => v == null || v.trim().isEmpty
? 'Device name is required'
: null,
),
const SizedBox(height: 16),
TextFormField(
@@ -259,7 +275,9 @@ class _RegistrationViewState extends State<RegistrationView> {
),
maxLength: 6,
textCapitalization: TextCapitalization.characters,
validator: (v) => v == null || v.trim().length < 6 ? 'Enter the 6-character code' : null,
validator: (v) => v == null || v.trim().length < 6
? 'Enter the 6-character code'
: null,
),
const SizedBox(height: 8),
if (vm.errorMessage != null)
@@ -289,7 +307,9 @@ class _RegistrationViewState extends State<RegistrationView> {
if (!_formKey.currentState!.validate()) return;
await vm.registerDevice(
deviceName: _deviceNameController.text.trim(),
registrationCode: _regCodeController.text.trim().toUpperCase(),
registrationCode: _regCodeController.text
.trim()
.toUpperCase(),
);
},
child: const Text('Register'),
@@ -338,27 +358,29 @@ class _RegistrationViewState extends State<RegistrationView> {
'${vm.selectedVenue?.name ?? "Venue"} is now linked.',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.6),
),
color: Theme.of(
context,
).colorScheme.onSurface.withValues(alpha: 0.6),
),
),
const SizedBox(height: 8),
Text(
'Open tabs will sync to the dashboard.',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.5),
),
color: Theme.of(
context,
).colorScheme.onSurface.withValues(alpha: 0.5),
),
),
const SizedBox(height: 32),
FilledButton.icon(
onPressed: () {
context.read<RemoteSyncViewModel>().startSync();
context.go('/bar');
},
// Once configured, the router redirects to /bar by itself.
onPressed: () => context.read<RemoteSyncViewModel>().activate(),
icon: const Icon(Icons.arrow_forward),
label: const Text('Start using KoolTab'),
label: const Text('Start using KoolTap'),
),
],
);
}
}
}