@@ -16,6 +16,7 @@ import Pagination from "../components/Pagination";
16
16
import Header from "../components/Header" ;
17
17
import { ErrorCodes } from "@gitpod/gitpod-protocol/lib/messaging/error" ;
18
18
import { FeatureFlagContext } from "../contexts/FeatureFlagContext" ;
19
+ import { ReactComponent as CreditsSvg } from "../images/credits.svg" ;
19
20
20
21
function TeamUsage ( ) {
21
22
const { teams } = useContext ( TeamsContext ) ;
@@ -28,8 +29,9 @@ function TeamUsage() {
28
29
const [ errorMessage , setErrorMessage ] = useState ( "" ) ;
29
30
const today = new Date ( ) ;
30
31
const startOfCurrentMonth = new Date ( today . getFullYear ( ) , today . getMonth ( ) , 1 ) ;
31
- const timestampOfStart = startOfCurrentMonth . getTime ( ) ;
32
- const [ startDateOfBillMonth ] = useState ( timestampOfStart ) ;
32
+ const timestampStartOfCurrentMonth = startOfCurrentMonth . getTime ( ) ;
33
+ const [ startDateOfBillMonth , setStartDateOfBillMonth ] = useState ( timestampStartOfCurrentMonth ) ;
34
+ const [ endDateOfBillMonth , setEndDateOfBillMonth ] = useState ( Date . now ( ) ) ;
33
35
34
36
useEffect ( ( ) => {
35
37
if ( ! team ) {
@@ -40,8 +42,8 @@ function TeamUsage() {
40
42
try {
41
43
const billedUsageResult = await getGitpodService ( ) . server . listBilledUsage (
42
44
attributionId ,
43
- startDateOfBillMonth , // TODO: set based on selected month
44
- Date . now ( ) , // TODO: set based on selected month
45
+ startDateOfBillMonth ,
46
+ endDateOfBillMonth ,
45
47
) ;
46
48
setBilledUsage ( billedUsageResult ) ;
47
49
} catch ( error ) {
@@ -50,7 +52,7 @@ function TeamUsage() {
50
52
}
51
53
}
52
54
} ) ( ) ;
53
- } , [ team ] ) ;
55
+ } , [ team , startDateOfBillMonth , endDateOfBillMonth ] ) ;
54
56
55
57
if ( ! showUsageBasedPricingUI ) {
56
58
return < Redirect to = "/" /> ;
@@ -82,6 +84,32 @@ function TeamUsage() {
82
84
return totalCredits ;
83
85
} ;
84
86
87
+ const handleMonthClick = ( start : any , end : any ) => {
88
+ setStartDateOfBillMonth ( start ) ;
89
+ setEndDateOfBillMonth ( end ) ;
90
+ } ;
91
+
92
+ const getBillingHistory = ( ) => {
93
+ let rows = [ ] ;
94
+ for ( let i = 1 ; i < 7 ; i ++ ) {
95
+ const endDateVar = i - 1 ;
96
+ const startDate = new Date ( today . getFullYear ( ) , today . getMonth ( ) - i ) ;
97
+ const endDate = new Date ( today . getFullYear ( ) , today . getMonth ( ) - endDateVar , 0 ) ;
98
+ const timeStampOfStartDate = startDate . getTime ( ) ;
99
+ const timeStampOfEndDate = endDate . getTime ( ) ;
100
+ rows . push (
101
+ < div
102
+ key = { `billing${ i } ` }
103
+ className = "text-sm text-blue-500 hover:text-blue-600 dark:text-blue-400 dark:hover:text-blue-500 truncate cursor-pointer gp-link"
104
+ onClick = { ( ) => handleMonthClick ( timeStampOfStartDate , timeStampOfEndDate ) }
105
+ >
106
+ { startDate . toLocaleString ( "default" , { month : "long" } ) } { startDate . getFullYear ( ) }
107
+ </ div > ,
108
+ ) ;
109
+ }
110
+ return rows ;
111
+ } ;
112
+
85
113
const lastResultOnCurrentPage = currentPage * resultsPerPage ;
86
114
const firstResultOnCurrentPage = lastResultOnCurrentPage - resultsPerPage ;
87
115
const numberOfPages = Math . ceil ( billedUsage . length / resultsPerPage ) ;
@@ -90,50 +118,29 @@ function TeamUsage() {
90
118
return (
91
119
< >
92
120
< Header title = "Usage" subtitle = "Manage team usage." />
93
- < div className = "app-container pt-9 " >
121
+ < div className = "app-container pt-5 " >
94
122
{ errorMessage && < p className = "text-base" > { errorMessage } </ p > }
95
123
{ ! errorMessage && (
96
124
< div className = "flex space-x-16" >
97
125
< div className = "flex" >
98
126
< div className = "space-y-8 mb-6" style = { { width : "max-content" } } >
99
127
< div className = "flex flex-col truncate" >
100
- < div className = "text-base text-gray-500 truncate" > Period</ div >
101
- < div className = "text-lg text-gray-600 font-semibold truncate" >
128
+ < div className = "text-base text-gray-500 truncate" > Current Month</ div >
129
+ < div
130
+ className = "text-sm text-blue-500 hover:text-blue-600 dark:text-blue-400 dark:hover:text-blue-500 truncate cursor-pointer mb-5"
131
+ onClick = { ( ) => handleMonthClick ( timestampStartOfCurrentMonth , Date . now ( ) ) }
132
+ >
102
133
{ startOfCurrentMonth . toLocaleString ( "default" , { month : "long" } ) } { " " }
103
134
{ startOfCurrentMonth . getFullYear ( ) }
104
135
</ div >
136
+ < div className = "text-base text-gray-500 truncate" > Previous Months</ div >
137
+ { getBillingHistory ( ) }
105
138
</ div >
106
139
< div className = "flex flex-col truncate" >
107
140
< div className = "text-base text-gray-500" > Total usage</ div >
108
141
< div className = "flex text-lg text-gray-600 font-semibold" >
109
- < svg
110
- className = "my-auto mr-1"
111
- width = "20"
112
- height = "20"
113
- fill = "none"
114
- xmlns = "http://www.w3.org/2000/svg"
115
- >
116
- < path
117
- fill-rule = "evenodd"
118
- clip-rule = "evenodd"
119
- d = "M5 2a3 3 0 0 0-3 3v10a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V5a3 3 0 0 0-3-3H5Zm5.2 11.4a3.2 3.2 0 1 0 0-6.4 3.2 3.2 0 0 0 0 6.4Z"
120
- fill = "url(#a)"
121
- />
122
- < defs >
123
- < linearGradient
124
- id = "a"
125
- x1 = "4.3"
126
- y1 = "4.3"
127
- x2 = "16.071"
128
- y2 = "17.107"
129
- gradientUnits = "userSpaceOnUse"
130
- >
131
- < stop stop-color = "#FFAD33" />
132
- < stop offset = "1" stop-color = "#FF8A00" />
133
- </ linearGradient >
134
- </ defs >
135
- </ svg >
136
- < span > { calculateTotalUsage ( ) } Total Credits</ span >
142
+ < CreditsSvg className = "my-auto mr-1" />
143
+ < span > { calculateTotalUsage ( ) } Credits</ span >
137
144
</ div >
138
145
</ div >
139
146
</ div >
@@ -153,8 +160,6 @@ function TeamUsage() {
153
160
) }
154
161
{ billedUsage . length > 0 && (
155
162
< div className = "flex flex-col w-full mb-8" >
156
- < h3 > All Usage</ h3 >
157
- < span className = "text-gray-500 mb-5" > View usage details of all team members.</ span >
158
163
< ItemsList className = "mt-2 text-gray-500" >
159
164
< Item header = { false } className = "grid grid-cols-5 bg-gray-100 mb-5" >
160
165
< ItemField className = "my-auto" >
@@ -167,33 +172,7 @@ function TeamUsage() {
167
172
< span > Usage</ span >
168
173
</ ItemField >
169
174
< ItemField className = "flex my-auto" >
170
- < svg
171
- className = "my-auto mr-1"
172
- width = "20"
173
- height = "20"
174
- fill = "none"
175
- xmlns = "http://www.w3.org/2000/svg"
176
- >
177
- < path
178
- fill-rule = "evenodd"
179
- clip-rule = "evenodd"
180
- d = "M5 2a3 3 0 0 0-3 3v10a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V5a3 3 0 0 0-3-3H5Zm5.2 11.4a3.2 3.2 0 1 0 0-6.4 3.2 3.2 0 0 0 0 6.4Z"
181
- fill = "url(#a)"
182
- />
183
- < defs >
184
- < linearGradient
185
- id = "a"
186
- x1 = "4.3"
187
- y1 = "4.3"
188
- x2 = "16.071"
189
- y2 = "17.107"
190
- gradientUnits = "userSpaceOnUse"
191
- >
192
- < stop stop-color = "#FFAD33" />
193
- < stop offset = "1" stop-color = "#FF8A00" />
194
- </ linearGradient >
195
- </ defs >
196
- </ svg >
175
+ < CreditsSvg className = "my-auto mr-1" />
197
176
< span > Credits</ span >
198
177
</ ItemField >
199
178
< ItemField className = "my-auto" />
0 commit comments