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>
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
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,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user