nkbmusic/lib/shared/widgets/section_header.dart
metatroncubeswdev 178d2d00ab Nanga Kathai: Flutter app, self-hosted backend and song tools
- Flutter app (Android/iOS): home, explore, albums, search, player with
  equalizer, mini player, sign up/sign in with email codes, profile,
  encrypted offline downloads, About page
- server/: one-command deploy of self-hosted Supabase behind HestiaCP/nginx
  (or Caddy), migrations, backups, email templates
- supabase/migrations: schema, row-level security, profiles
- tools/: song scanner and importer

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 10:39:26 -04:00

54 lines
1.6 KiB
Dart

import 'package:flutter/material.dart';
import '../../app/theme.dart';
class SectionHeader extends StatelessWidget {
const SectionHeader(this.title, {super.key, this.onSeeAll});
final String title;
final VoidCallback? onSeeAll;
@override
Widget build(BuildContext context) {
return Row(
children: [
Expanded(child: Text(title, style: Theme.of(context).textTheme.titleLarge)),
if (onSeeAll != null)
TextButton(
onPressed: onSeeAll,
style: TextButton.styleFrom(foregroundColor: const Color(0xFFC9D6CE)),
child: const Text('See all', style: TextStyle(fontWeight: FontWeight.w600)),
),
],
);
}
}
/// Centered message for empty lists and load errors.
class EmptyState extends StatelessWidget {
const EmptyState({super.key, required this.icon, required this.title, this.message});
final IconData icon;
final String title;
final String? message;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 48),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(icon, size: 48, color: NkColors.teaLeaf),
const SizedBox(height: 16),
Text(title, textAlign: TextAlign.center, style: Theme.of(context).textTheme.titleLarge),
if (message != null) ...[
const SizedBox(height: 8),
Text(message!, textAlign: TextAlign.center, style: const TextStyle(color: NkColors.muted, height: 1.4)),
],
],
),
);
}
}