Prepare product layout and reusable Flutter theme

Relocate the existing Astro website and preserve its assets and hosting configuration. Add the consumer/backend scaffold and themed Flutter package with consumer tests. Related to #1.
This commit is contained in:
Stephan D committed 2026-09-11 15:36:58 +02:00
1 parent ef65a40213
commit d9318053e8
46 files changed
+703 -1

No files matched your search

@@ -0,0 +1,77 @@
import 'package:flutter/material.dart';
import 'package:sxchnge_theme/sxchnge_theme.dart';
void main() => runApp(const ThemeExample());
class ThemeExample extends StatelessWidget {
const ThemeExample({super.key, this.mode = ThemeMode.system});
final ThemeMode mode;
@override
Widget build(BuildContext context) => MaterialApp(
debugShowCheckedModeBanner: false,
theme: SxchngeTheme.light(),
darkTheme: SxchngeTheme.dark(),
themeMode: mode,
home: const _Gallery(),
);
}
class _Gallery extends StatelessWidget {
const _Gallery();
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(title: const Text('sxchnge')),
body: SingleChildScrollView(
padding: const EdgeInsets.all(24),
child: Center(
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 560),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
'Your next exchange',
style: Theme.of(context).textTheme.headlineLarge,
),
const SizedBox(height: 16),
const Text(
'Обмен без лишних шагов.\nA preview of the SXCHNGE theme.',
),
const SizedBox(height: 24),
const Card(
child: Padding(
padding: EdgeInsets.all(24),
child: Text('Clear amounts. Clear choices.'),
),
),
const SizedBox(height: 24),
const TextField(
decoration: InputDecoration(
labelText: 'Amount',
hintText: '0.00',
),
),
const SizedBox(height: 16),
const TextField(
decoration: InputDecoration(
labelText: 'Email',
errorText: 'Enter a valid email address',
),
),
const SizedBox(height: 24),
FilledButton(onPressed: () {}, child: const Text('Continue')),
const SizedBox(height: 12),
OutlinedButton(onPressed: () {}, child: const Text('Back')),
const SizedBox(height: 12),
const FilledButton(onPressed: null, child: Text('Unavailable')),
],
),
),
),
),
);
}