// AUTO-GENERATED widget — matches web .data-card import 'package:flutter/material.dart'; import 'package:inou_app/design/inou_theme.dart'; import 'package:inou_app/design/inou_text.dart'; import 'package:inou_app/design/widgets/inou_badge.dart'; import 'package:inou_app/design/widgets/inou_button.dart'; /// Data card with colored indicator bar class InouCard extends StatelessWidget { final String? title; final String? subtitle; final Color indicatorColor; final Widget? trailing; final Widget? child; final VoidCallback? onTap; const InouCard({ super.key, this.title, this.subtitle, this.indicatorColor = InouTheme.accent, this.trailing, this.child, this.onTap, }); @override Widget build(BuildContext context) { return Container( margin: const EdgeInsets.only(bottom: InouTheme.spaceLg), decoration: BoxDecoration( color: InouTheme.bgCard, borderRadius: InouTheme.borderRadiusLg, border: Border.all(color: InouTheme.border), ), clipBehavior: Clip.antiAlias, child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ if (title != null) _Header( title: title!, subtitle: subtitle, indicatorColor: indicatorColor, trailing: trailing, ), if (child != null) child!, ], ), ); } } class _Header extends StatelessWidget { final String title; final String? subtitle; final Color indicatorColor; final Widget? trailing; const _Header({ required this.title, this.subtitle, required this.indicatorColor, this.trailing, }); @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.all(InouTheme.spaceLg), decoration: const BoxDecoration( border: Border( bottom: BorderSide(color: InouTheme.border), ), ), child: Row( children: [ Container( width: 4, height: 32, decoration: BoxDecoration( color: indicatorColor, borderRadius: BorderRadius.circular(2), ), ), const SizedBox(width: InouTheme.spaceMd), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title.toUpperCase(), style: InouText.labelCaps, ), if (subtitle != null) Text( subtitle!, style: InouText.bodySmall.copyWith( color: InouTheme.textMuted, ), ), ], ), ), if (trailing != null) trailing!, ], ), ); } } /// Simple card without indicator class InouSimpleCard extends StatelessWidget { final Widget child; final EdgeInsets? padding; final VoidCallback? onTap; const InouSimpleCard({ super.key, required this.child, this.padding, this.onTap, }); @override Widget build(BuildContext context) { final card = Container( padding: padding ?? const EdgeInsets.all(InouTheme.spaceLg), decoration: BoxDecoration( color: InouTheme.bgCard, borderRadius: InouTheme.borderRadiusLg, border: Border.all(color: InouTheme.border), ), child: child, ); if (onTap != null) { return InkWell( onTap: onTap, borderRadius: InouTheme.borderRadiusLg, child: card, ); } return card; } } /// Profile card for dashboard class InouProfileCard extends StatelessWidget { final String name; final String? role; final String? dob; final String? sex; final List stats; final bool isCare; final VoidCallback? onTap; final VoidCallback? onEdit; const InouProfileCard({ super.key, required this.name, this.role, this.dob, this.sex, this.stats = const [], this.isCare = false, this.onTap, this.onEdit, }); @override Widget build(BuildContext context) { return InkWell( onTap: onTap, borderRadius: InouTheme.borderRadiusLg, child: Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: InouTheme.bgCard, borderRadius: InouTheme.borderRadiusLg, border: Border.all(color: InouTheme.border), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( child: Text(name, style: InouText.h3), ), if (onEdit != null) GestureDetector( onTap: onEdit, child: Text('✎', style: TextStyle(color: InouTheme.textMuted)), ), ], ), const SizedBox(height: 4), Row( children: [ Text( role ?? 'you', style: InouText.bodySmall.copyWith(color: InouTheme.textSubtle), ), if (isCare) ...[ const SizedBox(width: 8), const InouBadge(text: 'care', variant: BadgeVariant.care), ], ], ), if (dob != null) ...[ const SizedBox(height: 8), Text( 'Born: $dob${sex != null ? ' · $sex' : ''}', style: InouText.bodySmall.copyWith(color: InouTheme.textMuted), ), ], if (stats.isNotEmpty) ...[ const SizedBox(height: 12), Wrap( spacing: 16, runSpacing: 8, children: stats.map((s) => _StatChip(stat: s)).toList(), ), ], const Spacer(), InouButton( text: 'View', size: ButtonSize.small, onPressed: onTap, ), ], ), ), ); } } class ProfileStat { final String emoji; final String label; const ProfileStat(this.emoji, this.label); } class _StatChip extends StatelessWidget { final ProfileStat stat; const _StatChip({required this.stat}); @override Widget build(BuildContext context) { return Text( '${stat.emoji} ${stat.label}', style: InouText.bodySmall.copyWith( color: InouTheme.textMuted, fontSize: 12, ), ); } } /// Add card (dashed border) class InouAddCard extends StatelessWidget { final String label; final VoidCallback? onTap; const InouAddCard({ super.key, required this.label, this.onTap, }); @override Widget build(BuildContext context) { return InkWell( onTap: onTap, borderRadius: InouTheme.borderRadiusLg, child: Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( borderRadius: InouTheme.borderRadiusLg, border: Border.all( color: InouTheme.border, width: 2, style: BorderStyle.solid, // Note: Flutter doesn't support dashed directly ), ), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( '+', style: TextStyle( fontSize: 28, color: InouTheme.accent, fontWeight: FontWeight.w300, ), ), const SizedBox(height: 6), Text( label, style: InouText.body.copyWith(color: InouTheme.textMuted), ), ], ), ), ); } }