Aksel Joonas Reedi commited on
Commit
c4ac4e6
·
unverified ·
1 Parent(s): 2715896

Replace orange JobsUpgradeDialog with sleek full-pane billing screen (#175)

Browse files

- Drop the HF-orange gradient bar, orange icon chip, and orange button.
Card now uses --panel/--border with a single high-contrast --text/--bg
primary button and a ghost secondary, matching the rest of the UI.
- Render as a full-pane fixed overlay rather than a small Dialog so the
chat is genuinely blocked while billing is required — the agent's
previous turn already ended on `tool_state_change(billing_required)`,
so the screen acts as the explicit "paused, waiting on you" state.
- Always show both actions side-by-side: "Add credits" (opens the HF
billing tab + arms the visibility-change auto-retry in ChatInput) and
"I've added credits" (calls the existing onRetry → resume message).
Removes the Topped-up? mode-flip; the visibility-change handler in
ChatInput continues to fire on tab refocus, unchanged.
- Keep the component name and props so ChatInput needs no changes.

frontend/src/components/JobsUpgradeDialog.tsx CHANGED
@@ -1,23 +1,17 @@
1
- import {
2
- Box,
3
- Button,
4
- Dialog,
5
- DialogActions,
6
- DialogContent,
7
- DialogTitle,
8
- Typography,
9
- } from '@mui/material';
10
  import OpenInNewIcon from '@mui/icons-material/OpenInNew';
11
  import CreditCardIcon from '@mui/icons-material/CreditCard';
12
  import ReplayIcon from '@mui/icons-material/Replay';
 
13
 
14
  const HF_BILLING_URL = 'https://huggingface.co/settings/billing';
15
- const HF_ORANGE = '#FF9D00';
16
 
17
  interface JobsUpgradeDialogProps {
18
  open: boolean;
19
  message: string;
20
- /** True after the user clicked "Add credits" — switches the dialog into retry mode. */
 
 
21
  awaitingTopUp: boolean;
22
  onUpgrade: () => void;
23
  onRetry: () => void;
@@ -32,101 +26,140 @@ export default function JobsUpgradeDialog({
32
  onRetry,
33
  onClose,
34
  }: JobsUpgradeDialogProps) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  return (
36
- <Dialog
37
- open={open}
38
- onClose={onClose}
39
- slotProps={{
40
- backdrop: {
41
- sx: { backgroundColor: 'rgba(0,0,0,0.55)', backdropFilter: 'blur(6px)' },
42
- },
43
- }}
44
- PaperProps={{
45
- sx: {
46
- bgcolor: 'var(--panel)',
47
- border: '1px solid var(--border)',
48
- borderRadius: 'var(--radius-md)',
49
- boxShadow: '0 30px 80px rgba(0,0,0,0.45), var(--shadow-1)',
50
- maxWidth: 460,
51
- width: '100%',
52
- mx: 2,
53
- overflow: 'hidden',
54
- },
55
  }}
 
 
 
56
  >
57
  <Box
58
  sx={{
59
- height: 4,
60
- background: `linear-gradient(90deg, ${HF_ORANGE} 0%, #FFC560 50%, ${HF_ORANGE} 100%)`,
61
- }}
62
- />
63
-
64
- <DialogTitle
65
- sx={{
 
 
66
  display: 'flex',
 
67
  alignItems: 'center',
68
- gap: 1.25,
69
- color: 'var(--text)',
70
- fontWeight: 800,
71
- fontSize: '1.05rem',
72
- pt: 2.5,
73
- pb: 0.5,
74
- px: 3,
75
- letterSpacing: '-0.01em',
76
  }}
77
  >
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  <Box
79
  sx={{
80
- width: 32,
81
- height: 32,
82
- borderRadius: '10px',
83
- bgcolor: 'rgba(255, 157, 0, 0.15)',
84
- color: HF_ORANGE,
 
85
  display: 'flex',
86
  alignItems: 'center',
87
  justifyContent: 'center',
 
88
  }}
89
  >
90
- <CreditCardIcon sx={{ fontSize: 18 }} />
91
  </Box>
92
- {awaitingTopUp ? 'Topped up?' : 'Top up to launch'}
93
- </DialogTitle>
94
- <DialogContent sx={{ px: 3, pt: 1.25, pb: 0 }}>
 
 
 
 
 
 
 
 
 
 
 
95
  <Typography
96
  sx={{
97
  color: 'var(--muted-text)',
98
  fontSize: '0.85rem',
99
  lineHeight: 1.6,
100
- mb: 1.5,
 
101
  }}
102
  >
103
  {awaitingTopUp
104
- ? "We'll auto-retry the job as soon as you switch back from the billing tab. Or hit the button below now."
105
  : message ||
106
- 'Hugging Face Jobs need credits on the namespace running them. Add some, then re-run the same job — the agent will pick it back up.'}
107
  </Typography>
108
- </DialogContent>
109
- <DialogActions sx={{ px: 3, pb: 2.5, pt: 2.5, gap: 1 }}>
110
- {awaitingTopUp ? (
111
- <Button
112
- onClick={onRetry}
113
- startIcon={<ReplayIcon sx={{ fontSize: 16 }} />}
114
- variant="contained"
115
- size="small"
116
- sx={{
117
- fontSize: '0.82rem',
118
- px: 2.5,
119
- bgcolor: HF_ORANGE,
120
- color: '#000',
121
- textTransform: 'none',
122
- fontWeight: 700,
123
- boxShadow: '0 6px 18px rgba(255, 157, 0, 0.35)',
124
- '&:hover': { bgcolor: '#FFB340', boxShadow: '0 8px 22px rgba(255, 157, 0, 0.45)' },
125
- }}
126
- >
127
- Retry now
128
- </Button>
129
- ) : (
130
  <Button
131
  component="a"
132
  href={HF_BILLING_URL}
@@ -135,35 +168,20 @@ export default function JobsUpgradeDialog({
135
  onClick={onUpgrade}
136
  startIcon={<OpenInNewIcon sx={{ fontSize: 16 }} />}
137
  variant="contained"
138
- size="small"
139
- sx={{
140
- fontSize: '0.82rem',
141
- px: 2.5,
142
- bgcolor: HF_ORANGE,
143
- color: '#000',
144
- textTransform: 'none',
145
- fontWeight: 700,
146
- boxShadow: '0 6px 18px rgba(255, 157, 0, 0.35)',
147
- '&:hover': { bgcolor: '#FFB340', boxShadow: '0 8px 22px rgba(255, 157, 0, 0.45)' },
148
- }}
149
  >
150
  Add credits
151
  </Button>
152
- )}
153
- <Button
154
- onClick={onClose}
155
- size="small"
156
- sx={{
157
- color: 'var(--muted-text)',
158
- fontSize: '0.82rem',
159
- px: 2,
160
- textTransform: 'none',
161
- '&:hover': { bgcolor: 'var(--hover-bg)' },
162
- }}
163
- >
164
- Close
165
- </Button>
166
- </DialogActions>
167
- </Dialog>
168
  );
169
  }
 
1
+ import { Box, Button, Typography } from '@mui/material';
 
 
 
 
 
 
 
 
2
  import OpenInNewIcon from '@mui/icons-material/OpenInNew';
3
  import CreditCardIcon from '@mui/icons-material/CreditCard';
4
  import ReplayIcon from '@mui/icons-material/Replay';
5
+ import CloseIcon from '@mui/icons-material/Close';
6
 
7
  const HF_BILLING_URL = 'https://huggingface.co/settings/billing';
 
8
 
9
  interface JobsUpgradeDialogProps {
10
  open: boolean;
11
  message: string;
12
+ /** True after the user clicked "Add credits" — the visibility-change auto-retry
13
+ * in the parent uses this; it is unused inside the screen itself, which always
14
+ * shows both actions ("Add credits" and "I've added credits"). */
15
  awaitingTopUp: boolean;
16
  onUpgrade: () => void;
17
  onRetry: () => void;
 
26
  onRetry,
27
  onClose,
28
  }: JobsUpgradeDialogProps) {
29
+ if (!open) return null;
30
+
31
+ const primarySx = {
32
+ bgcolor: 'var(--text)',
33
+ color: 'var(--bg)',
34
+ fontWeight: 700,
35
+ fontSize: '0.85rem',
36
+ textTransform: 'none' as const,
37
+ px: 2.5,
38
+ py: 1,
39
+ borderRadius: '10px',
40
+ boxShadow: 'none',
41
+ '&:hover': { bgcolor: 'var(--text)', opacity: 0.9, boxShadow: 'none' },
42
+ };
43
+
44
+ const secondarySx = {
45
+ bgcolor: 'transparent',
46
+ color: 'var(--text)',
47
+ fontWeight: 600,
48
+ fontSize: '0.85rem',
49
+ textTransform: 'none' as const,
50
+ px: 2.5,
51
+ py: 1,
52
+ borderRadius: '10px',
53
+ border: '1px solid var(--border-hover)',
54
+ '&:hover': { bgcolor: 'var(--hover-bg)', borderColor: 'var(--border-hover)' },
55
+ };
56
+
57
  return (
58
+ <Box
59
+ sx={{
60
+ position: 'fixed',
61
+ inset: 0,
62
+ zIndex: 1300,
63
+ display: 'flex',
64
+ alignItems: 'center',
65
+ justifyContent: 'center',
66
+ backgroundColor: 'rgba(0,0,0,0.55)',
67
+ backdropFilter: 'blur(8px)',
68
+ px: 2,
 
 
 
 
 
 
 
 
69
  }}
70
+ role="dialog"
71
+ aria-modal="true"
72
+ aria-labelledby="jobs-billing-title"
73
  >
74
  <Box
75
  sx={{
76
+ position: 'relative',
77
+ width: '100%',
78
+ maxWidth: 480,
79
+ bgcolor: 'var(--panel)',
80
+ border: '1px solid var(--border)',
81
+ borderRadius: 'var(--radius-md)',
82
+ boxShadow: 'var(--shadow-1)',
83
+ px: 4,
84
+ py: 4,
85
  display: 'flex',
86
+ flexDirection: 'column',
87
  alignItems: 'center',
88
+ textAlign: 'center',
 
 
 
 
 
 
 
89
  }}
90
  >
91
+ <Button
92
+ onClick={onClose}
93
+ aria-label="Close"
94
+ sx={{
95
+ position: 'absolute',
96
+ top: 10,
97
+ right: 10,
98
+ minWidth: 0,
99
+ width: 28,
100
+ height: 28,
101
+ borderRadius: '8px',
102
+ color: 'var(--muted-text)',
103
+ '&:hover': { bgcolor: 'var(--hover-bg)', color: 'var(--text)' },
104
+ }}
105
+ >
106
+ <CloseIcon sx={{ fontSize: 16 }} />
107
+ </Button>
108
+
109
  <Box
110
  sx={{
111
+ width: 44,
112
+ height: 44,
113
+ borderRadius: '12px',
114
+ bgcolor: 'var(--surface)',
115
+ border: '1px solid var(--border)',
116
+ color: 'var(--muted-text)',
117
  display: 'flex',
118
  alignItems: 'center',
119
  justifyContent: 'center',
120
+ mb: 2,
121
  }}
122
  >
123
+ <CreditCardIcon sx={{ fontSize: 22 }} />
124
  </Box>
125
+
126
+ <Typography
127
+ id="jobs-billing-title"
128
+ sx={{
129
+ color: 'var(--text)',
130
+ fontWeight: 700,
131
+ fontSize: '1.05rem',
132
+ letterSpacing: '-0.01em',
133
+ mb: 1,
134
+ }}
135
+ >
136
+ {awaitingTopUp ? 'Resume when you’re ready' : 'Add credits to launch this job'}
137
+ </Typography>
138
+
139
  <Typography
140
  sx={{
141
  color: 'var(--muted-text)',
142
  fontSize: '0.85rem',
143
  lineHeight: 1.6,
144
+ mb: 3,
145
+ maxWidth: 380,
146
  }}
147
  >
148
  {awaitingTopUp
149
+ ? 'Once your top-up is through, click below to resume the agent will pick the run back up where it left off.'
150
  : message ||
151
+ 'Hugging Face Jobs need credits on the namespace running them. Add some, then resume — the agent waits here in the meantime.'}
152
  </Typography>
153
+
154
+ <Box
155
+ sx={{
156
+ display: 'flex',
157
+ flexDirection: { xs: 'column', sm: 'row' },
158
+ gap: 1.25,
159
+ width: '100%',
160
+ justifyContent: 'center',
161
+ }}
162
+ >
 
 
 
 
 
 
 
 
 
 
 
 
163
  <Button
164
  component="a"
165
  href={HF_BILLING_URL}
 
168
  onClick={onUpgrade}
169
  startIcon={<OpenInNewIcon sx={{ fontSize: 16 }} />}
170
  variant="contained"
171
+ sx={primarySx}
 
 
 
 
 
 
 
 
 
 
172
  >
173
  Add credits
174
  </Button>
175
+ <Button
176
+ onClick={onRetry}
177
+ startIcon={<ReplayIcon sx={{ fontSize: 16 }} />}
178
+ variant="outlined"
179
+ sx={secondarySx}
180
+ >
181
+ I’ve added credits
182
+ </Button>
183
+ </Box>
184
+ </Box>
185
+ </Box>
 
 
 
 
 
186
  );
187
  }