Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
CodeIssuesPull RequestsActionsSecurityInsightsSettings
✨ AI
More
Blame · Line-by-line history

GateStatusBadge.tsx

Each line is annotated with the commit that last touched it. Click any SHA to jump to that commit and see the surrounding change.

GateStatusBadge.tsxBlame122 lines · 1 contributor
9989d86Claude1import React from 'react';
2import { StyleSheet, Text, View } from 'react-native';
3import { colors } from '../theme/colors';
4import type { GateRunStatus } from '../api/gates';
5
6interface GateStatusBadgeProps {
7 status: GateRunStatus;
8 aiRepaired?: boolean;
9 size?: 'small' | 'medium';
10}
11
12function statusLabel(status: GateRunStatus): string {
13 switch (status) {
14 case 'passed': return 'Passed';
15 case 'failed': return 'Failed';
16 case 'pending': return 'Pending';
17 case 'running': return 'Running';
18 case 'error': return 'Error';
19 }
20}
21
22function statusColor(status: GateRunStatus): string {
23 switch (status) {
24 case 'passed': return colors.accent;
25 case 'failed': return colors.accentRed;
26 case 'pending': return colors.accentYellow;
27 case 'running': return colors.accentBlue;
28 case 'error': return colors.accentRed;
29 }
30}
31
32function statusIcon(status: GateRunStatus): string {
33 switch (status) {
34 case 'passed': return '✓';
35 case 'failed': return '✗';
36 case 'pending': return '◌';
37 case 'running': return '◌';
38 case 'error': return '!';
39 }
40}
41
42export function GateStatusBadge({
43 status,
44 aiRepaired = false,
45 size = 'medium',
46}: GateStatusBadgeProps): React.ReactElement {
47 const badgeColor = statusColor(status);
48 const isSmall = size === 'small';
49
50 return (
51 <View style={styles.wrapper}>
52 <View
53 style={[
54 styles.badge,
55 isSmall && styles.badgeSmall,
56 { borderColor: badgeColor },
57 ]}
58 >
59 <Text style={[styles.icon, isSmall && styles.iconSmall, { color: badgeColor }]}>
60 {statusIcon(status)}
61 </Text>
62 <Text style={[styles.label, isSmall && styles.labelSmall, { color: badgeColor }]}>
63 {statusLabel(status)}
64 </Text>
65 </View>
66 {aiRepaired && (
67 <View style={styles.aiBadge}>
68 <Text style={styles.aiText}>AI Repaired</Text>
69 </View>
70 )}
71 </View>
72 );
73}
74
75const styles = StyleSheet.create({
76 wrapper: {
77 flexDirection: 'row',
78 alignItems: 'center',
79 gap: 6,
80 },
81 badge: {
82 flexDirection: 'row',
83 alignItems: 'center',
84 paddingHorizontal: 10,
85 paddingVertical: 4,
86 borderRadius: 20,
87 borderWidth: 1,
88 gap: 5,
89 backgroundColor: colors.bgSecondary,
90 },
91 badgeSmall: {
92 paddingHorizontal: 7,
93 paddingVertical: 2,
94 },
95 icon: {
96 fontSize: 13,
97 fontWeight: '700',
98 },
99 iconSmall: {
100 fontSize: 11,
101 },
102 label: {
103 fontSize: 13,
104 fontWeight: '600',
105 },
106 labelSmall: {
107 fontSize: 11,
108 },
109 aiBadge: {
110 paddingHorizontal: 7,
111 paddingVertical: 2,
112 borderRadius: 20,
113 backgroundColor: colors.bgSecondary,
114 borderWidth: 1,
115 borderColor: colors.accentPurple,
116 },
117 aiText: {
118 fontSize: 11,
119 color: colors.accentPurple,
120 fontWeight: '500',
121 },
122});