Files
tasq/lib/widgets/tech_chip.dart
T
redz1029 57377b1b21 UI: Cyber/IT design overhaul with semantic status tokens (Material 3)
Re-theme TasQ with a refined enterprise "Cyber/IT" identity on Material 3.
Functionality is unchanged — only color/shape tokens and a few state widgets.

Foundation:
- Hand-tuned light + dark ColorSchemes (deep-slate surfaces, azure/teal/violet
  accents), tightened 12-16dp shape language, flat hairline-outlined cards.
- New AppStatusColors theme extension (success/warning/danger/info/neutral,
  per-brightness) replacing scattered raw Colors.green/orange/red/grey so status
  color is consistent and legible in dark mode.
- New TechChip mono primitive; StatusPill.kind; M3Card hairline variants;
  tightened AppSurfaces radii.

Per-screen:
- Tokenized status colors + radii across dashboard, tickets, tasks, IT service
  requests, attendance, whereabouts, network map, reports charts, auth, and
  shared/admin screens. Added _ticketStatusKind/_taskStatusKind/_isrStatusKind
  mappers so status carries meaning consistently.
- Fixed white pie-slice borders for dark mode; dropped ad-hoc dialog radius
  overrides in favor of the theme default. Categorical palettes (leave-type
  icons, team color picker, distribution charts) intentionally preserved.

Verified: flutter analyze lib clean; flutter build web green; visual QA in
light and dark (dashboard, tickets, attendance).

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

93 lines
2.5 KiB
Dart

import 'package:flutter/material.dart';
import '../theme/app_status_colors.dart';
import '../theme/app_surfaces.dart';
import '../theme/app_typography.dart';
/// A compact, monospace "code" chip for technical identifiers — ticket/task
/// numbers, IP/MAC addresses, ports, VLAN ids, device codes, short timestamps.
///
/// Reinforces the Cyber/IT identity by rendering machine data in Roboto Mono on
/// a subtle tonal surface with a hairline outline. Optionally tint it with a
/// semantic [StatusKind] for at-a-glance meaning.
class TechChip extends StatelessWidget {
const TechChip(
this.text, {
super.key,
this.icon,
this.status,
this.onTap,
this.dense = false,
});
final String text;
/// Optional leading glyph (e.g. `Icons.tag`, `Icons.lan_outlined`).
final IconData? icon;
/// When set, tints the chip with the matching [AppStatusColors] swatch.
final StatusKind? status;
final VoidCallback? onTap;
/// Tighter padding + smaller glyph for inline use within dense rows.
final bool dense;
@override
Widget build(BuildContext context) {
final cs = Theme.of(context).colorScheme;
final radius = AppSurfaces.of(context).chipRadius;
final swatch = status == null
? null
: AppStatusColors.of(context).byKind(status!);
final background = swatch?.container ?? cs.surfaceContainerHighest;
final foreground = swatch?.onContainer ?? cs.onSurfaceVariant;
final border = swatch == null ? cs.outlineVariant : Colors.transparent;
final labelStyle = AppMonoText.of(context).label.copyWith(
color: foreground,
fontWeight: FontWeight.w600,
height: 1.0,
);
final content = Row(
mainAxisSize: MainAxisSize.min,
children: [
if (icon != null) ...[
Icon(icon, size: dense ? 12 : 14, color: foreground),
SizedBox(width: dense ? 4 : 6),
],
Flexible(
child: Text(
text,
style: labelStyle,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
],
);
final chip = Container(
padding: EdgeInsets.symmetric(
horizontal: dense ? 6 : 8,
vertical: dense ? 2 : 4,
),
decoration: BoxDecoration(
color: background,
borderRadius: BorderRadius.circular(radius),
border: Border.all(color: border),
),
child: content,
);
if (onTap == null) return chip;
return InkWell(
onTap: onTap,
borderRadius: BorderRadius.circular(radius),
child: chip,
);
}
}