Files
tasq/lib/widgets/app_section_header.dart
redz1029 9f764150a2 UI Phase 2 (L0): shared layout primitives + chrome standardization
Extract four shared layout widgets from the best existing implementations and
adopt them across list/overview screens, deleting duplicated inline code.
Layout/consistency only — no behavior change.

New primitives (lib/widgets/):
- app_section_header.dart  — AppSectionHeader (azure accent bar + uppercase
  telemetry label; promoted from the dashboard's _sectionTitle).
- app_metric_card.dart     — AppMetricCard (uppercase label + mono value on a
  flat hairline surface; unifies KPI/stat tiles).
- app_status_summary.dart  — AppStatusSummaryRow/Item/Chip (dot + count + label,
  selectable; semantic AppStatusColors).
- app_filter_bar.dart      — AppFilterBar (responsive filter-row chrome).

Adopted / de-duplicated:
- Dashboard: _MetricCard now wraps AppMetricCard; section titles use
  AppSectionHeader (removed local _sectionTitle).
- Tickets / Tasks / ISR: three separate summary-chip implementations
  (_StatusSummaryCard x2, _SummaryChip) collapsed into AppStatusSummaryRow.
- Network Map overview: Sites/Devices tiles -> AppMetricCard (removed local
  _SummaryCard).
- Workforce: "Duty Schedules" header -> AppSectionHeader with trailing chip.

Verified: flutter analyze lib clean; flutter build web green; visual QA (tickets
+ ISR summary chips) in dark.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-09-26 15:42:26 +08:00

59 lines
1.6 KiB
Dart

import 'package:flutter/material.dart';
/// Cyber/IT section header — a short accent bar + an uppercase, letter-spaced
/// "telemetry" label, with optional trailing actions.
///
/// This is the single shared treatment for in-page section titles (promoted
/// from the Dashboard's original `_sectionTitle`). Use it instead of ad-hoc
/// bold `Text` sub-headers so every screen's sections read the same way.
class AppSectionHeader extends StatelessWidget {
const AppSectionHeader(
this.title, {
super.key,
this.trailing,
this.padding = const EdgeInsets.only(bottom: 12),
});
final String title;
/// Optional trailing widget (e.g. a "Show past" button or filter chip),
/// pinned to the end of the header row.
final Widget? trailing;
final EdgeInsetsGeometry padding;
@override
Widget build(BuildContext context) {
final cs = Theme.of(context).colorScheme;
return Padding(
padding: padding,
child: Row(
children: [
Container(
width: 3,
height: 16,
decoration: BoxDecoration(
color: cs.primary,
borderRadius: BorderRadius.circular(2),
),
),
const SizedBox(width: 10),
Expanded(
child: Text(
title.toUpperCase(),
style: Theme.of(context).textTheme.labelLarge?.copyWith(
fontWeight: FontWeight.w700,
letterSpacing: 0.8,
color: cs.onSurface,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
?trailing,
],
),
);
}
}