202 lines
6.5 KiB
Dart
202 lines
6.5 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:sighej/services/session_store.dart';
|
|
|
|
const List<String> kAvailableInterests = [
|
|
'Tech',
|
|
'Musik',
|
|
'Filosofi',
|
|
'Design',
|
|
'DevOps',
|
|
'Bøger',
|
|
'Gaming',
|
|
'Fitness',
|
|
'Kunst',
|
|
'Mad',
|
|
'Rejser',
|
|
'Videnskab',
|
|
'Iværksætteri',
|
|
'Film',
|
|
'Natur',
|
|
'Kodning',
|
|
'Podcast',
|
|
'Arkitektur',
|
|
'Klima',
|
|
'Sport',
|
|
];
|
|
|
|
class ProfileScreen extends StatefulWidget {
|
|
/// If [isSetup] is true, the screen is shown as first-run onboarding.
|
|
/// If false, it's opened from the home screen as "rediger profil".
|
|
final bool isSetup;
|
|
|
|
const ProfileScreen({super.key, this.isSetup = false});
|
|
|
|
@override
|
|
State<ProfileScreen> createState() => _ProfileScreenState();
|
|
}
|
|
|
|
class _ProfileScreenState extends State<ProfileScreen> {
|
|
late final TextEditingController _nameCtrl;
|
|
late final TextEditingController _taglineCtrl;
|
|
late final Set<String> _selected;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
final store = context.read<SessionStore>();
|
|
_nameCtrl = TextEditingController(text: store.name);
|
|
_taglineCtrl = TextEditingController(text: store.tagline);
|
|
_selected = Set<String>.from(store.interests);
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_nameCtrl.dispose();
|
|
_taglineCtrl.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
Future<void> _save() async {
|
|
await context.read<SessionStore>().saveProfile(
|
|
name: _nameCtrl.text.trim(),
|
|
tagline: _taglineCtrl.text.trim(),
|
|
interests: _selected.toList(),
|
|
);
|
|
if (mounted) Navigator.of(context).pop();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final isSetup = widget.isSetup;
|
|
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
title: Text(isSetup ? 'Hvem er du?' : 'Din profil'),
|
|
automaticallyImplyLeading: !isSetup,
|
|
),
|
|
body: SafeArea(
|
|
child: Column(
|
|
children: [
|
|
Expanded(
|
|
child: SingleChildScrollView(
|
|
padding: const EdgeInsets.all(24),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
if (isSetup) ...[
|
|
Text(
|
|
'SigHej sender en diskret notifikation, når nogen i nærheden deler dine interesser. '
|
|
'Ingen profiler at swipe — bare et lille vink om at starte en samtale.',
|
|
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
|
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
|
),
|
|
),
|
|
const SizedBox(height: 28),
|
|
],
|
|
_SectionLabel('Kaldenavn', hint: 'Valgfrit — hvad vil du kaldes?'),
|
|
const SizedBox(height: 8),
|
|
TextField(
|
|
controller: _nameCtrl,
|
|
maxLength: 40,
|
|
textCapitalization: TextCapitalization.sentences,
|
|
decoration: const InputDecoration(
|
|
hintText: 'F.eks. "Henrik" eller "Tech-nerd"',
|
|
border: OutlineInputBorder(),
|
|
counterText: '',
|
|
),
|
|
),
|
|
const SizedBox(height: 24),
|
|
_SectionLabel(
|
|
'Hvad er du op til i dag?',
|
|
hint: 'Valgfrit — sæt tonen',
|
|
),
|
|
const SizedBox(height: 8),
|
|
TextField(
|
|
controller: _taglineCtrl,
|
|
maxLength: 80,
|
|
textCapitalization: TextCapitalization.sentences,
|
|
decoration: const InputDecoration(
|
|
hintText: 'F.eks. "Åben for en kaffesnak" eller "Op til at netværke"',
|
|
border: OutlineInputBorder(),
|
|
counterText: '',
|
|
),
|
|
),
|
|
const SizedBox(height: 24),
|
|
_SectionLabel(
|
|
'Hvad interesserer dig?',
|
|
hint: 'Vi finder folk med fælles interesser i nærheden',
|
|
),
|
|
const SizedBox(height: 12),
|
|
Wrap(
|
|
spacing: 8,
|
|
runSpacing: 8,
|
|
children: kAvailableInterests.map((interest) {
|
|
final selected = _selected.contains(interest);
|
|
return FilterChip(
|
|
label: Text(interest),
|
|
selected: selected,
|
|
onSelected: (val) => setState(
|
|
() => val
|
|
? _selected.add(interest)
|
|
: _selected.remove(interest),
|
|
),
|
|
);
|
|
}).toList(),
|
|
),
|
|
const SizedBox(height: 16),
|
|
if (_selected.isEmpty)
|
|
Text(
|
|
'Vælg mindst ét emne for at bruge SigHej.',
|
|
style: TextStyle(
|
|
color: Theme.of(context).colorScheme.error,
|
|
fontSize: 13,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
Padding(
|
|
padding: const EdgeInsets.fromLTRB(24, 8, 24, 24),
|
|
child: FilledButton(
|
|
onPressed: _selected.isEmpty ? null : _save,
|
|
style: FilledButton.styleFrom(
|
|
minimumSize: const Size.fromHeight(52),
|
|
),
|
|
child: Text(isSetup ? 'Kom i gang' : 'Gem'),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class _SectionLabel extends StatelessWidget {
|
|
final String label;
|
|
final String? hint;
|
|
|
|
const _SectionLabel(this.label, {this.hint});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(label, style: Theme.of(context).textTheme.titleSmall),
|
|
if (hint != null) ...[
|
|
const SizedBox(height: 2),
|
|
Text(
|
|
hint!,
|
|
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
|
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
|
),
|
|
),
|
|
],
|
|
],
|
|
);
|
|
}
|
|
}
|